前言 

以源码方式安装软件,需要对源码进行编译,因此要求当前系统中存在一个可用的编译器。Linux发行版一般都安装了GCC编译器,但版本一般较低。因此博文将以安装指定版本GCC编译器为例,说明使用源码安装软件的方法,其他软件源码包安装方法大同小异。

使用源码安装软件的三个步骤:配置(configure)、编译(make)与安装(make install),如下图所示。(其中configure、Makefile.in一般由项目管理器自动生成的,GCC编译器需要安装。)

编译安装zabbix起不来 安装编译器_服务器


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。

编译安装zabbix起不来 安装编译器_linux_02

用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 &

编译安装zabbix起不来 安装编译器_运维_03

(1)安装路径的配置

通过执行"./configure -h"可以查看帮助。

由下图可知,--prefix选项用来配置安装的路径。如果没有通过该选项指定安装路径,则默认将可执行文件安装到/usr/local/bin,将库文件放到/usr/local/lib中。

编译安装zabbix起不来 安装编译器_运维_04

建议使用--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这个变量中。