需要提前准备什么?
- 交叉编译器(以及相应的sysroot,可以通过xxx-gcc --print-sysroot来查看路径)
- gcc源码,这里我用的是7.5.0版本的,也可以尝试别的 下载地址
- binutils源码,光有gcc是不行的,还需要as才可以完成整个编译过程 下载地址
编译器路径
其实一般情况下我是比较建议直接使用交叉编译器的绝对路径的,但是在这个编译过程中出现过问题,因此将其加入环境变量
export PATH=/path/to/your/cross/compiler/bin/:$PATH
这里我用的是gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu,你的可能并不一样,请根据实际情况来修改
这里可以简单测试
which aarch64-linux-gnu-gcc # 确认该命令是否来自你所期望的路径
aarch64-linux-gnu-gcc -v # 确认命令执行正常
编译流程
目录组织
.
├── archive # 源码包
│ ├── binutils-2.35.tar.xz
│ └── gcc-7.5.0.tar.gz
├── build # 编译中间文件,在这里执行configure
│ ├── binutils
│ └── gcc
├── output # 最终输出路径,即prefix指向的位置
│ ├── binutils
│ ├── libc
│ └── gcc
└── src # 解压得到的源码
├── binutils-2.35
└── gcc-7.5.0
交叉编译gcc
下载依赖
进入gcc源码目录(src/gcc-7.5.0),执行
contrib/download_prerequisites
需要看到
gmp-6.1.0.tar.bz2: OK
mpfr-3.1.4.tar.bz2: OK
mpc-1.0.3.tar.gz: OK
isl-0.16.1.tar.bz2: OK
All prerequisites downloaded successfully.
才算成功
编译
来到build目录(build/gcc-7.5.0),执行
CC=aarch64-linux-gnu-gcc \
CXX=aarch64-linux-gnu-g++ \
../../src/gcc-7.5.0/configure \
--prefix=/your/path/to/output/gcc-7.5.0 \
--target=aarch64-linux-gnu \
--host=aarch64-linux-gnu \
--build=x86_64-unknown-linux-gnu \
--with-sysroot=/opt/build-env/libc \
--with-build-sysroot=/your/path/to/cross/compiler/sysroot \
--enable-languages=c,c++ \
--disable-multilib \
--enable-shared \
--disable-libmudflap \
--enable-threads=posix \
--enable-nls \
--with-gnu-as \
--with-gnu-ld \
--disable-libstdcxx-pch \
--enable-c99 \
--enable-clocale=gnu \
--enable-libstdcxx-debug \
--enable-long-long \
--enable-gnu-indirect-function
注意点:
CC
和CXX
根据实际情况进行设置--host
/--target
/--build
根据实际情况进行设置--with-sysroot
是指将来在板子上使用gcc时,它默认的查找sysroot的路径(注意,这个路径是板子上的路径,而且必须是绝对路径),如果不设置,可能会从/usr/include之类的地方查,如果你的板子并没有提供这些头文件,那么这个选项要仔细设置--with-build-sysroot
为编译时交叉编译器使用的sysroot,如果没有设置--with-sysroot
,那么这个会使用默认的路径,不设置也可以;但如果设置了--with-sysroot
,交叉编译器使用的sysroot也会被设置,因此这种情况下就需要设置本选项来指定,一般来说直接指定为前述--print-sysroot
输出的路径即可
完成后,执行
make -j8
根据你自己的机器配置来决定到底是j几,编译之后执行
make install
完成gcc的交叉编译,此时就可以在output/gcc-7.5.0中找到编好的东西了
交叉编译binutils
这个比较简单
CC=aarch64-linux-gnu-gcc \
CXX=aarch64-linux-gnu-g++ \
../../src/binutils-2.35/configure \
--prefix=/your/path/to/output/binutils-2.35 \
--target=aarch64-linux-gnu \
--host=aarch64-linux-gnu \
--build=x86_64-unknown-linux-gnu \
--enable-ld=yes
make -j8
make install
sysroot
如果你的板子没有提供头文件,那么你需要把先前--print-sysroot
指定路径下的所有内容都放到编译gcc时--with-sysroot
指定的路径下
使用
将前述3个项目内容都弄到板子上,这里建议打包之后再传,不然可能会导致权限、文件类型出现异常,尤其是经过Windows的情况
在板子上,你可以
- 把前述内容放到usr下面,你可以注意一下目录名都是对得上的,这样不用配环境变量就可以在板子上直接使用
- 在使用前配置gcc和binutils的环境变量,PATH指向两个bin目录,也是OK的