Linux 入门教程——如何安装软件?

气象家园投稿第五篇:如何安装软件?

上一期曾说过,如果你要在 Linux 下写 Fortran 程序,可能要自行安装 Fortran 编译器;要想读写 nc 文件时,也需要安装 netcdf 库。毫无疑问,新装好的系统当然要根据自己的需求安装一些特定功能的软件啦!不过要在 Linux 下安装软件可不像 Windows 下那样轻松。唔,要是在 Windows 下的话,安装软件只需要“选路径”,“勾选项”和“下一步”就差不多了,图形界面的操作一目了然。可是到了 Linux 下,不光是图形操作变成了字符输入,还得考虑一些环境设置及软件依赖性的问题,确实不太容易啊。哈哈,别急,让我们一起来了解下相关的知识,然后你就会觉得,其实一点也不难嘛!

源码安装

软件的安装方式大概可以分成两种,一种是源码安装,即人家把源代码提供给我们,然后我们在自己机器上编译得到可执行文件;另一种则是软件被预先编译好,我们直接下载可执行文件就能用了。Linux 下的绝大部分软件,都是可以源码安装的,换句话说我们可以获取源代码。许多软件网站上会同时提供两种安装方式,即所谓的 source code 和 binaries。但 Windows 下的软件,开源的软件很少见吧?所以在 Windwos 下安装软件,只是将已编译好的程序复制到你电脑上,再设置设置注册表什么的。
使用 binaries 安装是最为简单的,前面已经说过了,下载下来就能用,你唯一要做的事情就是解压一下。虽然简单,但存在不小的局限性,即 binaries 必须是在特定的系统上才行使用。你去随便找个软件的 binaries,就会看到它让你根据你的系统选择版本,以NCL为例:
pic_1.png
那万一它不提供我这个系统的呢?比如上面也没有 Fedora 的啊!这个时候可以考虑下个 RHEL 的试试,因为 Fedora 和 RHEL 相对比较接近。可要是不行呢?总不能重新换个系统吧。更别说有的软件还不提供 binaries 呢!
没办法,只能源码安装咯。那么上一期所介绍的内容就有些用了,因为采用源码安装软件的方式,实际上就是编译一个程序嘛,只不过比我们自己写的程序大一些而已。这里我想找一个软件来演示下安装过程,最后决定还是以 NCL 为例,但 NCL 的源码安装实在是,太!麻!烦!了!就连官网都这样说:

“We highly recommend that you use a precompiled NCL binary rather than attempting a build from source code. If you tried a precompiled binary and ran into problems, you can post your problem to the ncl-install email list. If you decide to go forth with building from source code, good luck!”

好吧……不过我就是喜欢挑战!咳咳,其实也是觉得大多人都没源码装过 NCL,我来介绍介绍也是不错的吧?
嗯,我说源码安装就是编译程序,那你会想起这样的命令 compiler -o xxx xxx -Ixxx -Lxxx。不过软件源文件较多,所以是用 Makefile 进行编译。那是用什么编译器,以及所需的头文件和库文件是什么呢?我们得根据软件和系统的实际情况来设置。要是我缺少某个库呢?那就得先把那个库装好,即所谓的依赖性问题:安装该软件时需要依赖其它软件。装好以后还得在 .bashrc 文件里面加上软件路径,有时候还有其他的配置,以便使用。总结一下,源码安装的主要步骤即设置编译环境、编译软件、配置软件。不过不同软件有不同之处,具体某个软件的安装步骤详见其官网及 READMEINSTALL 文件。好了,下面我给大家演示下源码安装 NCL(参考官网的介绍)。
第一步得先解决依赖性问题,即安装 NCL 前,需要先安装其他的软件,这里贴一下官网的列表:
pic_2.png
什么?本来我只是要装一个 NCL,现在要装这么多其他的软件?什么什么?怎么我装列表中的某个软件时,它又说我得再装另外几个软件?哦,天哪,到底一共要装多少软件啊!不过要是不需要额外的功能,就能少装些依赖软件,而且可能有些软件已经被安装了。这里只演示下 netcdf 和 hdf5 的安装,其他软件装起来也差不多。当然,假设你和我一样,已经把 netcdf 和 hdf5 的依赖软件装好了。
我们先装 hdf5,下载源码后的操作大致是这样的:

1
2
3
4
5
6
7
[root@Dell Downloads]# tar -xvzf hdf5-1.8.13.tar.gz > /dev/null
[root@Dell Downloads]# cd hdf5-1.8.13/
[root@Dell hdf5-1.8.13]# mkdir -p /opt/hdf5/hdf5-1.8.13
[root@Dell hdf5-1.8.13]# ./configure --prefix=/opt/hdf5/hdf5-1.8.13 > config.output 2>&1
[root@Dell hdf5-1.8.13]# make all install > make.output 2>&1
[root@Dell hdf5-1.8.13]# ls /opt/hdf5/hdf5-1.8.13/
bin include lib share

然后装 netcdf,其过程则是这样的:

1
2
3
4
5
6
7
[root@Dell netcdf]# tar -xvzf netcdf-4.4.0.tar.gz > /dev/null
[root@Dell netcdf]# cd netcdf-4.4.0/
[root@Dell netcdf-4.4.0]# mkdir -p /opt/netcdf/netcdf-4.4.0
[root@Dell netcdf-4.4.0]# CC=gcc FC=gfortran CPPFLAGS=-I/opt/hdf5/hdf5-1.8.13/include LDFLAGS=-L/opt/hdf5/hdf5-1.8.13/lib ./configure --prefix=/opt/netcdf/netcdf-4.4.0 > config.output 2>&1
[root@Dell netcdf-4.4.0]# make all install > make.output 2>&1
[root@Dell netcdf-4.4.0]# ls /opt/netcdf/netcdf-4.4.0/
bin include lib share

楼上是安装 C 库,楼下开始安装 Fortran 库:

1
2
3
4
5
6
7
[root@Dell netcdf]# tar -xvzf netcdf-fortran-4.4.0.tar.gz > /dev/null
[root@Dell netcdf]# cd netcdf-fortran-4.4.0/
[root@Dell netcdf-fortran-4.4.0]# mkdir -p /opt/netcdf/netcdf-fortran-4.4.0
[root@Dell netcdf-fortran-4.4.0]# CC=gcc FC=gfortran CPPFLAGS=-I/opt/netcdf/netcdf-4.4.0/include LDFLAGS=-L/opt/netcdf/netcdf-4.4.0/lib ./configure --prefix=/opt/netcdf/netcdf-fortran-4.4.0 > config.output 2>&1
[root@Dell netcdf-fortran-4.4.0]# make all install > make.output 2>&1
[root@Dell netcdf-fortran-4.4.0]# ls /opt/netcdf/netcdf-fortran-4.4.0/
bin include lib share

安装过程中使用的是 root 权限,因为我要装在 /opt 这个目录下。我这里多次使用了重定向,像 tarconfiguremake 这些命令,都会有大量的屏幕输出,为了显示便捷,我通过重定向把这些屏幕输出“扔掉了”(即 > /dev/null)或者保存成文件了(即 > config.out 2>&1> make.output 2>&1)。另外,netcdf 在某个版本(4.2?)后将 C 库和 Fortran 库分离了,而且得先安装 C 库再安装 Fortran 库,就像我这里演示的一样。
安装 hdf5 和 netcdf 的过程差不多,先解压源码包,创建安装目录,利用 configure 进行配置(设置库的位置、软件安装位置等),利用 make 进行编译,然后就 OK 了。configure 时可以指定编译器,比如我这里指定为 gccgfortran,也可以不指定,那么软件会用默认编译器进行安装。安装软件时需要用到不少的外部库函数,其中大部分存放在 /usr/lib/usr/local/lib(或 /usrlib64/usrlocal/lib64)里面,这些库可以自动被系统识别到。个别的库则需要我们在 configure 时进行设置,比如装 netcdf 的 C 库时加上了 hdf5 的路径,装 netcdf 的 Fortran 库时又加上了刚装的 netcdf 的 C 库,装 hdf5 时则不需要额外的库路径。那 configure 时要加的库到底有哪些呢?不同的软件明显是不同的 ,你可以在软件的 READMEINSTALL 文件里进行查看。要是你懒得看,啥都不加也行啊,如果它报错说缺少库了,根据错误信息就能知道要加哪些库。嗯,也许一开始会让人有混乱感,但多装几个不同的软件以后慢慢就会熟悉的。
好了,等装好几个必要的软件以后,我们开始安装 NCL。首先需要预先测试下你的系统是否可以安装 NCL,并得到适合你机器的环境文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@Dell ncl]# tar -xvzf ncl_ncarg-6.3.0.tar.gz > /dev/null
[root@Dell ncl]# cd ncl_ncarg-6.3.0/
[root@Dell ncl_ncarg-6.3.0]# mkdir -p /opt/ncl/ncl-6.3.0
[root@Dell ncl_ncarg-6.3.0]# cd config/
[root@Dell config]# make -f Makefile.ini
cc -O -c -o ymake-filter.o ymake-filter.c
cc -O -o ymake-filter ymake-filter.o
[root@Dell config]# ./ymake -config `pwd`
[root@Dell config]# grep SYSTEM_INCLUDE Makefile
SYSTEM_INCLUDE = "LINUX"
[root@Dell config]# ls LINUX*
LINUX LINUX.64.INTEL LINUX.GNU LINUX.INTEL LINUX.ppc64.xl
LINUX.32.PGI LINUX.64.PGI LINUX.IA64 LINUX.PGI
LINUX.64.GNU LINUX_alpha LINUX.IA64.INTEL LINUX.ppc32.GNU
[root@Dell config]# vi LINUX.64.GNU
[root@Dell config]# cp LINUX.64.GNU LINUX
cp: overwrite 'LINUX'? y

ymake 用来检测环境,可以看到没有错误提示。grep 的结果则告诉我们,待会 configure 时会用到 LINUX 这个环境文件,我们需要对它进行修改(改一改编译器、编译选项、库路径什么的)。不过这里我们可以用 LINUX.64.GNU 这个 template,用它覆盖掉 LINUX 就行了。当然,使用 LINUX.64.GNU 这个文件说明我所用编译器为 gccgfortran,如果你想用 intel 的编译器 iccifort 来编译,可以考虑使用 LINUX.64.INTEL
好了,接下来就 configure 吧,然后你会发现,NCL 看起来更加友好一些:
pic_3.png
是的,你直接运行 configure,它会交互式地让你输入相关信息,不用像装 netcdf 那样要一次性敲一长串字符,而且看起来更容易理解。当然了,其中有很多选项,而有些选项是需要额外库的,如果你确实需要某些功能,那就得先装好所需的库。嗯,还有就是,别把安装路径和库路径输错了。
安装路径:
pic_4.png
库路径:
pic_5.png
configure 结束以后,make 一下就完事儿啦!

1
[root@Dell ncl_ncarg-6.3.0]# make Everything > make.output 2>&1

噢,当然,别忘记在 .bashrc 里面设置环境变量了!(这里可以看到我给 netcdf 和 hdf5 也进行了设置)
pic_6.png
不知道你看到这感觉怎样?不简单?太容易?我的感觉是:这一段写得我好累啊…

软件包管理器

嗯,感觉源码安装还是太麻烦,可是 binaries 又不能用?不妨这样想想,某个人也在用 Fedora,而且他已经源码装过 NCL 了,那他直接把编译好的拷给我是不是就能用了?咳咳,这个想法是不错,就算官网没有合适的,那找同系统且装过 NCL 的人拷贝呗。不过,是不是我还是得装一下 NCL 的依赖软件?好吧,这其实是一种比较粗略的想法。
好了,正式的来说,我们需要使用软件包管理器。先提一下 Linux 两大主流的软件包管理器,一个是 Fedora、CentOS、Red Hat 等使用的 RPM,另一个是 Debian、Ubuntu 等使用的 DPKG,后面的内容主要谈论 RPM(因为我是 Fedora 系统)。软件包管理器需要解决的即为 binaries 所无法满足的,即不同系统、不同环境的问题。首先,Fedora 和 CentOS 虽然是不同系统,但它们都采用 RPM 的包管理机制,一个 rpm 软件包当然既可以在 Fedora 下也可以在 CentOS 下安装了。其次,环境问题即为是否已经装有依赖软件,而 rpm 包大概相当于 binaries 加上环境检测脚本,它会先自动检测依赖性问题,不满足则不会安装,并且告诉你需要的依赖软件。虽说我们还是得装好几个其他的软件,但依赖软件也通过 RPM 安装不就行了,不用编译源码还是比较省事的。RPM 安装过程非常简单,比如我装一个 Google Chrome:
pic_7.png
使用 rpm 命令就行了,-i 表示安装,-v 表示显示详细信息,-h 表示显示安装进度,-q 则查找是否安装了某个包。从显示的内容可以看出,我已经装过 Chrome 了。这里我就不再为了演示而把我的 Chrome 卸载重装了。
使用 RPM 是不是容易多了?毕竟不用自己编译。但还有更简单的方式,那就是使用 yum 命令。yum 可以自动帮你查找依赖软件然后一并安装。比如我用 yum 安装 NCL:
pic_8.png
pic_9.png
一条命令,它会自行解决依赖问题,确认后就连 NCL 带依赖软件一起装好了……啊呸,你咋不早说啊?前面源码装了这么久的 NCL,还出错好多次,现在告诉我就一条命令?好吧,我承认 yum 很好用,平时软件都是这么装的,也推荐你这样做。不过 rpmyum 也不是万能的,不一定存在你要的软件包,就好比是“你并没有找到那个和你同系统且装了 NCL 的人”。其实我去年尝试用 yum 装 NCL 时就说找不到这样的软件包,所以我第一次装 NCL 就是实实在在的源码安装。还有一个问题就是版本的问题,我用 yum 只能装到6.1.2版的 NCL,而源码安装就能随便选择版本了。
对了,关于 yum 的使用,我也有困惑的地方,那就是软件包的名字。比如 NCL 的包的名字是 ncl,而我之前尝试用 yum 安装过 Google Chrome,我输 yum install chrome 或者 yum install google-chrome,它都说找不到这个软件。Chrome 这么大众的软件,怎么可能没有啊,实际上要这样输才行:yum install google-chrome-stable。嗯,也许猜不到软件包名称的时候应该 Google 一下。还有另一个经验要分享一下,如果你要用 yum,记得有个叫 -devel 的后缀,很多情况下有这个后缀的包才有头文件。比如 yum install netcdf 得到的只有库文件,你得再 yum install netcdf-devel 才能把头文件也装上。

结语

Linux 软件千千万,安装方式两三种。对于你,也许是用的 Ubuntu 的 apt-get,也许更喜欢源码?!看你心情咯~最后预告一下,下一期要开始调模式了。很显然,这个只能是源码安装!