0. 系统环境
系统:
- ubuntu16.04
1. 编译交叉编译工具链
交叉编译工具链需要用到至少七个库:
同时我们还有两个用于优化的库:
这两个库是可选的。搭建完成后我们会获得一系列编译、链接工具,包括我们熟知的 gcc
、ld
等。
工具版本
1.binutils-2.37 2.gcc-7.3.0 3.glibc-2.27 4.gmp-6.2.0 5.mpc-1.1.0 6.mpfr-4.0.2
7.linux-4.14.98 8.cloog-0.18.1 9.isl-0.18
进入/home/work/toolchain目录下载相应的包脚本 1-down.sh
#!/bin/sh
export GNU_MIRROR_SITE=https://mirrors.tuna.tsinghua.edu.cn/gnu/
export KERNEL_MIRROR_SITE=https://mirrors.tuna.tsinghua.edu.cn/kernel/
wget $GNU_MIRROR_SITE/binutils/binutils-2.37.tar.xz # binutils
wget $GNU_MIRROR_SITE/gcc/gcc-7.3.0/gcc-7.3.0.tar.xz # gcc
wget $GNU_MIRROR_SITE/glibc/glibc-2.27.tar.xz # glibc
wget $KERNEL_MIRROR_SITE/v4.x/linux-4.14.98.tar.xz # kernel
wget $GNU_MIRROR_SITE/mpfr/mpfr-4.0.2.tar.xz # mpfr
wget $GNU_MIRROR_SITE/gmp/gmp-6.2.0.tar.xz # gmp
wget $GNU_MIRROR_SITE/mpc/mpc-1.1.0.tar.gz # mpc
# optional
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2 # isl
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz # cloog
进入/home/work/toolchain目录解压库文件,脚本2-tar.sh
#!/bin/sh
for f in *.tar.xz;
do
tar -xJf $f;
done
for f in *.tar.bz2;
do
tar -xjf $f;
done
for f in *.tar.gz;
do
tar -xzf $f;
done
建立 GCC 依赖库们的软链接,进入/home/work/toolchain目录执行脚本脚本3-ln.sh
#!/bin/sh
ln -sf ../mpfr-4.0.2 gcc-7.3.0/mpfr # mfpr
ln -sf ../gmp-6.2.0 gcc-7.3.0/gmp # gmp
ln -sf ../mpc-1.1.0 gcc-7.3.0/mpc # mpc
# optional
ln -sf ../isl-0.18 gcc-7.3.0/isl # isl
ln -sf ../cloog-0.18.1 gcc-7.3.0/cloog # cloog
设定编译时使用的线程数
export NPROC=`nproc`
1.2. 编译安装 Binutils
这个工具包将会被安装在 /home/work/toolchain/path/bin
内,包括了交叉汇编器、交叉链接器等工具,脚本
#!/bin/sh
export NPROC=`nproc`
export CROSS_COMPILE_INSTALL=/home/work/toolchain/path
mkdir binutils
cd binutils
../binutils-2.37/configure \
--prefix=$CROSS_COMPILE_INSTALL \
--target=aarch64-cc-linux \
--enable-multilib
make -j$NPROC
make install
1.3. 安装 Linux Kernel 头文件
这一步会将 Linux Kernel 头文件安装咋 $CROSS_COMPILE_INSTALL/aarch64-install/include
,这样交叉编译链编译出的软件可以在目标平台中使用 Linux 系统调用。
export NPROC=`nproc`
export CROSS_COMPILE_INSTALL=/home/work/toolchain/path
cd ./linux-4.14.98
make \
ARCH=arm64 \
INSTALL_HDR_PATH=$CROSS_COMPILE_INSTALL/aarch64-cc-linux \
headers_install
1.4. 编译安装 GCC 和 glibc
这是很长的一步,我们将要轮流编译属于两个库(GCC 和 glibc)的组件,并最终全部编译完成。编译顺序如下(图源为参考博客)
1.4.1. 编译器
这一步只会安装 C/C++ 交叉编译器本身,它们会被安装在 $CROSS_COMPILE_INSTALL/bin
。
export NPROC=`nproc`
export CROSS_COMPILE_INSTALL=/home/work/toolchain/path
mkdir gcc
cd gcc
../gcc-7.3.0/configure \
--prefix=$CROSS_COMPILE_INSTALL \
--target=aarch64-cc-linux \
--enable-language=c,c++ \
--with-gnu-ld --enable-shared --enable-threads=posix --enable-multilib --enable-c99 --enable-long-long \
--enable-libstdcxx-pch --enable-lto --enable-libssp --enable-libitm --disable-bootstrap --disable-libmudflap \
--with-system-zlib --enable-linker-build-id --with-ppl=no --with-cloog=no --enable-checking=release --without-isl --enable-nls \
--without-local-prefix --with-linker-hash-style=gnu --without-long-double-128 --enable-poison-system-directories --enable-initfini-array \
--disable-silent-rules --enable-symvers=gnu --enable-cheaders=c_global --enable-__cxa_atexit
make -j$NPROC all-gcc
make install-gcc
这一步要编译个十分钟左右
1.4.2. 标准 C 头文件和启动文件
这一步里我们将所有的标准 C 头文件安装在 $CROSS_COMPILE_INSTALL/aarch64-cc-linux/include
内。同时我们还会编译一些启动文件并安装在 $CROSS_COMPILE_INSTALL/aarch64-cc-linux/lib
内,这些文件将被下一步用到,并在下下步被替换。
注意: 如果前面没有把 $CROSS_COMPILE_INSTALL/bin
加入到 PATH
中的话这一步会报错。
export NPROC=`nproc`
export CROSS_COMPILE_INSTALL=/home/work/toolchain/path
export PATH=$PATH:$CROSS_COMPILE_INSTALL/bin
mkdir glibc
cd glibc
../glibc-2.27/configure \
--prefix=$CROSS_COMPILE_INSTALL/aarch64-cc-linux \
--build=$MACHTYPE \
--host=aarch64-cc-linux \
--target=aarch64-cc-linux \
--with-headers=$CROSS_COMPILE_INSTALL/aarch64-cc-linux/include \
--enable-multilib \
libc_cv_forced_unwind=yes
# --disable-multilib \
make install-bootstrap-headers=yes install-headers
make -j$NPROC csu/subdir_lib #
install csu/crt1.o csu/crti.o csu/crtn.o $CROSS_COMPILE_INSTALL/aarch64-cc-linux/lib
aarch64-cc-linux-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $CROSS_COMPILE_INSTALL/aarch64-cc-linux/lib/libc.so
touch $CROSS_COMPILE_INSTALL/aarch64-cc-linux/include/gnu/stubs.h
1.4.3. 编译器支持库
这一步我们使用前面编译得到的交叉编译器来编译编译器支持库。
export NPROC=`nproc`
export CROSS_COMPILE_INSTALL=/home/work/toolchain/path
export PATH=$PATH:$CROSS_COMPILE_INSTALL/bin
cd ./gcc
make -j$NPORC all-target-libgcc #
make install-target-libgcc
1.4.4. 编译标准 C 库
这一步我们可以完成 glibc 的编译安装。标准 C 库将被安装于 $CROSS_COMPILE_INSTALL/aarch64-cc-linux/lib
。
export NPROC=`nproc`
export CROSS_COMPILE_INSTALL=/home/work/toolchain/path
export PATH=$PATH:$CROSS_COMPILE_INSTALL/bin
cd ./glibc
make -j$NPROC
make install
这一步也要编译个十分钟左右
1.4.5. 编译标准 C++ 库
这一步我们可以完成 GCC 的编译安装。标准 C++ 库将被安装于 $CROSS_COMPILE_INSTALL/aarch64-cc-linux/lib64
。
cd ./gcc
make -j$NPROC
make install
这一步也要编译个十分钟左右
1.5. strip
export NPROC=`nproc`
export CROSS_COMPILE_INSTALL=/home/work/toolchain/path
export PATH=$PATH:$CROSS_COMPILE_INSTALL/bin
cd $CROSS_COMPILE_INSTALL/libexec/gcc/aarch64-mile-linux/7.3.0
strip cc1 cc1obj cc1plus collect2 f951 lto1 lto-wrapper
cd $CROSS_COMPILE_INSTALL/bin
strip *
1.5. 测试交叉编译器
aarch64-cc-linux-gcc helloworld.c -o hello
./hello