本文将在一个纯净的Ubuntu 22.04 LTS 下构建ARM交叉编译器,GCC版本为11.1.0。
必需的依赖项:
sudo apt-get install bison
sudo apt-get install texinfo
sudo apt-get install build-essential
sudo apt-get install make
sudo apt-get install gawk
创建工作文件夹并进入
mkdir cross
cd cross
本文采用的软件包版本为:binutils-2.38, GCC-11.1.0, linux-kernel-5.10.5, glibc-2.33
下载软件包:
wget http://ftpmirror.gnu.org/binutils/binutils-2.38.tar.gz
wget http://ftpmirror.gnu.org/gcc/gcc-11.1.0/gcc-11.1.0.tar.gz
wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v5.x/linux-5.10.5.tar.xz
wget http://ftpmirror.gnu.org/glibc/glibc-2.33.tar.xz
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz
下载完成后,提取文件:
for f in *.tar*; do tar xf $f; done
进入GCC目录,下载GCC依赖项:
cd gcc-11.1.0
./contrib/download_prerequisites
该过程会自动下载gmp、mpfr、mpc和isl。
将cloog链接到GCC目录:
ln -s ../cloog-0.18.1 cloog
选择一个安装目录,并确保对它有写权限。在接下来的步骤中,将把新的工具链安装到/opt/cross
sudo mkdir /opt/cross
sudo chmod -R 777 /opt/cross
在接下来的步骤中,需要用到已经安装到/opt/cross/bin中的工具,因此需要将/opt/cross/bin添加到环境变量中。这里推荐修改~/.bashrc文件,因为修改后可以立即生效,而且对全局有效。
sudo vim ~/.bashrc
export PATH=/opt/cross/bin:$PATH
source ~/.bashrc
检查环境变量是否生效:
echo $PATH
至此,准备工作完成,接下来开始安装。建议所有操作在root
用户下进行,以免出现问题。
此步骤构建并安装交叉汇编器、交叉链接器和其他工具。
mkdir build-binutils
cd build-binutils
../binutils-2.38/configure --prefix=/opt/cross --target=aarch64-linux --disable-multilib
make -j4
make install
cd ..
–prefix 为工具安装的目标位置
–taeget 为目标工具的名称
–disable-multilib 表示只安装aarch64,不兼容32位
这个步骤将Linux内核头文件安装到/opt/cross/aarch64-linux/include,从而允许我们构建的交叉编译器编译出的程序能够进行系统调用。
cd linux-5.10.5/
make ARCH=arm64 INSTALL_HDR_PATH=/opt/cross/aarch64-linux headers_install
cd ..
这一步将构建GCC的交叉编译器,并将它们安装到/opt/cross/bin。
mkdir build-gcc
cd build-gcc
../gcc-11.1.0/configure --prefix=/opt/cross --target=aarch64-linux --enable-languages=c,c++,fortran,objc,obj-c++ --disable-multilib
make -j4 all-gcc
make install-gcc
cd..
–prefix 指定安装位置
–target 指定目标交叉编译i器,同时,构建的交叉编译器也会以aarch64-linux为前缀
–enable-languages 指定支持的编程语言
–disable-multilib 表示只支持64位,不兼容32位
这一步中将Glibc的标准C库头文件安装到/opt/cross/aarch64-linux/include,并使用步骤3中内置的C编译器来编译库的启动文件,并将它们安装到/opt/cross/aarch64-linux/lib。
mkdir build-glibc
cd build-glibc
../glibc-2.33/configure --prefix=/opt/cross/aarch64-linux --build=$MACHTYPE --host=aarch64-linux --target=aarch64-linux --with-headers=/opt/cross/aarch64-linux/include --disable-multilib libc_cv_forced_unwind=yes
make install-bootstrap-headers=yes install-headers
make csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o /opt/cross/aarch64-linux/lib
aarch64-linux-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /opt/cross/aarch64-linux/lib/libc.so
touch /opt/cross/aarch64-linux/include/gnu/stubs.h
cd ..
–prefix 指定安装位置
–host和–target指定glibc库最终运行的系统
–with-headers指定内核头文件,即第2步中我们安装的linux内核头文件
详细信息可使用如下命令查看:
../glibc-2.33/configure --help
编译器支持库包含一些C++异常处理样板代码。
cd build-gcc
make -j8 all-target-libgcc
make install-target-libgcc
cd ..
在这一步中构建标准C库并将其文件安装到 /opt/cross/aarch64-linux/lib/。静态库名为libc.a,共享库名为libc.so。
cd build-glibc
make -j8
make install
cd ..
这一步构建了标准的C++库并安装到/opt/cross/aarch64-linux/lib64/。生成的静态库名为libstdc++.a,共享库为 libstdc++.so。
cd build-gcc
make -j8
make install
cd ..
这里可能会报错,提示PATH_MAX未定义
../../../../gcc-11.1.0/libsanitizer/asan/asan_linux.cpp: 在函数‘void __asan::AsanCheckIncompatibleRT()’中:
../../../../gcc-11.1.0/libsanitizer/asan/asan_linux.cpp:199:21: 错误:‘PATH_MAX’在此作用域中尚未声明
199 | char filename[PATH_MAX];
| ^~~~~~~~
../../../../gcc-11.1.0/libsanitizer/asan/asan_linux.cpp:200:35: 错误:‘filename’ was not declared in this scope; did you mean ‘rename’?
200 | MemoryMappedSegment segment(filename, sizeof(filename));
| ^~~~~~~~
| rename
make[4]: *** [Makefile:654:asan_linux.lo] 错误 1
解决方法为:
cd gcc-11.1.0/libsanitizer/asan
vim asan_linux.cpp
在打开的文件前面添加如下代码:
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
保存后退出,重新编译即可。
aarch64-linux-gcc -v
出现如下信息即表示构建成功:
使用内建 specs。
COLLECT_GCC=aarch64-linux-gcc
COLLECT_LTO_WRAPPER=/opt/cross/libexec/gcc/aarch64-linux/11.1.0/lto-wrapper
目标:aarch64-linux
配置为:../gcc-11.1.0/configure --prefix=/opt/cross --target=aarch64-linux --enable-languages=c,c++,fortran,objc,obj-c++ --disable-multilib
线程模型:posix
Supported LTO compression algorithms: zlib
gcc 版本 11.1.0 (GCC)