本文介绍如何在CentOS6.5(或RHEL6.5)上基于源码包构建高版本gcc和glibc,搭建交叉编译环境;并举例说明基于这个交叉编译环境,编译GNU tool chain工程(以编译Python-3为例)、CMake工程(以编译MySQL5.7为例)、以及其他C++工程(以编译boost库为例)的方法。最后再简要介绍一下,如何使用交叉编译环境中的gdb进行调试。
升级编译环境是一个非常复杂而耗时的工程,因为gcc和glibc之间存在相互依赖,所以只能先构建出高版本的GNU工具链和高版本gcc,再用高版本gcc和GNU工具链构建高版本glibc,而后再基于新构建出的glibc重新构建gcc,最后再基于新构建的glibc和gcc重新构建GNU工具链、并进一步构建出CMake工具。(注:gcc和glibc的编译时间都非常长,而且gcc要编译两次)
开始构建工作之前,我们需要先准备以下源码包:
GCC和glibc:
gcc-10.2.1.tar.bz2
glibc-2.24.tar.gz
GNU工具及其依赖库:
autoconf-2.68.tar.gz
automake-1.16.tar.gz
binutils-2.36.tar.gz
bison-3.4.2.tar.gz
expat-2.3.0.tar.gz
gdb-10.1.tar.gz
libidn-1.35.tar.gz
m4-1.4.18.tar.gz
make-4.3.tar.gz
texinfo-6.7.tar.gz
Linux内核源码包:
linux-5.11.4.tar.xz
Python-3及其依赖库(Python-3依赖于libffi库):
libffi-3.3.tar.gz
Python-3.9.2.tgz
Git工具及其依赖库(git依赖于zlib库):
zlib-1.2.11.tar.gz
git-2.28.0.tar.gz
CMake3:
cmake-3.4.3.tar.gz
MySQL5.7及其依赖库:
ncurses-6.2.tar.gz
openssl-1.1.1-stable.tar.gz
boost_1_59_0.tar.gz
mysql-5.7.32.tar.gz
注:
glibc Released Requires Linux kernel version
----------------------------------------------------------
2.31 1 Feb 2020 ? (same as 2.26?)
2.30 1 Aug 2019 ? (same as 2.26?)
2.29 1 Feb 2019 ? (same as 2.26?)
2.28 1 Aug 2018 ? (same as 2.26?)
2.27 2 Feb 2018 ? (same as 2.26?)
2.26 2 Aug 2017 3.2 (or higher)
2.25 5 Feb 2017 ? (same as 2.24?)
2.24 4 Aug 2016 on i[4567]86 and x86_64 -> 2.6.32
2.24 4 Aug 2016 on other platforms -> 3.2
Note 1: Some minor architectures require a higher kernel
version than listed above.
Note 2: Your Linux distribution may vary from the above,
as glibc can optionally be configured at compile
time to require a kernel version newer than the
oldest supported version.
For reference of other Linux distributions:
Linux distribution glibc version Requires Linux kernel version
----------------------------------------------------------
Debian 10 Buster 2.28 3.2 ?
Debian 9 Stretch 2.24 on x86 2.6.32
Debian 9 Stretch 2.24 on other 3.2
Ubuntu 20.04 2.31 3.2 ?
Ubuntu 18.04 2.27 3.2 ?
Ubuntu 17.10 2.26 3.2
Ubuntu 17.04 2.24 ?
Ubuntu 16.10 2.24 ?
Ubuntu 16.04 2.23 ?
本例工作在/opt目录下,使用/opt/mydev目录作为编译和临时安装目录,使用/opt/devtools目录作为最终安装目录。我们在/opt/mydev目录下创建如下3个子目录:
基于上述目录结构,构建过程大致过程如下:
先构建gcc,并安装在临时安装目录install中;
构建glibc所需的依赖包,并安装在临时安装目录install中;
基于install目录中的gcc和其他依赖库,构建glibc并安装在devtools子目录;
基于devtools子目录中的glibc和install子目录中的gcc,重新构建gcc,并安装在devtools子目录;
最后基于devtools子目录中的glibc和gcc,重新构建全部开发库,并安装至devtools子目录。
我们进入src子目录,并解压所有源码包:
cd /opt/mydev/src
tar zxf autoconf-2.68.tar.gz
tar zxf automake-1.16.tar.gz
tar zxf binutils-2.36.tar.gz
tar zxf bison-3.4.2.tar.gz
tar zxf boost_1_59_0.tar.gz
tar zxf boost_1_73_0.tar.gz
tar zxf bzip2-1.0.6.tar.gz
tar zxf cmake-3.4.3.tar.gz
tar zxf expat-2.3.0.tar.gz
tar jxf gcc-10.2.1.tar.bz2
tar zxf gdb-10.1.tar.gz
tar zxf git-2.28.0.tar.gz
tar zxf glibc-2.24.tar.gz
tar zxf libffi-3.3.tar.gz
tar zxf libidn-1.35.tar.gz
tar Jxf linux-5.11.4.tar.xz
tar zxf m4-1.4.18.tar.gz
tar zxf make-4.3.tar.gz
tar zxf mysql-5.7.32.tar.gz
tar zxf ncurses-6.2.tar.gz
tar zxf openssl-1.1.1-stable.tar.gz
tar zxf Python-3.9.2.tgz
tar zxf texinfo-6.7.tar.gz
tar zxf zlib-1.2.11.tar.gz
安装Linux内核头文件(编译glibc只需要头文件):
cd /opt/mydev/src/linux-5.11.4
make headers_install INSTALL_HDR_PATH=/opt/devtools
构建Python-3:
mkdir /opt/mydev/build/Python3
cd /opt/mydev/build/Python3
/opt/mydev/src/Python-3.9.2/configure --prefix=/opt/mydev/install
make -j4
make install
构建binutils:
mkdir /opt/mydev/build/binutils
cd /opt/mydev/build/binutils
/opt/mydev/src/binutils-2.36/configure --prefix=/opt/mydev/install
make -j4
make install
构建gmake:
mkdir /opt/mydev/build/gmake
cd /opt/mydev/build/gmake
/opt/mydev/src/make-4.3/configure --prefix=/opt/mydev/install
make -j4
make install
构建bison:
mkdir /opt/mydev/build/bison
cd /opt/mydev/build/bison
/opt/mydev/src/bison-3.4.2/configure --prefix=/opt/mydev/install
make -j4
make install
mkdir /opt/mydev/build/gcc
cd /opt/mydev/build/gcc
/opt/mydev/src/gcc-10.2.1/configure --prefix=/opt/mydev/install --disable-multilib
make -j4
make install
export CC=/opt/mydev/install/bin/gcc
export CXX=/opt/mydev/install/bin/g++
export C_INCLUDE_PATH=/opt/mydev/install/lib/gcc/x86_64-pc-linux-gnu/10.2.1/include
export CPLUS_INCLUDE_PATH=${C_INCLUDE_PATH}
OLDPATH=${PATH}
export PATH=/opt/mydev/install/bin:${PATH}
mkdir /opt/mydev/build/glibc
cd /opt/mydev/build/glibc
/opt/mydev/src/glibc-2.24/configure --prefix=/opt/devtools --with-headers=/opt/devtools/include --without-selinux --enable-kernel=2.6.32 --with-binutils=/opt/mydev/install --disable-werror
make -j4
export CC=
export CXX=
export C_INCLUDE_PATH=
export CPLUS_INCLUDE_PATH=
export PATH=${OLDPATH}
make install
注:
GLIBCDIR=/opt/devtools
LDFLAGS="-Wl,-q"
CFLAGS="-L${GLIBCDIR}/lib -Wl,--rpath=${GLIBCDIR}/lib -Wl,--dynamic-linker=${GLIBCDIR}/lib/ld-linux-x86-64.so.2"
export CC=/opt/mydev/install/bin/gcc
export CXX=/opt/mydev/install/bin/g++
export C_INCLUDE_PATH=${GLIBCDIR}/include
export CPLUS_INCLUDE_PATH=${GLIBCDIR}/include
mkdir /opt/mydev/build/gcc-new
cd /opt/mydev/build/gcc-new
/opt/mydev/src/gcc-10.2.1/configure --prefix=/opt/devtools --disable-multilib CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
make distclean
/opt/mydev/src/gcc-10.2.1/configure --prefix=/opt/devtools --disable-multilib CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
make -j4
export CC=
export CXX=
export C_INCLUDE_PATH=
export CPLUS_INCLUDE_PATH=
make install
注:
GLIBCDIR=/opt/devtools
LDFLAGS="-Wl,-q"
CFLAGS="-isystem /opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/include -isystem /opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/backward -isystem /opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/x86_64-pc-linux-gnu -isystem /opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1 -isystem /opt/devtools/include -L${GLIBCDIR}/lib -L${GLIBCDIR}/lib64 -Wl,--rpath=${GLIBCDIR}/lib -Wl,--dynamic-linker=${GLIBCDIR}/lib/ld-linux-x86-64.so.2"
export CC=/opt/devtools/bin/gcc
export CXX=/opt/devtools/bin/g++
export PATH=/opt/devtools/bin:${PATH}
export C_INCLUDE_PATH=${GLIBCDIR}/include
export CPLUS_INCLUDE_PATH=${GLIBCDIR}/include
OLDPATH=${PATH}
export PATH=/opt/mydev/install/bin:${PATH}
注:
构建expat(GNU工具依赖于这个库):
mkdir /opt/mydev/build/expat-new
cd /opt/mydev/build/expat-new
/opt/mydev/src/expat-2.3.0/configure --prefix=/opt/devtools CFLAGS="${CFLAGS} -fPIC" CXXFLAGS="${CFLAGS} -fPIC" LDFLAGS="${LDFLAGS}"
make
make install
重新构建binutils(编译完binutils之后,即可恢复环境变量PATH):
mkdir /opt/mydev/build/binutils-new
cd /opt/mydev/build/binutils-new
/opt/mydev/src/binutils-2.36/configure --prefix=/opt/devtools CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
make -j4
make install
export PATH=${OLDPATH}
重新构建gmake:
mkdir /opt/mydev/build/gmake-new
cd /opt/mydev/build/gmake-new
/opt/mydev/src/make-4.3/configure --prefix=/opt/devtools CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
make -j4
make install
构建m4:
mkdir /opt/mydev/build/m4-new
cd /opt/mydev/build/m4-new
/opt/mydev/src/m4-1.4.18/configure --prefix=/opt/devtools CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
make
make install
构建autoconf:
mkdir /opt/mydev/build/autoconf-new
cd /opt/mydev/build/autoconf-new
/opt/mydev/src/autoconf-2.68/configure --prefix=/opt/devtools CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
make
make install
构建automake:
mkdir /opt/mydev/build/automake-new
cd /opt/mydev/build/automake-new
/opt/mydev/src/automake-1.16/configure --prefix=/opt/devtools CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
make
make install
构建texinfo(gdb依赖于这个库):
mkdir /opt/mydev/build/texinfo-new
cd /opt/mydev/build/texinfo-new
/opt/mydev/src/texinfo-6.7/configure --prefix=/opt/devtools CFLAGS="${CFLAGS} -fPIC" CXXFLAGS="${CFLAGS} -fPIC" LDFLAGS="${LDFLAGS}"
make -j4
make install
构建gdb:
mkdir /opt/mydev/build/gdb-new
cd /opt/mydev/build/gdb-new
/opt/mydev/src/gdb-10.1/configure --prefix=/opt/devtools CFLAGS="-static-libstdc++ -static-libgcc ${CFLAGS}" CXXFLAGS="-static-libstdc++ -static-libgcc ${CFLAGS}" LDFLAGS="${LDFLAGS}"
make -j4
make install
重新构建bison:
mkdir /opt/mydev/build/bison-new
cd /opt/mydev/build/bison-new
/opt/mydev/src/bison-3.4.2/configure --prefix=/opt/devtools CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
make -j4
make install
构建ncurses(MySQL依赖于这个库):
mkdir /opt/mydev/build/ncurses-new
cd /opt/mydev/build/ncurses-new
/opt/mydev/src/ncurses-6.2/configure --prefix=/opt/devtools CFLAGS="${CFLAGS} -fPIC" CXXFLAGS="${CFLAGS} -fPIC" LDFLAGS="${LDFLAGS}"
make -j4
make install
构建libidn:
mkdir /opt/mydev/build/libidn-new
cd /opt/mydev/build/libidn-new
/opt/mydev/src/libidn-1.35/configure --prefix=/opt/devtools CFLAGS="${CFLAGS} -fPIC" CXXFLAGS="${CFLAGS} -fPIC" LDFLAGS="${LDFLAGS}"
make -j4
make install
构建依赖库libffi-3.3:
mkdir /opt/mydev/build/libffi-new
cd /opt/mydev/build/libffi-new
/opt/mydev/src/libffi-3.3/configure --prefix=/opt/devtools CFLAGS="${CFLAGS} -fPIC" CXXFLAGS="${CFLAGS} -fPIC" LDFLAGS="${LDFLAGS}"
make -j4
make install
构建依赖库openssl(MySQL同样依赖于这个库):
mkdir /opt/mydev/build/openssl-new
cd /opt/mydev/build/openssl-new
CMAKE_INCLUDE_PATH=/opt/devtools/include:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/x86_64-pc-linux-gnu:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/backward:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/include CMAKE_LIBRARY_PATH=/opt/devtools/lib64:/opt/devtools/lib cmake /opt/mydev/src/openssl-1.1.1-stable -DCMAKE_INSTALL_PREFIX=/opt/devtools -DCMAKE_C_COMPILER=${GLIBCDIR}/bin/gcc -DCMAKE_CXX_COMPILER=${GLIBCDIR}/bin/g++ -DCMAKE_C_FLAGS="-Wall -O2 -fPIC ${CFLAGS}" -DCMAKE_CXX_FLAGS="-Wall -O2 -fPIC ${CFLAGS}"
make -j4
make install
注:
重新构建Python-3:
mkdir /opt/mydev/build/Python3-new
cd /opt/mydev/build/Python3-new
/opt/mydev/src/Python-3.9.2/configure --prefix=/opt/devtools --with-openssl=/opt/devtools CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${CFLAGS} ${LDFLAGS} -lrt"
make -j4
make install
注:构建Python-3的过程,可以作为构建标准GNU tool chain工程的例子。
mkdir /opt/mydev/build/cmake-new
cd /opt/mydev/build/cmake-new
CMAKE_INCLUDE_PATH=/opt/devtools/include:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/x86_64-pc-linux-gnu:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/backward:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/include CMAKE_LIBRARY_PATH=/opt/devtools/lib64:/opt/devtools/lib cmake /opt/mydev/src/cmake-3.4.3 -DCMAKE_INSTALL_PREFIX=/opt/devtools -DCMAKE_C_COMPILER=${GLIBCDIR}/bin/gcc -DCMAKE_CXX_COMPILER=${GLIBCDIR}/bin/g++ -DCMAKE_C_FLAGS="-static-libstdc++ -static-libgcc ${CFLAGS}" -DCMAKE_CXX_FLAGS="-static-libstdc++ -static-libgcc ${CFLAGS}"
make -j4
make install
构建依赖库zlib:
mkdir /opt/mydev/build/zlib-new
cd /opt/mydev/build/zlib-new
CMAKE_INCLUDE_PATH=/opt/devtools/include:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/x86_64-pc-linux-gnu:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/backward:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/include CMAKE_LIBRARY_PATH=/opt/devtools/lib64:/opt/devtools/lib cmake /opt/mydev/src/zlib-1.2.11 -DCMAKE_INSTALL_PREFIX=/opt/devtools -DCMAKE_C_COMPILER=${GLIBCDIR}/bin/gcc -DCMAKE_CXX_COMPILER=${GLIBCDIR}/bin/g++ -DCMAKE_C_FLAGS="${CFLAGS}" -DCMAKE_CXX_FLAGS="${CFLAGS}"
make -j4
make install
构建git:
cd /opt/mydev/src/git-2.28.0
./configure --prefix=/opt/devtools CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS} -ldl"
make -j4
make install
注:git不支持跨目录编译 。
构建依赖库bzip2:
cd /opt/mydev/src/bzip2-1.0.6
BZIP2_CFLAGS="-fPIC ${CFLAGS}" BZIP2_LDFLAGS="${LDFLAGS}" make
BZIP2_PREFIX="/opt/devtools" make install
注:bzip2不支持跨目录编译,而且bzip2既不是GNU工程,也不是CMake工程,而是直接基于Makefile编译。对于此类工程的编译,上述过程可以作为一个例子。
编译boost库:
cd /opt/mydev/src/boost_1_59_0
CXX="g++ -static-libstdc++ -static-libgcc ${CFLAGS}" ./bootstrap.sh --prefix=/opt/devtools --with-python=python3
sed -i "s/using gcc/using gcc : 10.2 : g++ : \"-isystem \/opt\/devtools\/lib\/gcc\/x86_64-pc-linux-gnu\/10.2.1\/include -isystem \/opt\/devtools\/lib\/gcc\/x86_64-pc-linux-gnu\/10.2.1\/..\/..\/..\/..\/include\/c++\/10.2.1\/backward -isystem \/opt\/devtools\/lib\/gcc\/x86_64-pc-linux-gnu\/10.2.1\/..\/..\/..\/..\/include\/c++\/10.2.1\/x86_64-pc-linux-gnu -isystem \/opt\/devtools\/lib\/gcc\/x86_64-pc-linux-gnu\/10.2.1\/..\/..\/..\/..\/include\/c++\/10.2.1 -isystem \/opt\/devtools\/include -L\/opt\/devtools\/lib -L\/opt\/devtools\/lib64 -Wl,--rpath=\/opt\/devtools\/lib -Wl,--dynamic-linker=\/opt\/devtools\/lib\/ld-linux-x86-64.so.2 -fPIC\"/g" project-config.jam
./b2 --segmented-stacks=on --link=static
mkdir /opt/devtools/boost_1_59_0
\cp -frP boost stage /opt/devtools/boost_1_59_0
注:
mkdir /opt/mydev/build/mysql-5.7.32
cd /opt/mydev/build/mysql-5.7.32
CMAKE_INCLUDE_PATH=/opt/devtools/include:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/x86_64-pc-linux-gnu:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/../../../../include/c++/10.2.1/backward:/opt/devtools/lib/gcc/x86_64-pc-linux-gnu/10.2.1/include CMAKE_LIBRARY_PATH=/opt/devtools/lib64:/opt/devtools/lib cmake /opt/mydev/src/mysql-5.7.32 -DCMAKE_INSTALL_PREFIX=/opt/mysql5.7.32 -DCMAKE_C_COMPILER=${GLIBCDIR}/bin/gcc -DCMAKE_CXX_COMPILER=${GLIBCDIR}/bin/g++ -DCMAKE_C_FLAGS="${CFLAGS}" -DCMAKE_CXX_FLAGS="${CFLAGS}" -DWITH_SSL=system -DWITH_RAPID=on -DWITH_BOOST="/opt/devtools/boost_1_59_0"
make -j4
make install
注:
使用非系统自带的gdb进行调试时,需要在启动gdb时,通过“set auto-load safe-path”命令将“/opt/devtools”指定为安全路径,否则gdb访问“/opt/devtools”时会失败。启动命令如下:
/opt/devtools/bin/gdb -q -iex "set auto-load safe-path /opt/devtools" --pid=81665
注:其中,“--pid”参数用于指定要debug的进程ID。