如何构建一个GCC交叉编译工具链

GCC不仅是一个编译器,它是一个开源工程,可以让你建立各种编译器。一些编译器支持多线程,一些支持共享库,一些支持Multilib(典型的应用是在64位机上运行32位应用程序),这些都取决于在编译 编译器 时的配置。

本文档将说明怎么建立一个交叉编译器。你需要一个已经安装gcc的Unix-like环境。

一、需要的包

Debian系统,首先需要安装一些包

$ sudo apt-get install g++ make gawk

其他的包将使用源代码来编译。在根文件系统的某个地方新建一个文件夹,下载下面的包。本文是2014年写的,你看到时,可能有更新的包可以使用,所以你可以使用更新的包。

$ wget http://ftpmirror.gnu.org/binutils/binutils-2.24.tar.gz

$ wget http://ftpmirror.gnu.org/gcc/gcc-4.9.2/gcc-4.9.2.tar.gz

$ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.17.2.tar.xz

$ wget http://ftpmirror.gnu.org/glibc/glibc-2.20.tar.xz

$ wget http://ftpmirror.gnu.org/mpfr/mpfr-3.1.2.tar.xz

$ wget http://ftpmirror.gnu.org/gmp/gmp-6.0.0a.tar.xz

$ wget http://ftpmirror.gnu.org/mpc/mpc-1.0.2.tar.gz

$ wget ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.12.2.tar.bz2

$ wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz

最开始的四个包:binutils、gcc、Linux kernel和glibc是主要要用的包。后面三个mpfr、gmp、mpc你可以使用系统自带的package manager安装,但是可能比较旧。最后两个包ISL和CLooG是可选的,它们支持一些优化。

二、它们是怎么有机结合在一起的呢?

当我们完成时,我们会构建如下的程序和库。首先,构建左边的工具,然后使用这些工具来构建右边的程序和库。我们将不构建目标系统的Linux kernel,但是我们需要kernel header来构建目标系统标准C库。

左边的编译器将调用汇编器和链接器。其他的包MPFR、GMP和MPC将连接到编译器中。

右边图中的a.out,运行在目标OS上,使用交叉编译器,连接目标系统标准C库和C++库。C++标准库调用标准C库,C库直接调用Linux kernel。

注意,除了使用glibc外,还可以使用其他替代的C库实现,比如Newlibc,uclibc等,其他替代的C库用在嵌入式中较多,比glibc库要小,功能没有glibc全面。

三、构建步骤

解压所有的包。

$ for f in *.tar*; do tar xf $f; done

创建一些其他目录的符号连接,这5个包依附于gcc,如果存在符号连接,gcc脚本将自动build这些包。

$ cd gcc-4.9.2

$ ln -s ../mpfr-3.1.2 mpfr

$ ln -s ../gmp-6.0.0 gmp

$ ln -s ../mpc-1.0.2 mpc

$ ln -s ../isl-0.12.2 isl

$ ln -s ../cloog-0.18.1 cloog

$ cd ..

选择一个安装路径,确保有写的权限。下面步骤中,我将安装新的工具链到/opt/cross

$ sudo mkdir -p /opt/cross

$ sudo chown jeff /opt/cross

整个构建过程中,确保安装的bin子目录在你的PATH环境变量中。后续你可以从PATH中移除该目录,但是大部分构建步骤将会默认通过PATH来查找aarch64-linux-gcc和其他host工具。

$ export PATH=/opt/cross/bin:$PATH

注意/opt/cross/aarch64-linux/目录下的文件。该目录被认为是虚拟的aarch64 linux目标系统的根目录。理论上,可以使用里面所有的头文件和库。

1. Binutils

构建binutils、安装交叉汇编器、链接器和其他工具的步骤:

$ mkdir build-binutils

$ cd build-binutils

$ ../binutils-2.24/configure --prefix=/opt/cross --target=aarch64-linux --disable-multilib

$ make -j4

$ make install

$ cd ..

我们制定aarch64-linux作为目标系统类型,binutils的配置脚本将识别到它与正在进行编译的主机系统不一样,配置一个交叉汇编器和交叉链接器。这些工具将安装到/opt/cross/bin,名字以arm-linux-开头。

--disable-multilib意味着我们只希望我们的程序和库使用aarch64指令集,而不使用aarch32的指令集。

2. Linux Kernel Headers

将Linux kernel 头文件安装到/opt/cross/aarch64-linux/include, 使用新工具链构建的程序会调用这些目标环境中的aarch64 kernel。

$ cd linux-3.17.2

$ make ARCH=arm64 INSTALL_HDR_PATH=/opt/cross/aarch64-linux headers_install

$ cd ..

我们也可以在构建binutils之前做这件事。

尽管第4步,configure脚本期望linux kernel header依据安装,但是实际上在步骤6之前,当我们编译标准C库时,linux kernel headers不会被用到。

因为Linux kernel和其他开源工程不一样,它有一个不同的方式来识别目标CPU架构: ARCH=arm

剩下的步骤涉及构建GCC和Glibc。这里有个道道,就是部分gcc需要部分glibc被构建,而部分glibc又需要gcc被构建。我们不能一步搞定这些编译,而是要分成几步。我们要这几个包之间来往几次。

3. C/C++ Compilers

该步将构建gcc的C和C++编译器,并安装到/opt/cross/bin,目前还不能引用这些编译器来构建库。

$ mkdir -p build-gcc

$ cd build-gcc

$ ../gcc-4.9.2/configure --prefix=/opt/cross --target=aarch64-linux --enable-languages=c,c++ --disable-multilib

$ make -j4 all-gcc

$ make install-gcc

$ cd ..

因为我们指定了--target=aarch64-linux,构建脚本会依据aarch64-linux-前缀查找第一步安装的binutils工具。同样,C/C++编译器的名字也会带上aarch64-linux-前缀。

--enable-languages=c,c++避免了在GCC套件中出现其他的编译器,比如Fortran、Java等。

4. Standard C Library Headers and Startup Files

安装标准C库头文件到/opt/cross/aarch64-linux/include。我们会使用第三步构建的C编译器来编译库的startup files并安装到/opt/cross/aarch64-linux/lib。最后我们创建几个傀儡文件,libc.so和stubs.h,在第5步会用到,但是第6步会替换为真的。

$ mkdir -p build-glibc

$ cd build-glibc

$ ../glibc-2.20/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 -j4 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=/opt/cross/aarch64-linux告诉configure脚本它要安装头文件和库到这里。注意这个和普通的--prefix。

Glibc的configure需要我们制定所有的--build,--host和--target系统类型。

$MACHTYPE是一个预定义的环境变量,表示正在运行build脚本的机器。--build=$MACHTYPE是必须的,因为在第六步中,该build脚本将编译一些额外的工具,这些工具是build进程的一部分。

--host,在glibc的configure中,--host和--target选项都指glibc库最终运行的系统。

我们手动安装C库startup文件,ctr1.o ctri.o和ctrn.o。其他的方法好像都有副作用。

5. Compiler Support Library

使用第三步的交叉编译器构建compiler support library,编译器支持的库包含一些C++异常处理样板代码等等。该库依赖第四步安装的startup file。第六步需要该库。不像其他的指导手册,我们不需要重新运行gcc configure。只需要在相同配置下构建额外的target即可。

$ cd build-gcc

$ make -j4 all-target-libgcc

$ make install-target-libgcc

$ cd ..

两个静态库,libgcc.a和libgcc_eh.a,安装到/opt/cross/lib/gcc/aarch64-linux/4.9.2.

共享库,lingcc_s.so,安装到/opt/cross/aarch64-linux/lib64.

6. Standard C Library

这步完成glibc的安装。安装标准C库到/opt/cross/aarch64-linux/lib中。静态库名字为libc.a,动态库为libc.so

$ cd build-glibc

$ make -j4

$ make install

$ cd ..

7. Standard C++ Library

最后完成gcc的安装,构建标准C++库,安装到/opt/cross/aarch64-linux/lib64。它依赖第六步的C库。目标静态库名字为libstdc++.a,动态库为libstdc++.so。

$ cd build-gcc

$ make -j4

$ make install

$ cd ..

How to Build a GCC Cross-Compiler

http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/

构建gcc交叉编译工具链相关推荐

  1. Linux下gcc交叉编译工具链制作实例详细总结(附下载地址)

    一.简介 本文主要讲解gcc交叉编译工具链搭建的全过程,以本人实际的操作去讲述整个工具链的搭建,希望对大家有所帮助. 二.工具链的搭建流程 1.下载相关源码:包括binutils.kernel.gcc ...

  2. 交叉编译openwrt php,构建 openwrt 交叉编译工具链

    1 首先.make menuconfig 的时候选上工具链: 也就是 Package the OpenWrt-based Toolchain Target System (Ralink RT288x/ ...

  3. Linaro GCC 交叉编译工具链 国内源下载列表 (持续更新)

    gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf.tar.xz 链接:https://pan.baidu.com/s/1-DCIVVs6QTGv5tY ...

  4. linux centos7 使用 crosstool-ng 构建 交叉编译 工具链 即构建各cpu架构平台的gcc编译器

    简介 crosstool-ng,全称是crosstool Next Generation,即下一代crosstool.crosstool是个交叉编译器的制作工具,但是做的不够好,于是有人(Yann E ...

  5. arm-buildroot-linux-,buildroot构建交叉编译工具链,根文件系统

    支持多种处理器,arch,avr32,mips,x86等等,在arch/目录可查看. buildroot可使用make menuconfig进行配置,选择需要编译到目标文件系统的包,相关的配置文件在c ...

  6. Mastering Embedded Linux Programming 学习 (一)嵌入式交叉编译工具链的构建,基于crosstool-NG

    Mastering Embedded Linux Programming 学习 (一) 一.ubuntu 软件包下载 sudo apt install autoconf automake bison ...

  7. 采用arm-none-eabi-gcc交叉编译工具链 以及使用xmake构建 STM32 RT-Thread nano工程 笔记

    xmake构建工程 由于多余的文件目录太多,所以删除了bsp目录 xmake.lua构建文件编写 -- 设置工程名 set_project("stm32_rtt_nano_demo" ...

  8. linux环境变量、交叉编译工具链gcc

    ** linux环境变量 ** 1.linux环境变量 Linux 是一个多用户操作系统,每个用户都有自己专有的运行环境.用户所使用的环境由一系列变量所定义,这些变量被称为环境变量.系统环境变量通常都 ...

  9. Crosstool-ng制作交叉编译工具链

    Crosstool-ng制作交叉编译工具链 交叉编译器可以用现成的,比如CodeSourcery制作的交叉编译器,也可以自己制作,一般是用kernel+gcc+glibc+binutils的源码包来编 ...

最新文章

  1. python中将字符变为大写_Python笔记(一)
  2. Java文件流应用:剪切文件
  3. VMware虚拟机磁盘操作占用过高问题(转:http://blog.csdn.net/New_When/article/details/73731149)
  4. Cisco ftp linux 权限,在Cisco设备上利用FTP传IOS文件
  5. 三星Galaxy Note 20系列将首发Exynos 992:性能超骁龙865
  6. kotlin项目开发基础之gradle初识
  7. Visual Studio-运行库的设置
  8. jQuery页面滚动右侧浮动导航切换
  9. WindowsServer2003中Vmware虚拟机与物理机配置FTP文件共享
  10. java jtable 单元格合并_java 表格JTable中怎么样合并单元格
  11. javascript中隐藏显示的样式表属性
  12. RISC-V_GD32VF103-开发环境搭建和使用
  13. Windows10 隐藏更新小工具
  14. Java-String类常用方法汇总
  15. 劳务派遣人员管理办法范文
  16. 每日一算法:杨辉三角形
  17. 高效能人士的七个习惯--由内而外全面造就自己
  18. 剑指 Offer 65. 不用加减乘除做加法(位运算、递归、迭代)
  19. 搜索衬线字体和无衬线字体的区别
  20. 世上没有免费午餐:谈谈网络广告与节操

热门文章

  1. 【转】好资料,非常棒!!!
  2. 《阅读的力量》书中的精髓:读书对一个人塑造自我、锤炼自我和扩展自我过程中的影响,让你真真切切的感受到阅读带来的力量。
  3. 坐式养生八段锦口诀及练法图解
  4. 微信读书怎么导入本地电子书
  5. 【爬虫搜索引擎工程师,360buy京东商城(集团总部技术系统)】前程无忧官方招聘网站...
  6. 震惊!某程序员吐槽零基础自学编程很难,真的是这样吗?
  7. 成就亿万富翁的10条规则
  8. db db2_monitorTool IBM Rational Performace Tester
  9. HEVC之tiles、slice、slice segment、CU、PU、TU分析
  10. 华尔街见闻下操作mysql_GitHub - boshengw-shzq/reainl: 华尔街见闻和新浪财经新闻采集...