交叉编译工具链的构建

交叉编译工具链的构建

@[toc]   本文档简要介绍了嵌入式开发中软件开发环境建立过程的初始阶段--交叉编译工具链的构建过程。构建交叉编译工具链的过程相当复杂,对于刚入门进行嵌入式系统开发的同学,往往会在这一步花费大量的时间却不得其门而入。幸运的是目前各Linux操作系统均支持交叉编译工具链的下载安装。对于初入门的同学建议直接下载安装已有的交叉编译工具链,学习嵌入式系统程序开发。在嵌入式系统开发的高级阶段,往往会需要根据项目开发的实际需求,构建基于不同编译器、操作系统版本的交叉工具链,满足实际开发需求。

  本文档讲述基于ARM的嵌入式Linux交叉编译工具链的构建过程,文档的大部分内容参考了 《Linux下gcc交叉编译工具链制作实例详细总结》1 。不同之处在于本文档所用的软件版本与参考文档不同。文中对与参考文献部分不同的设置会有重点说明。这些不同点的设置只是本人在的方法,不一定正确,欢迎大家批评指正。

本文档所使用的各软件版本:

  • Linux操作系统 Ubuntu 20.04
  • gcc version 9.4.0 Target:x86_64-gnu-linux
  • binutils-2.40.tar.xz
  • mpc-1.2.1.tar.gz
  • glibc-2.38.tar.xz
  • mpfr-4.1.0.tar.bz2
  • glibc-linuxthreads-2.5.tar.bz2
  • gmp-6.2.1.tar.bz2
  • isl-0.24.tar.bz2
  • gcc-13.1.0.tar.xz
  • linux-5.10.tar.xz

一、什么是交叉编译

   本地编译与交叉编译: 大家平时在学习C语言程序设计时,往往是在PC平台(x86 CPU)上的Windows操作系统下编译出可执行文件,这样的可执行文件同样还是在PC平台(x86 CPU)上的Windows操作系统下运行和调试,这称之为本地编译。简单的讲本地编译就是A平台上编译生成的程序还在A平台上运行。
  有过单片机开发经验的同学,应该有过体验这样的体验:单片机应用程序在PC+Windows平台上编译时用的是专门的编译器,而不是在学习C语言程序设计时的编译器;同时编译生成的程序不能在PC+Windows平台上运行,只能在专用的仿真软件下仿真执行或者下载到单片机上运行。这种在A平台上编译出在B平台上运行的程序,称之为交叉编译。能够实现跨平台编译的一系列工具称之为交叉编译工具链
  目前基于ARM的嵌入式系统开发往往是在PC+Linux平台上开发,编译出能在以ARM+Linux平台上运行的程序,虽然两个系统的操作系统都是Linux但仍属于交叉编译。现在对于一些功能较强的平台,支持本地编译开发已经成为可能,如树莓派平台。
   专业解释: build: gcc的编译平台; host:gcc的运行平台; target:gcc编译产生的应用程序的运行平台。如果build=host=target称之为本地编译(native compiler);如果build=host ≠ \neq =target称之为交叉编译(cross compiler);如果三者均不同称之为Canadian compiler。其他host = target,但是build不同,叫做crossed native;build = target,但是host不同,叫做crossback。
  在裁减和制定linux内核用于嵌入式系统之前,由于一般嵌入式研发系统存储大小有限,通常都要在性能优越的PC上建立一个用于目标机(嵌入式开发板)的交叉编译工具链,用该交叉编译工具链在PC上编译目标机上要运行的程式。交叉编译工具链是由编译器、连接器、解释器和调试器组成的综合研发环境,交叉编译工具链主要由binutils、gcc和glibc 3个部分组成。有时出于减小 libc 库大小的考虑,也能用别的 c 库来代替 glibc,例如 uClibc、dietlibc 和 newlib。

二、交叉工具链的搭建流程

  • 1、下载相关源码
  • 2、安装本地编译依赖包、搭建本地编译环境
  • 3、设置环境变量
  • 4、编译binutils
  • 5、复制Linux内核头文件
  • 6、建立初始编译器
  • 7、编译glibc
  • 8、编译全套编译器
  • 9、编译其他工具
  • 10、创建链接
  • 11、工具链验证

三、构建过程详细讲解

1、下载相关源码

  下载的源码包括kernel、binutils、gcc、glibc等,除了kernel下载地址为https://www.kernel.org 外,其他源码均可在https://ftp.gnu.org/gnu/ 或 https://gcc.gnu.org/pub/ 中找到。
  在构建交叉编译工具链过程中,各工具的版本配合非常重要。在编译构建中的许多错误,大部分都是由于版本不匹配造成的。基本的原则是先确定所使用内核的版本,内核版本确定后内核目录下的 /Documentation/Changes 文件的Kernel compilation部分写明了该版本内核需要依赖的各软件包的版本及下载路径。不是这里面的所有软件包都需要下载源码编译安装,同时该文件中只是给出了最低版本的要求,可适当可提高软件包版本。
  其他依赖包下载,确定gcc版本并下载后解压gcc压缩包。在gcc目录下的contrib/download_prerequisites脚本中注明了gmp、mpfr、mpc、isl软件包版本。可手动下载、解压相关的软件包到gcc源码目录小或运行该脚本下载并解压相关的软件包。高版本gcc一般不再需要cloog;同时建议大家在编译源码时,建立单独的编译目录,这样在编译出错需要重新编译时,不会对源码本身有影响。
  以个人经验而言,所有的软件包都不要用最新的。本次重现过程中曾尝试使用gcc-13.2.0(刚刚发布一个多月),出现了很多无法解决的问题,网上也找不到解决方案。本文档只是对交叉编译工具链过程的描述,在特定版本的编译过程中会有不同的问题,建议大家根据系统提示和参考网上其他人解决问题的方法解决。由于第一次交叉编译环境构建成功后还有许多报错,希望能够解决参考了《How to Build a GCC Cross-Compiler》2 对构建过程进行了调整。

2、安装本地编译依赖包,搭建本地编译环境

dev@Ubuntu:~$ sudo apt-get install xz-utils
dev@Ubuntu:~$ sudo apt-get install m4
dev@Ubuntu:~$ sudo apt-get install libncurses-dev
dev@Ubuntu:~$ sudo apt-get install g++
dev@Ubuntu:~$ sudo apt-get install gawk

3、设置环境变量

dev@Ubuntu:~$ export TARGET=arm-linux-gnueabi
dev@Ubuntu:~$ export PREFIX=/opt/cross/gcc
dev@Ubuntu:~$ export TARGET_PREFIX=$PREFIX/$TARGET
dev@Ubuntu:~$ export PATH=$PATH:$PREFIX/bin

由于我的电脑里已经有一个版本的交叉编译环境,且安装在/usr/bin目录下对PATH变量部分的设置改为:export PATH=$PREFIX/bin:$PATH否则后面有各种报错。

  以上各参数的作用可以通过运行gcc目录下的./configure --help 获得,常用参数的含义如下:

--prefix  编译好的文件重定位安装路径,如make install后相关的可执行文件都安装在prefix指定的路径下
--build – 本地编译机器的平台架构,如x86
--host – 交叉编译工具运行的平台架构,如arm64,如是本机运行一般不指定
--target – 通过该交叉编译工具编译后的可执行代码运行的目标平台

  以上通过export设置的环境变量在系统重启或终端关闭后会失效。可以将其加入到.bashrc文件中,打开终端后会自动执行。

4、编译binutils

  此文档所用软件版本已在前面给出,为了便于描述各源码版本均以x.y代替。

#解压
dev@Ubuntu:~$ tar -xjvf binutils-x.y.tar.gz
#配置
dev@Ubuntu:~$ cd binutilis-x.y
dev@Ubuntu:~/binutilis-x.y$ mkdir build-binutilis
dev@Ubuntu:~/binutilis-x.y$ cd build-binutilis
dev@Ubuntu:~/binutilis-x.y/build-binutilis$ sudo ../configure --prefix=$PREFIX --target=$TARGET --disable-multilib

   –disable-multilib 只希望binutils安装使用特定指令集的程序和库,而不是任何相关指令集,如AArch32、AArch64。在确定所使用平台程使用目标时不建议选择。

  出现如下提示:

checking for isl 0.15 or later... no
required isl version is 0.15 or later

  解决方案:

dev@Ubuntu:~$ tar -vxjf isl-x.y.tar.bz2
dev@Ubuntu:~$ mv isl-x.y binutils-x.y/isl
#重新配置
#编译
dev@Ubuntu:~/binutilis-x.y/build-binutilis$ sudo make
#安装
dev@Ubuntu:~/binutilis-x.y/build-binutilis$ sudo make install

  如果在$PREFIX/bin下会生成部分交叉编译工具,说明已经编译成功,可用于后续的gcc、glic编译:

  • arm-linux-gnueabi-addr2line:将地址转成文件和行号,
    如:arm-linux-gnueabi-addr2line 地址xx -e vmlinux -f
  • arm-linux-gnueabi-ar:产生、修改和解开一个存档文件
  • arm-linux-gnueabi-as:GNU的汇编器
  • arm-linux-gnueabi-gprof:GNU汇编器预编译器
  • arm-linux-gnueabi-ld:GNU的连接器
  • arm-linux-gnueabi-nm:列出目标文件的符号和对应的地址
  • arm-linux-gnueabi-objcopy:将某种格式的目标文件转化成另外格式的目标文件
  • arm-linux-gnueabi-objdump:显示目标文件的信息
  • arm-linux-gnueabi-ranlib:为一个存档文件产生一个索引,并将这个索引存入存档文件中
  • arm-linux-gnueabi-readelf:显示 elf 格式的目标文件的信息
  • arm-linux-gnueabi-size:显示目标文件各个节的大小和目标文件的大小
  • arm-linux-gnueabi-strings:打印出目标文件中可以打印的字符串,有个默认的长度,为4
  • arm-linux-gnueabi-strip:剥掉目标文件的所有的符号信息

5、复制Linux内核头文件

  将Linux内核头文件安装到$TARGET_PREFIX/include下,这将允许用交叉编译工具链生成的程序调用特定内核的系统调用。

#解压内核
dev@Ubuntu:~$ tar -vxJf linux-x.y.tar.xz
#编译内核头文件
dev@Ubuntu:~/linux-x.y$ sudo make ARCH=arm INSTALL_HDR_PATH=$TARGET_PREFIX headers_install
dev@Ubuntu:~/linux-x.y$ ls /opt/cross/gcc/arm-linux-gnueabi/include
  asm  asm-generic  drm  linux  misc  mtd  rdma  scsi  sound  video  xen

6、建立初始编译器(不带glibc支持)

  这一步的目的主要是建立arm-linux-gcc工具,这个gcc没有glibc库的支持,所以只能用于编译内核、BootLoader等不必C库支持的程式,后面创建C库也要用到这个编译器,所以创建他主要是为创建C库做准备,如果只想编译内核和BootLoader,那么安装完这个就能到此结束。也称该步骤生成的gcc为boot-trap gcc

#解压gcc
dev@Ubuntu:~$ tar -vxJf gcc-x.y.tar.xz

#解压mpfr、mpc、gmp、isl 改名并复制至gcc-x.y中
dev@Ubuntu:~$ tar -vxjf mpfr-x.y.tar.bz2
dev@Ubuntu:~$ mv mpfr-x.y gcc-x.y/mpfr
dev@Ubuntu:~$ tar -vxjf mpc-x.y.tar.bz2
dev@Ubuntu:~$ mv mpc-x.y gcc-x.y/mpc
dev@Ubuntu:~$ tar -vxjf gmp-x.y.tar.bz2
dev@Ubuntu:~$ mv gmp-x.y gcc-x.y/gmp
dev@Ubuntu:~$ tar -vxjf isl-x.y.tar.bz2
dev@Ubuntu:~$ mv isl-x.y gcc-x.y/isl
#以上步骤可以通过在gcc-x.y目录下运行./contrib/download_prerequisites脚本代替。

在此处增加一步,解压linux线程库的操作,否则在第8步操作中会报错。

dev@Ubuntu:~$ cd gcc-x.y
dev@Ubuntu:~/gcc-x.y$ tar -vxf glibc-linuxthreads-2.5.tar.bz2
dev@Ubuntu:~/gcc-x.y$ mkdir build-gcc
dev@Ubuntu:~/gcc-x.y$ cd build-gcc
dev@Ubuntu:~/gcc-x.y/build-gcc$ sudo ../configure --prefix=$PREFIX --target=$TARGET --without-headers --enable-languages=c --enable-multilib --enable-threads  --disable-decimal-float --with-newlib --disable-shared --disable-nls --disable-libmudflap --disable-libssp --enable-checking=release
#选项解释
--enable-language=c用来告诉配置脚本,需要产生的编译器支持何种语言,现在只需支持C语言。虽然配置为c,c++也可以的
--enable-threads 是因为threads需要libc的支持,需要在gcc目录下下载并解压glibc-linuxthreads-x.y.tar.bz2。
--disable-decimal-float,需要libc的支持,而我们在初步编译的时候尚未生成libc
--disable-shared,既然是第一次安装ARM交叉编译工具,那么本机的glibc支持的应该是本机的编译工具库,而不是ARM交叉编译工具库。
--disable-libmudflap和--disable-libssp,由于没有arm的glibc,需要禁止两个边界检查使用的库。

  将原作者的--with-headers=$TARGET_PREFIX/include参数根据网上其他文档建议更改为了--without-headers用参考文献[1]中的–with-headers=$TARGET_PREFIX/include,选项会有各种报错!

  在配置过程中出现以下提示,目前不影响编译过程,具体影响未知。

checking for objdir... .libs
configure: WARNING: using in-tree isl, disabling version check
*** This configuration is not supported in the following subdirectories:
     gnattools gotools target-libada target-libphobos target-zlib target-libbacktrace target-libgfortran target-libgo target-libffi target-libgm2 target-libobjc
    (Any other directories should still work fine.)
dev@Ubuntu:~/gcc-x.y/build-gcc$ sudo make all-gcc
dev@Ubuntu:~/gcc-x.y/build-gcc$ sudo make install-gcc

  在编译gcc过程中会出现如下提示:

g++: fatal error: 已杀死 signal terminated program cc1plus
#原因:内存不足导致
#解决方案:关闭其他窗口,重新编译;或增加虚拟机内存,重新编译。
dev@Ubuntu:~/gcc-x.y/build-gcc$ sudo make all-target-libgcc

  出现如下错误提示:根据参考文献[2] 跳过这一步,直接进行第7步操作。

In file included from ../../../libgcc/gthr.h:148,
                 from ../../../libgcc/emutls.c:31:
./gthr-default.h:35:10: fatal error: pthread.h: No such file or directory
   35 | #include <pthread.h>
      |          ^~~~~~~~~~~
compilation terminated.

  第7步执行完毕后进行,在$TARGET_PREFIX/include 目录下出有了pthead.h文件。再进行如下操作,重新进行libgcc的编译与安装,上述的错误提示不再出现。

dev@Ubuntu:~$ unset CC
dev@Ubuntu:~$ unset CFLAGS
dev@Ubuntu:~$ cd gcc-x.y/build-gcc
dev@Ubuntu:~/gcc-x.y/build-gcc$ sudo make all-target-libgcc
dev@Ubuntu:~/gcc-x.y/build-gcc$ sudo make install-target-libgcc

  完成之后,$PREFIX/bin下又多了几个文件:
arm-linux-gnueabi-cpp:GNU的C的预编译器
arm-linux-gnueabi-gcc:GNU的C语言编译器
arm-linux-gnueabi-gcc-x.y:GNU的C语言编译器,其实和arm-linux-gcc是一样的
arm-linux-gnueabi-gcov:gcc 的辅助测试工具,用来分析和优化程序
在/opt/cross/lib/gcc/arm-linux-gnueabi/x.y/中安装了两个静态库libgcc.a 和 libgcc_eh.a。
“共享库libgcc_s.so安装到/opt/cross/arm-linux-gnueabi/lib64。” 这个共享库没找到,与第5步的选项有关。

  为了消除其他隐患删除~/glibc-x.y/build-glibc目录,再编译一次glibc。

7、编译glibc

#解压
dev@Ubuntu:~$ tar -vxJf glibc-x.y.tar.xz
dev@Ubuntu:~$ cd glibc-x.y
dev@Ubuntu:~/glibc-x.y$ mkdir build-glibc
dev@Ubuntu:~/glibc-x.y$ cd build-glibc
dev@Ubuntu:~/glibc-x.y/build-glibc$ export CC=$TARGET-gcc
dev@Ubuntu:~/glibc-x.y/build-glibc$ export CFLAGS="-g -O2 -march=armv6"
#在不确定目标平台CPU的处理器版本时不建议使用-march选项

创建config.cache配置文件

dev@Ubuntu:~/glibc-x.y/build-glibc$ vim config.cache
libc_cv_forced_unwind=yes
libc_cv_c_cleanup=yes
libc_cv_arm_tls=yes
#配置
dev@Ubuntu:~/glibc-x.y/build-glibc$ sudo ../configure --host=$TARGET --target=$TARGET --prefix=$TARGET_PREFIX --enable-add-ons --enable-crypt --disable-profile --cache-file=config.cache --with-binutils=$PREFIX/bin --with-headers=$TARGET_PREFIX/include
#编译
dev@Ubuntu:~/glibc-x.y/build-glibc$ sudo make all
#安装
dev@Ubuntu:~/glibc-x.y/build-glibc$ sudo make install

在$TARGET_PREFIX目录下生成了各种库和其他文件。
在此处相对与参考文献[1],增加了 --enable-crypt 选项,否则第八步的make install过程会报如下错误:

../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:180:10: 致命错误: crypt.h:没有那个文件或目录
  180 | #include <crypt.h>

8、建立全套编译器

dev@Ubuntu:~$ unset CC
dev@Ubuntu:~$ unset CFLAGS
dev@Ubuntu:~$ cd gcc-x.y/build-gcc
dev@Ubuntu:~/gcc-x.y/bulid-gcc$ sudo ../configure --prefix=$PREFIX --target=$TARGET --enable-shared --enable-languages=c,c++ --enable-checking=release
dev@Ubuntu:~/gcc-x.y/build-gcc$ sudo make
dev@Ubuntu:~/gcc-x.y/build-gcc$ sudo make install

  make结束后会出现如下错误,不必理会(具体可以分析Makefile文件,实际已完成了所需的编译工作)。

libtool: link: /opt/cross/gcc/arm-linux-gnueabi/bin/ranlib .libs/libitm.a
libtool: link: ( cd ".libs" && rm -f "libitm.la" && ln -s "../libitm.la" "libitm.la" )
make[4]: 离开目录“/home/dev/gcc-13.1.0/build-gcc/arm-linux-gnueabi/libitm”
make[3]: 离开目录“/home/dev/gcc-13.1.0/build-gcc/arm-linux-gnueabi/libitm”
make[2]: 离开目录“/home/dev/gcc-13.1.0/build-gcc/arm-linux-gnueabi/libitm”
make[1]: 离开目录“/home/dev/gcc-13.1.0/build-gcc”
make: *** [Makefile:1050:all] 错误 2

或者是没有错误的如下提示:

make[5]: 离开目录“/home/dev/gcc-13.1.0/build-gcc/arm-linux-gnueabi/libatomic”
make[4]: 离开目录“/home/dev/gcc-13.1.0/build-gcc/arm-linux-gnueabi/libatomic”
make[3]: 离开目录“/home/dev/gcc-13.1.0/build-gcc/arm-linux-gnueabi/libatomic”
make[2]: 离开目录“/home/dev/gcc-13.1.0/build-gcc/arm-linux-gnueabi/libatomic”
make[1]: 离开目录“/home/dev/gcc-13.1.0/build-gcc”

继续执行make install,提示如下信息。

----------------------------------------------------------------------
Libraries have been installed in:
   /opt/cross/gcc/arm-linux-gnueabi/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
make[4]: 对“install-data-am”无需做任何事。
make[4]: 离开目录“/home/dev/gcc-13.1.0/build/arm-linux-gnueabi/libatomic”
make[3]: 离开目录“/home/dev/gcc-13.1.0/build/arm-linux-gnueabi/libatomic”
make[2]: 离开目录“/home/dev/gcc-13.1.0/build/arm-linux-gnueabi/libatomic”
make[1]: 离开目录“/home/dev/gcc-13.1.0/build”

关键的文件和库均已在相应的目录下。
完成之后,$PREFIX/bin下又多了几个文件:
arm-linux-gnueabi-g++:GNU的c++编译器
arm-linux-gnueabi-c++:等同于arm-linux-gnueabi-g++
标准C库并将其文件安装到 /opt/cross/arm-linux/lib/。静态库名为libc.a,共享库名为 libc.so

9、创建符号链接(不是必须步骤)

dev@Ubuntu:~/gcc-x.y/bulid-gcc$ cd $PREFIX/bin
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-addr2line arm-linux-addr2line
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-ar arm-linux-ar
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-as arm-linux-as
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-c++ arm-linux-c++
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-c++filt arm-linux-c++filt
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-cpp arm-linux-cpp
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-elfedit arm-linux-elfedit
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-g++ arm-linux-g++
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-gcc arm-linux-gcc
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-gcc-4.8.2 arm-linux-gcc-4.8.2
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-gcov arm-linux-gcov
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-gdb arm-linux-gdb
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-gdbtui arm-linux-gdbtui
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-gprof arm-linux-gprof
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-ld arm-linux-ld
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-ld.bfd arm-linux-ld.bfd
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-nm arm-linux-nm
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-objcopy arm-linux-objcopy
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-objdump arm-linux-objdump
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-ranlib arm-linux-ranlib
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-readelf arm-linux-readelf
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-run arm-linux-run
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-size arm-linux-size
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-strings arm-linux-strings
dev@Ubuntu:/opt/cross/gcc/bin$ ln -s arm-linux-gnueabi-strip arm-linux-strip

10、验证交叉编译环境

#将$PREFIX加入路径中
dev@Ubuntu:~/src/mfloat$ export PREFIX=/opt/cross/gcc
dev@Ubuntu:~/src/mfloat$ export PATH=$PREFIX/bin:$PATH
#检测gcc 版本
dev@Ubuntu:~/src/mfloat$ arm-linux-gcc -v
#系统显示信息:
使用内建 specs。
COLLECT_GCC=arm-linux-gcc
COLLECT_LTO_WRAPPER=/opt/cross/gcc/libexec/gcc/arm-linux-gnueabi/13.1.0/lto-wrapper
目标:arm-linux-gnueabi
配置为:../configure --prefix=/opt/cross/gcc --target=arm-linux-gnueabi --enable-shared --enable-languages=c,c++ --enable-checking=release
线程模型:posix
支持的 LTO 压缩算法:zlib
gcc 版本 13.1.0 (GCC) 

#检测用新编译器编译完成可执行文件信息
file mfloat13
mfloat13: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped

好像前面编译过程中的错误对gcc没有影响,目前还没有进行深度测试。

附录:构建过程中部分命令参数

设置环境变量
export TARGET=arm-linux-gnueabi
export PREFIX=/opt/cross/gcc
export TARGET_PREFIX=$PREFIX/$TARGET                                            
export PATH=$PREFIX/bin:$PATH

编译binutils
sudo ../configure --prefix=$PREFIX --target=$TARGET

复制Linux内核头文件
sudo make ARCH=arm INSTALL_HDR_PATH=$TARGET_PREFIX headers_install

建立初始编译器(不带glibc支持)
sudo ../configure --prefix=$PREFIX --target=$TARGET --without-headers --enable-languages=c --enable-multilib --enable-threads  --disable-decimal-float --with-newlib --disable-shared --disable-nls --disable-libmudflap --disable-libssp --enable-checking=release

编译glibc
export CC=$TARGET-gcc
export CFLAGS="-g -O2"

vim config.cache
libc_cv_forced_unwind=yes
libc_cv_c_cleanup=yes
libc_cv_arm_tls=yes

sudo ../configure --host=$TARGET --target=$TARGET --prefix=$TARGET_PREFIX --enable-add-ons --disable-profile --cache-file=config.cache --with-binutils=$PREFIX/bin --with-headers=$TARGET_PREFIX/include
                                                                                

建立全套编译器
sudo ../configure --prefix=$PREFIX --target=$TARGET --enable-shared --enable-languages=c,c++ --enable-checking=release 

  1. Linux下gcc交叉编译工具链制作实例详细总结 https://blog.csdn.net/Luckiers/article/details/124411615 ↩︎

  2. How to Build a GCC Cross-Compiler https://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/ ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值