前言
以源码方式安装软件,需要对源码进行编译,因此要求当前系统中存在一个可用的编译器。Linux发行版一般都安装了GCC编译器,但版本一般较低。因此博文将以安装指定版本GCC编译器为例,说明使用源码安装软件的方法,其他软件源码包安装方法大同小异。
使用源码安装软件的三个步骤:配置(configure)、编译(make)与安装(make install),如下图所示。(其中configure、Makefile.in一般由项目管理器自动生成的,GCC编译器需要安装。)
1、获取与解压源码安装包
当前GCC版本信息可以通过gcc --version获知,从中看出这是gcc 4.8.4版本。
xjh@ubuntu:~/Downloads$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4
####省略部分输出
xjh@ubuntu:~/Downloads$
可以前往GCC官网下载指定版本的GCC源码安装包,这里下载gcc-10.1.0.tar.gz。
用firefox浏览器下载文件,默认保存到“/home/普通用户名/Downloads”目录中,或者root用户的“/root/Downloads”目录。
可以使用md5sum校验工具,进行源码包的完整性校验,防止源码包被别人串改。校验方法:计算MD5校验和,并与官方提供的值相比较,如果一致则表明没有篡改,如果不一致则表明被篡改了。
xjh@ubuntu:~/Downloads$ pwd
/home/xjh/Downloads
xjh@ubuntu:~/Downloads$ ls
gcc-10.1.0.tar.gz sublime_text_3_build_3211_x32.tar.bz2
xjh@ubuntu:~/Downloads$ md5sum gcc-10.1.0.tar.gz
8a9fbd7e24d04c5d36e96bc894d3cd6b gcc-10.1.0.tar.gz
xjh@ubuntu:~/Downloads$
我们将gcc-10.1.0.tar.gz解压至 /usr/local/src目录,得到文件夹gcc-10.1.0。
xjh@ubuntu:~/Downloads$ sudo tar -zxvf gcc-10.1.0.tar.gz -C /usr/local/src
##忽略解压输出
xjh@ubuntu:~/Downloads$ cd /usr/local/src/
xjh@ubuntu:/usr/local/src$ ls
gcc-10.1.0
xjh@ubuntu:/usr/local/src$ cd gcc-10.1.0/
xjh@ubuntu:/usr/local/src/gcc-10.1.0$ ls
ABOUT-NLS contrib install-sh libgomp libvtv MD5SUMS
ar-lib COPYING intl libhsail-rt ltgcc.m4 missing
ChangeLog COPYING3 LAST_UPDATED libiberty ltmain.sh mkdep
ChangeLog.jit COPYING3.LIB libada libitm lt~obsolete.m4 mkinstalldirs
ChangeLog.tree-ssa COPYING.LIB libatomic libobjc lto-plugin move-if-change
compile COPYING.RUNTIME libbacktrace liboffloadmic ltoptions.m4 multilib.am
config depcomp libcc1 libphobos ltsugar.m4 NEWS
config.guess fixincludes libcpp libquadmath ltversion.m4 README
config-ml.in gcc libdecnumber libsanitizer MAINTAINERS symlink-tree
config.rpath gnattools libffi libssp maintainer-scripts test-driver
config.sub gotools libgcc libstdc++-v3 Makefile.def ylwrap
configure include libgfortran libtool-ldflags Makefile.in zlib
configure.ac INSTALL libgo libtool.m4 Makefile.tpl
xjh@ubuntu:/usr/local/src/gcc-10.1.0$
2、配置
软件包中一般会有安装教程,比如README文档。进入INSTALL目录下,发现有一个README文档,它提示我们可以打开当前目录下的index.html来查看安装教程。
在终端通过命令打开html文件的方法为“firefox xxx.html &”,此时会弹出安装教程的网页。
xjh@ubuntu:/usr/local/src/gcc-10.1.0/INSTALL$ firefox configure.html &
(1)安装路径的配置
通过执行"./configure -h"可以查看帮助。
由下图可知,--prefix选项用来配置安装的路径。如果没有通过该选项指定安装路径,则默认将可执行文件安装到/usr/local/bin,将库文件放到/usr/local/lib中。
建议使用--prefix选项,把文件安装到指定目录中,这样有利于查找、卸载软件或移植软件。当不再需要某个软件时,删除该安装目录就可以把软件卸载得干干净净,移植软件时只需要拷贝整个目录到另外一个机器即可。
这里设置安装路径为/usr/local/src/gcc-build-10.1.0。首先在/usr/local/src目录下创建gcc-build-10.1.0文件夹,接着通过./configure命令来设置软件的安装路径,如下所示:
xjh@ubuntu:/usr/local/src$ ls
gcc-10.1.0 gcc-build-10.1.0
xjh@ubuntu:/usr/local/src$ cd gcc-10.1.0
xjh@ubuntu:/usr/local/src/gcc-10.1.0$ ./configure --prefix=/usr/local/src/gcc-build-10.1.0/
##省略输出内容
xjh@ubuntu:/usr/local/src/gcc-10.1.0$
(2)依赖包的配置
执行上述命令时,错误提示还没有安装GCC所需要的依赖包(如 gmp、mpfr、mpc 等)。
checking for the correct version of gmp.h... no
configure: error: Building GCC requires GMP 4.2+, MPFR 3.1.0+ and MPC 0.8.0+.
Try the --with-gmp, --with-mpfr and/or --with-mpc options to specify
their locations. Source code for these libraries can be found at
their respective hosting sites as well as at
https://gcc.gnu.org/pub/gcc/infrastructure/. See also
http://gcc.gnu.org/install/prerequisites.html for additional info. If
you obtained GMP, MPFR and/or MPC from a vendor distribution package,
make sure that you have installed both the libraries and the header
files. They may be located in separate packages.
因此使用以下指令进行GCC所需要的依赖包的安装。
xjh@ubuntu:/usr/local/src/gcc-10.1.0$ sudo ./contrib/download_prerequisites
2023-03-10 16:28:23 URL:http://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2 [2383840/2383840] -> "./gmp-6.1.0.tar.bz2" [1]
2023-03-10 16:28:30 URL:http://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2 [1279284/1279284] -> "./mpfr-3.1.4.tar.bz2" [1]
2023-03-10 16:28:34 URL:http://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz [669925/669925] -> "./mpc-1.0.3.tar.gz" [1]
2023-03-10 16:30:19 URL:http://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2 [1658291/1658291] -> "./isl-0.18.tar.bz2" [1]
gmp-6.1.0.tar.bz2: OK
mpfr-3.1.4.tar.bz2: OK
mpc-1.0.3.tar.gz: OK
isl-0.18.tar.bz2: OK
All prerequisites downloaded successfully.
xjh@ubuntu:/usr/local/src/gcc-10.1.0$
然后再次进行配置安装路径,此时没有错误提示。
xjh@ubuntu:/usr/local/src/gcc-10.1.0$ ./configure --prefix=/usr/local/src/gcc-build-10.1.0/
##省略输出内容
configure: creating ./config.status
config.status: creating Makefile
xjh@ubuntu:/usr/local/src/gcc-10.1.0$
(3)支持语言的配置
GCC编译器支持多种编程语言的编译,但是我们只需要编译C与C++程序。
我们可以通过下面命令来配置GCC编译器,以支持C和C++的编译(注意前面的配置--prefix在这里也要添上去,否则默认将可执行文件安装到/usr/local/bin,将库文件放到/usr/local/lib中)。
xjh@ubuntu:/usr/local/src/gcc-10.1.0$ sudo ./configure --prefix=/usr/local/src/gcc-build-10.1.0/ --enable-checking=release --enable-languages=c,c++ --disable-multilib
###省略部分输出
checking whether to enable maintainer-specific portions of Makefiles... no
configure: creating ./config.status
config.status: creating Makefile
xjh@ubuntu:/usr/local/src/gcc-10.1.0$
3、对源码进行编译
上面的配置会生成Makefile文件,接下来我们可以使用 make 命令来编译 GCC 源程序。
xjh@ubuntu:/usr/local/src/gcc-10.1.0$ sudo make
编译的过程耗费时间很长,另外也出现错误提示:
configure: error: C++ preprocessor "/lib/cpp" fails sanity check
这是因为缺少必要的C++库,可以通过以下命令安装这些库文件。
apt-get install build-essential
apt-get install g++
经过上面的修改与处理后,再次执行编译则会成功。
xjh@ubuntu:/usr/local/src/gcc-10.1.0$ sudo make
##省略部分输出
make[4]: Leaving directory `/usr/local/src/gcc-10.1.0/i686-pc-linux-gnu/libatomic'
make[3]: Leaving directory `/usr/local/src/gcc-10.1.0/i686-pc-linux-gnu/libatomic'
make[2]: Leaving directory `/usr/local/src/gcc-10.1.0/i686-pc-linux-gnu/libatomic'
make[1]: Leaving directory `/usr/local/src/gcc-10.1.0'
xjh@ubuntu:/usr/local/src/gcc-10.1.0$
4、安装GCC编译器
通过执行以下命令来安装经过编译后的GCC编译器,安装好成功后有如下提示。
xjh@ubuntu:/usr/local/src/gcc-10.1.0$ sudo make install
####省略部分输出
----------------------------------------------------------------------
Libraries have been installed in:
/usr/local/lib
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
make[4]: Nothing to be done for `install-data-am'.
make[4]: Leaving directory `/usr/local/src/gcc-10.1.0/i686-pc-linux-gnu/libatomic'
make[3]: Leaving directory `/usr/local/src/gcc-10.1.0/i686-pc-linux-gnu/libatomic'
make[2]: Leaving directory `/usr/local/src/gcc-10.1.0/i686-pc-linux-gnu/libatomic'
make[1]: Leaving directory `/usr/local/src/gcc-10.1.0'
xjh@ubuntu:/usr/local/src/gcc-10.1.0$
5、多版本GCC的切换与共存
旧版本的gcc命令位于/usr/bin目录下,它是一个链接符号,指向/usr/bin/gcc-4.8命令,如下所示。
xjh@ubuntu:/usr/bin$ ls gcc -l
lrwxrwxrwx 1 root root 7 六月 5 2022 gcc -> gcc-4.8
xjh@ubuntu:/usr/bin$
新版本gcc安装完成后,在/usr/local/src/gcc-build-10.1.0/bin目录下也有一个gcc命令。
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0$ ls
bin include lib libexec share
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0$ cd bin
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$ ls
c++ g++ gcc-ar gcc-ranlib gcov-dump i686-pc-linux-gnu-c++ i686-pc-linux-gnu-gcc i686-pc-linux-gnu-gcc-ar i686-pc-linux-gnu-gcc-ranlib
cpp gcc gcc-nm gcov gcov-tool i686-pc-linux-gnu-g++ i686-pc-linux-gnu-gcc-10.1.0 i686-pc-linux-gnu-gcc-nm lto-dump
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$
我们可以修改/usr/bin/gcc这个符号链接的指向,实现不同版本GCC编译器的切换。如果这个符号链接指向/usr/bin/gcc-4.8命令,则用的是旧版本的GCC编译器;如果指向/usr/local/src/gcc-build-10.1.0/bin/gcc命令,则使用的是新版本的GCC编译器。
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.8/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04.4' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-i386/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-i386 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-i386 --with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-targets=all --enable-multiarch --disable-werror --with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4)
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$ ls -l /usr/bin/gcc
lrwxrwxrwx 1 root root 16 Mar 11 01:52 /usr/bin/gcc -> /usr/bin/gcc-4.8
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$ sudo rm /usr/bin/gcc
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$ sudo ln -s /usr/local/src/gcc-build-10.1.0/bin/gcc /usr/bin/gcc
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$ ls -l /usr/bin/gcc
lrwxrwxrwx 1 root root 39 Mar 11 01:55 /usr/bin/gcc -> /usr/local/src/gcc-build-10.1.0/bin/gcc
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$ gcc -v
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/src/gcc-build-10.1.0/libexec/gcc/i686-pc-linux-gnu/10.1.0/lto-wrapper
目标:i686-pc-linux-gnu
配置为:./configure --prefix=/usr/local/src/gcc-build-10.1.0/ --enable-checking=release --enable-languages=c,c++ --disable-multilib
线程模型:posix
Supported LTO compression algorithms: zlib
gcc 版本 10.1.0 (GCC)
xjh@ubuntu:/usr/local/src/gcc-build-10.1.0/bin$
/usr/local/src/gcc-build-10.1.0/目录下有bin目录、lib目录,分别是可执行文件、动静态链接库的存放目录。当我们想要不带路径地使用新版本gcc命令时,需要将bin目录里的内容拷贝到/usr/bin目录下,或者将bin目录路径导出到PATH这个变量中(上面的软链接方式只是为了实现切换)。当我们想要链接某些库函数时,需要通过-L指定lib目录的路径,-l选项指定某库,又或者将lib目录导出到LD_LIBRARY_PATH这个变量中。