背景
有时我们所用的内核版本太旧,系统自带的库(如libstdc++.so.6)版本低或者依赖的其他软件版本较低,导致无法安装目标软件。
软件/库其实是对机器汇编指令集的封装,在X86体系下,不同版本的内核其实指令集差别不是很大,所以我们可以在机器上自己编译新版本的软件依赖库,进而安装我们需要的软件。
方法
我们自己编译安装一些系统没有的软件版本,需要知道一些常见的编译方法和编译参数。
1. 直接包含configure脚本
configure
是用来检测你的安装平台的目标特征的。比如它会检测你是不是有CC或GCC,并不是需要CC或GCC;也会检查一些依赖软件/库的版本。
其常用参数如下:
CC:指定gcc编译binary,比如我们可以指定自己编译出的gcc最新版本
CXX:指定g++编译binary,一般与gcc在一个目录
--prefix=DIR:指定安装目录
--program-suffix=-5:比如在安装gcc 5.x.x版本时,可以指定binary后缀为-5,编译出来名称则为gcc-5和g++-5
--disable-multilib:不生成32位库
PKG_CONFIG_PATH:依赖库安装完成,可以将其lib目录下的pkgconfig加入该环境变量。
命令举例:
PKG_CONFIG_PATH=/home/admin/brotli/lib/pkgconfig:/home/admin/sqlite/lib/pkgconfig:/home/admin/xz/lib/pkgconfig:$PKG_CONFIG_PATH ./configure CXX="/home/admin/gcc-5.5.0/bin/g++-5" --prefix=/home/admin
上述configure
脚本执行完后会生成Makefile
,此时直接使用make && make install
即可安装完成。
2. 包含autogen.sh
表明该项目依赖了autoconf
、automake
等工具。
直接运行autogen.sh
会产生configure
,如果出现如下类似错误:
$./autogen.sh
configure.ac:54: installing 'build-aux/ar-lib'
src/Makefile.am:54: error: Libtool library used but 'LIBTOOL' is undefined
src/Makefile.am:54: The usual way to define 'LIBTOOL' is to add 'LT_INIT'
src/Makefile.am:54: to 'configure.ac' and run 'aclocal' and 'autoconf' again.
src/Makefile.am:54: If 'LT_INIT' is in 'configure.ac', make sure
src/Makefile.am:54: its definition is in aclocal's search path.
tests/Makefile.am:33: error: Libtool library used but 'LIBTOOL' is undefined
tests/Makefile.am:33: The usual way to define 'LIBTOOL' is to add 'LT_INIT'
tests/Makefile.am:33: to 'configure.ac' and run 'aclocal' and 'autoconf' again.
tests/Makefile.am:33: If 'LT_INIT' is in 'configure.ac', make sure
tests/Makefile.am:33: its definition is in aclocal's search path.
tools/Makefile.am:21: error: Libtool library used but 'LIBTOOL' is undefined
tools/Makefile.am:21: The usual way to define 'LIBTOOL' is to add 'LT_INIT'
tools/Makefile.am:21: to 'configure.ac' and run 'aclocal' and 'autoconf' again.
tools/Makefile.am:21: If 'LT_INIT' is in 'configure.ac', make sure
tools/Makefile.am:21: its definition is in aclocal's search path.
autoreconf: automake failed with exit status: 1
则需要安装libtool
工具,其依赖的m4
、autoconf
、automake
、help2man
等工具如果版本不匹配则也需要编译安装。如果安装最新版则需要安装较新的gcc。
相关软件:
m4
https://mirrors.ustc.edu.cn/gnu/m4/ 编译时需要加:CPPFLAGS="-fgnu89-inline"
automake
https://mirrors.ustc.edu.cn/gnu/automake/automake-1.16.1.tar.gzhelp2man
https://mirrors.ustc.edu.cn/gnu/help2man/help2man-1.47.8.tar.xz
由上述我们可以看到:自己编译软件包版本虽然能够解决依赖冲突问题,但是复杂的依赖关系靠人工解决显然效率过低,所以此处需要介绍一个工具:
Nix
Nix is a powerful package manager for Linux and other Unix systems that makes package management reliable and reproducible. It provides atomic upgrades and rollbacks, side-by-side installation of multiple versions of a package, multi-user package management and easy setup of build environments. Read more…
其恰好是工具化了上述人工编译过程,一个软件包的安装,自动下载其依赖的其他binary,使得每个软件的依赖不会相互交叠,极大方便了用户管理(升级)软件。
附录
下面将一些遇到的编译错误记录,方便回顾。
编译Nix
gcc版本
configure: error: *** A compiler with support for C++14 language features is required.
解决方法:编译安装高版本GCC,C++14需要安装gcc 5.x.x版本
sqlite3版本过低
checking for sqlite3 >= 3.6.19... no
configure: error: Package requirements (sqlite3 >= 3.6.19) were not met:
Requested 'sqlite3 >= 3.6.19' but version of SQLite is 3.3
解决方法:
编译安装sqlite3,并指定pkg config、g++版本
PKG_CONFIG_PATH=/home/admin/sqlite/lib/pkgconfig:$PKG_CONFIG_PATH ./configure CXX="/home/admin/gcc-5.5.0/bin/g++-5"
依赖liblzma
configure: error: Package requirements (liblzma) were not met:
No package 'liblzma' found
解决方法:安装XZ Utils
https://www.tukaani.org/xz/
依赖libbrotlidec
configure: error: Package requirements (libbrotlienc libbrotlidec) were not met:
No package 'libbrotlienc' found
No package 'libbrotlidec' found
找到库
https://github.com/google/brotli
编译安装
cd out && ../configure-cmake --prefix=/home/admin/brotli
cmake版本不对
下载:https://cmake.org/download/
编译:
./configure CC="/home/admin/gcc-5.5.0/bin/gcc-5"
LD_LIBRARY_PATH=/home/admin/gcc-5.5.0/lib64:$LD_LIBRARY_PATH ./configure CC="/home/admin/gcc-5.5.0/bin/gcc-5" CXX="/home/admin/gcc-5.5.0/bin/g++-5"
依赖libseccomp
configure: error: Package requirements (libseccomp) were not met:
No package 'libseccomp' found
找到库
https://github.com/seccomp/libseccomp
需要按照前面所述的安装libtool
等工具。
编译GCC
编译命令
./configure --prefix=/home/admin/gcc/ --program-suffix=-5 --enable-checking=release --enable-languages=c,c++ --disable-multilib
无法下载依赖包问题
修改contrib/download_prerequisites
的FTP为HTTP