突然想看看在ARM64开发板上编译代码会是什么样的,首先需要把gcc源码通过aarch64-linux-gnu-gcc编译成ARM aarch64指令的编译工具。
- 所需原材料
gmp https://mirrors.aliyun.com/gnu/gmp/gmp-6.2.0.tar.xz
mpfr https://mirrors.aliyun.com/gnu/mpfr/mpfr-4.1.0.tar.xz
mpc https://mirrors.aliyun.com/gnu/mpc/mpc-1.2.0.tar.gz
glibc https://mirrors.aliyun.com/gnu/glibc/glibc-2.29.tar.xz
gcc https://mirrors.aliyun.com/gnu/gcc/gcc-7.5.0/gcc-7.5.0.tar.xz
linux https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.3.12.tar.xz
Ubuntu系统 Linux version 5.4.0-42-generic (buildd@lgw01-amd64-023) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #46~18.04.1-Ubuntu SMP Fri Jul 10 07:21:24 UTC 2020
GCC交叉编译工具 aarch64-linux-gnu-gcc和aarch64-linux-gnu-g++
- 解压所有软件包
zhihqiao@zhihqiao:/mnt/workspace/code$ ll
drwxr-xr-x 37 zhi zhi 4096 9月 27 11:19 gcc-7.5.0/
drwxrwxr-x 69 zhi zhi 4096 9月 27 16:33 glibc-2.29/
drwxr-xr-x 15 zhi zhi 4096 1月 17 2020 gmp-6.2.0/
drwxr-xr-x 8 zhi zhi 4096 8月 17 23:23 mpc-1.2.0/
drwxr-xr-x 9 zhi zhi 4096 7月 10 19:59 mpfr-4.1.0/
drwxrwxr-x 24 zhi zhi 4096 9月 27 14:38 linux-5.3.12/
- 安装aarch64-linux-gnu-gcc和aarch64-linux-gnu-g++交叉编译工具
sudo apt install gcc-aarch64-linux-gnu
sudo apt install g++-aarch64-linux-gnu
- 创建安装目录
zhi@zhi:/mnt/workspace$ ll
drwxrwxr-x 8 zhi zhi 4096 9月 27 15:09 aarch64-gcc/
drwxrwxr-x 2 zhi zhi 4096 9月 27 14:01 aarch64-glibc/
drwxrwxr-x 5 zhi zhi 4096 9月 27 10:20 aarch64-gmp/
drwxrwxr-x 5 zhi zhi 4096 9月 27 10:23 aarch64-mpc/
drwxrwxr-x 5 zhi zhi 4096 9月 27 10:22 aarch64-mpfr/
- 安装Linux kernel头文件
make ARCH=arm64 INSTALL_HDR_PATH=/mnt/workspace/aarch64-gcc/aarch64-linux-gnu headers_install
- 编译gmp,mpfr,mpc和glibc
创建编译目录
zhi@zhi:/mnt/workspace/code$ ll build-*
drwxrwxr-x 15 zhih zhi 4096 9月 27 16:31 build-aarch64-gmp/
drwxrwxr-x 6 zhih zhi 4096 9月 27 16:32 build-aarch64-mpc/
drwxrwxr-x 7 zhih zhi 4096 9月 27 16:31 build-aarch64-mpfr/
drwxrwxr-x 14 zhi zhi 4096 9月 27 16:58 build-aarch64-gcc/
drwxrwxr-x 62 zhi zhi 4096 9月 27 16:38 build-aarch64-glibc/
交叉编译gmp
./../gmp-6.2.0/configure --prefix=/mnt/workspace/aarch64-gmp --host=aarch64-linux-gnu --target=aarch64-linux-gnu
make -j16 && make install
交叉编译mpfr
./../mpfr-4.1.0/configure --prefix=/mnt/workspace/aarch64-mpfr --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-gmp=/mnt/workspace/aarch64-gmp
make -j16 && make install
交叉编译mpc
./../mpc-1.2.0/configure --prefix=/mnt/workspace/aarch64-mpc --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-gmp=/mnt/workspace/aarch64-gmp --with-mpfr=/mnt/workspace/aarch64-mpfr
make -j16 && make install
交叉编译glibc
./../glibc-2.29/configure --prefix=/mnt/workspace/aarch64-gcc/aarch64-linux-gnu --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-headers=/mnt/workspace/aarch64-gcc/aarch64-linux-gnu/include --disable-multilib libc_cv_forced_unwind=yes
make -j16 && make install
- 交叉编译gcc
./../gcc-7.5.0/configure --prefix=/mnt/workspace/aarch64-gcc --host=aarch64-linux-gnu --target=aarch64-linux-gnu --enable-languages=c,c++ --disable-multilib --with-mpc=/mnt/workspace/aarch64-mpc --with-gmp=/mnt/workspace/aarch64-gmp --with-mpfr=/mnt/workspace/aarch64-mpfr
make -j16 && make install
- 查看生成的文件
zhi@zhi:/mnt/workspace/aarch64-gcc$ ll
total 32
drwxrwxr-x 8 zhi zhi 4096 9月 27 15:09 ./
drwxr-xr-x 12 zhi zhi 4096 9月 27 16:05 ../
drwxrwxr-x 10 zhi zhi 4096 9月 27 14:43 aarch64-linux-gnu/
drwxrwxr-x 2 zhi zhi 4096 9月 27 16:54 bin/
drwxrwxr-x 3 zhi zhi 4096 9月 27 15:09 include/
drwxrwxr-x 3 zhi zhi 4096 9月 27 16:54 lib/
drwxrwxr-x 3 zhi zhi 4096 9月 27 15:09 libexec/
drwxrwxr-x 6 zhi zhi 4096 9月 27 15:09 share/
zhi@zhi:/mnt/workspace/aarch64-gcc$ file bin/gcc
bin/gcc: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=7ad92d97fabaf28d166b855083627118bc32b880, with debug_info, not stripped
- 将5个安装目录下的所有目标文件拷贝到ARM64平台的Linux系统中,合并到/usr目录下
[root@root:/]# ls /usr/
aarch64-linux-gnu include lib64 sbin
bin lib libexec share
- 测试ARM aarch64 GCC
[root@root:/mnt]# ls
helloworld.c
[root@root:/mnt]# gcc helloworld.c -o helloworld
/usr/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: cannot find /mnt/workspace/aarch64-gcc/aarch64-linux-gnu/lib/libc.so.6
/usr/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: cannot find /mnt/workspace/aarch64-gcc/aarch64-linux-gnu/lib/libc_nonshared.a
/usr/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: cannot find /mnt/workspace/aarch64-gcc/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1
collect2: error: ld returned 1 exit status
编译时提示在指定路径下找不到这三个库文件,其实这三个库存在于/usr/aarch64-linux-gnu/lib下,找不打的原因是在交叉编译时指定的prefix目录与系统默认的LIB目录不一致。如果在config时将prefix设置为/usr/aarch64-linux-gnu,会破坏PC的编译环境。
Workaround一下,手动创建这个路径,然后把这三个库copy过去。
[root@root:/mnt]# mkdir -p /mnt/workspace/aarch64-gcc/aarch64-linux-gnu/lib
重新测试
[root@root:/mnt]# gcc helloworld.c -o helloworld
[root@root:/mnt]# ./helloworld
Hello World!