为嵌入式板卡交叉编译gcc

需要提前准备什么?

  • 交叉编译器(以及相应的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

注意点:

  • CCCXX根据实际情况进行设置
  • --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的
posted @ 2025-01-22 19:59  I加加  阅读(127)  评论(0)    收藏  举报