第 3 章 交叉编译器简介

目录

3.1. 交叉编译器的名字的命名规则
3.1.1. 交叉编译器名字举例
3.1.2. crosstool-ng中交叉编译前缀的命名规则
3.1.2.1. 交叉编译器名字中的arch部分
3.1.2.1.1. crosstool-ng中arch的值
3.1.2.2. 交叉编译器名字中的vendor部分
3.1.2.2.1. crosstool-ng中vendor的值
3.1.2.3. 交叉编译器名字中的kernel部分
3.1.2.3.1. crosstool-ng中kernel的值
3.1.2.4. 交叉编译器名字中的system部分
3.1.2.4.1. system中的gnu
3.1.2.4.1.1. crosstool-ng中system为gnu的情况
3.1.2.4.2. system中的eabi
3.1.2.4.2.1. crosstool-ng中system为eabi的情况
3.1.2.4.3. system中的uclibc
3.1.2.4.3.1. crosstool-ng中system为uclibc的情况
3.2. 如何得到交叉编译器
3.2.1. 拿来主义:直接去下载和使用别人已经编译好的交叉编译器
3.2.2. 自己动手,丰衣足食:自己去编译出来一套自己想要的交叉编译器
3.2.2.1. 白手起家从头开始制作交叉编译器
3.2.2.2. 借助别人的工具去制作交叉编译器
3.3. 各种制作交叉编译器的工具
3.3.1. crosstool-NG
3.3.2. Buildroot
3.3.3. crosstool
3.3.4. Embedded Linux Development Kit (ELDK)
3.3.5. OpenEmbedded的BitBake
3.3.6. Crossdev
3.3.7. OSELAS.Toolchain()
3.4. 使用已有的交叉编译器和自己手动编译交叉编译器之间的对比
3.4.1. 使用已有交叉编译器的优点
3.4.1.1. 已有的交叉工具链的下载
3.4.1.1.1. ELDK的下载
3.4.2. 使用已有交叉编译器的缺点
3.4.3. 自己手动编译交叉编译器的优点
3.4.4. 自己手动编译交叉编译器的缺点

摘要

TODO:

相关旧帖:嵌入式开发之交叉编译器

3.1. 交叉编译器的名字的命名规则

在折腾嵌入式开发,用到交叉编译器的时候,常常会看到这样的名字:

arm-xscale-linux-gnueabi-gcc

arm-liunx-gnu-gcc

等等

其中,对应的交叉编译器的前缀为:

arm-xscale-linux-gnueabi-

arm-liunx-gnu-

而关于这些名字,我之前也是没注意其具体含义,或者说对于其含义也是很模糊的感觉,不是很清楚这些名字是从何而来的。

后来,经过折腾了crosstool-ng后,基本上明白了这些名字,是如何生成的。

其中,貌似此交叉编译器命名的规则,应该是通用的,至少记得是Buildroot中,好像也是这样命名的。

下面,就以crosstool-ng为例,参考我之前折腾crosstool-ng期间:

【整理】crosstool中如何设置xscale的Tuple’s vendor string(CT_TARGET_VENDOR)

所了解到的内容,来解释解释,这些名字的含义。

3.1.1. 交叉编译器名字举例

此处,以编译crosstool-ng中:

【记录】重试使用最新版本1.18.0的crosstool-ng去配置和编译xscale的交叉编译器

通过ct-ng list-samples中得到的输出为例,

当做交叉编译器的名字的例子,供参考:


CLi@PC-CLI-1 ~/develop/crosstool-ng/crosstool-ng-1.18.0_build
$ ct-ng list-samples
Status  Sample name
[G.X]   alphaev56-unknown-linux-gnu
[G.X]   alphaev67-unknown-linux-gnu
[G.X]   arm-bare_newlib_cortex_m3_nommu-eabi
[G.X]   arm-cortex_a15-linux-gnueabi
[G..]   arm-cortex_a8-linux-gnueabi
[G..]   arm-davinci-linux-gnueabi
[G..]   armeb-unknown-eabi
[G.X]   armeb-unknown-linux-gnueabi
[G.X]   armeb-unknown-linux-uclibcgnueabi
[G..]   arm-unknown-eabi
[G..]   arm-unknown-linux-gnueabi
[G.X]   arm-unknown-linux-uclibcgnueabi
[G.X]   armv6-rpi-linux-gnueabi
[G.X]   avr32-unknown-none
[G..]   bfin-unknown-linux-uclibc
[G..]   i586-geode-linux-uclibc
[G.X]   i586-mingw32msvc,i686-none-linux-gnu
[G.X]   i686-nptl-linux-gnu
[G.X]   i686-unknown-mingw32
[G.X]   m68k-unknown-elf
[G.X]   m68k-unknown-uclinux-uclibc
[G.X]   mips64el-n32-linux-uclibc
[G.X]   mips64el-n64-linux-uclibc
[G.X]   mips-ar2315-linux-gnu
[G..]   mipsel-sde-elf
[G..]   mipsel-unknown-linux-gnu
[G.X]   mips-malta-linux-gnu
[G..]   mips-unknown-elf
[G.X]   mips-unknown-linux-uclibc
[G..]   powerpc-405-linux-gnu
[G.X]   powerpc64-unknown-linux-gnu
[G..]   powerpc-860-linux-gnu
[G.X]   powerpc-e300c3-linux-gnu
[G.X]   powerpc-e500v2-linux-gnuspe
[G..]   powerpc-unknown_nofpu-linux-gnu
[G..]   powerpc-unknown-linux-gnu
[G..]   powerpc-unknown-linux-uclibc
[G.X]   s390-ibm-linux-gnu
[G.X]   s390x-ibm-linux-gnu
[G..]   sh4-unknown-linux-gnu
[G..]   x86_64-unknown-linux-gnu
[G..]   x86_64-unknown-linux-uclibc
[G.X]   x86_64-unknown-mingw32
 L (Local)       : sample was found in current directory
 G (Global)      : sample was installed with crosstool-NG
 X (EXPERIMENTAL): sample may use EXPERIMENTAL features
 B (BROKEN)      : sample is currently broken

        

3.1.2. crosstool-ng中交叉编译前缀的命名规则

crosstool-ng中,交叉编译器的(前缀)的名字的命名规则是:

arch-vendor-kernel-system

对应分别是:

3.1.2.1. 交叉编译器名字中的arch部分

arch,即系统架构

表示交叉编译器,是用于哪个目标系统架构中,用于那个平台中的

即,用此交叉编译器编译出来的程序,是运行在哪种CPU上面的

arch的值,常见的有很多种,比如arm,x86,mips等等。

例 3.1. 举例:交叉编译器中的arch的值

arm-cortex_a8-linux-gnueabi中的arm

mips-ar2315-linux-gnu中的mips

powerpc-e500v2-linux-gnuspe中的powerpc

x86_64-unknown-mingw32中的x86_64


3.1.2.1.1. crosstool-ng中arch的值

crosstool-ng中,和arch对应的值,应该就是"Target options"中的"Target Architecture"的值了。

比如常见的,配置为arm的话,就是:


Target options
  Target Architecture (arm)  --->

                

对应的配置参数是:ARCH_arm

3.1.2.2. 交叉编译器名字中的vendor部分

vendor,即生成厂家,提供商

表示谁提供的,即谁制作出来这个交叉编译器的。

vendor的值,貌似是可以自己随便填写的。

其他常见写法,还有写成编译交叉编译器的作者的自己的名字的

比如,我叫crifan,那么就可以写成crifan,然后生成的交叉编译器,就是xxx-crifan-xxx-xxx了。

更加通用的做法,好像是:

把vendor写成,体系架构的值,比如我之前针对xscale的去配置crosstool-ng的时候,就写了个xscale。

或者写成CPU的厂家的名字,或者是开发板的名字等等。

例 3.2. 举例:交叉编译器中的vendor的值

  • arm-cortex_a8-linux-gnueabi中的cortex_a8,就属于CPU的名字
  • mips-ar2315-linux-gnu中的ar2315
  • powerpc-e500v2-linux-gnuspe中的e500v2,也是CPU的内核名
  • arm-buildroot-linux-uclibcgnueabi中的buildroot,是之前折腾Buildroot时,看到的,即Buildroot把自己视为当前自己制作出来的交叉编译器的vendor。

3.1.2.2.1. crosstool-ng中vendor的值

crosstool-ng中,和vendor对应的值,应该就是"Toolchain options"中的"Tuple's vendor string"的值了。

比如我之前配置为xscale的话,就是:


Toolchain options
  (xscale) Tuple's vendor string

                

对应的配置参数是:CT_TARGET_VENDOR

对应的help的解释是:


  ┌────────────────────────────────── Tuple's vendor string ──────────────────────────────────┐
  │ CT_TARGET_VENDOR:                                                                         │
  │                                                                                           │
  │ Vendor part of the target tuple.                                                          │
  │                                                                                           │
  │ A tuple is of the form arch-vendor-kernel-system.                                         │
  │ You can set the second part, vendor, to whatever you see fit.                             │
  │ Use a single word, or use underscores "_" to separate words.                              │
  │ Use neither dash nor space, as it breaks things.                                          │
  │                                                                                           │
  │ Keep the default (unknown) if you don't know better.                                      │
  │                                                                                           │
  │ Symbol: TARGET_VENDOR [=xscale]                                                           │
  │ Type  : string                                                                            │
  │ Prompt: Tuple's vendor string                                                             │
  │   Defined at config/toolchain.in:99                                                       │
  │   Location:                                                                               │
  │     -> Toolchain options                                                                  │

                

3.1.2.3. 交叉编译器名字中的kernel部分

kernel,直译为,内核

其实指的是,你用此交叉编译器,编译出来的程序,所运行的目标系统

即,此交叉编译器,编译出来的程序,在什么系统中,什么环境中,运行。

而对应的环境或系统,主要有两种:

  • Linux

    表示:有OS(此处主要指的是Linux)操作系统的环境

    比如,我用交叉编译器,编译一个helloworld程序,然后下载到嵌入式开发中的嵌入式Linux中运行,

    就属于,用此交叉编译器,编译出来的程序,是要运行于,带OS,即嵌入式Linux系统,环境中的

    此处,简称为,有OS的目标系统:Linux

  • bare-metal

    bare-metal,直译为:裸金属

    表示:无(此处主要指的是Linux)操作系统的环境,

    比如,用此交叉编译器,去编译一个Uboot,或者是其他一个小程序,是运行在,无嵌入式Linux的时候,单独运行的一个程序。

    比如,你购买的嵌入式系统开发版,常常附带一些小程序,比如点亮LED,跑马灯等程序,就是这种,运行在无OS的环境的

    此处,简称为:无OS系统的:bare-metal

关于,运行在有OS的Linux下,和,无OS的bare-metal,到底有何区别

目前,还没有完全搞懂。

但是,之前遇到一个实际的例子:

之前用比较新的一个交叉编译器去编译比较老的uboot时,会出现一个错误:

【已解决】uboot交叉编译出错:gcc/config/arm/lib1funcs.asm:1266: undefined reference to `raise’

其就是和这个kernel有关:

编译的uboot,目标运行平台,不是Linux,而是裸的开发板,即Linux还没有运行呢,Uboot去运行,去初始化开发板的时候

详细的情况,见该贴中的解释。

例 3.3. 举例:交叉编译器中的kernel的值

  • arm-bare_newlib_cortex_m3_nommu-eabi中的bare_newlib_cortex_m3_nommu,此处的bare,应该就是指的是bare-metal,用于运行在无OS的环境下
  • powerpc-e300c3-linux-gnu中的linux
  • m68k-unknown-uclinux-uclibc中的uclinux,就是指的是编译出来的程序,是运行于没有MMU的uclinux下

3.1.2.3.1. crosstool-ng中kernel的值

crosstool-ng中,和kernel对应的值,应该就是"Operating System"中的"Target OS"的值了。

比如我之前配置为Linux的话,就是:


Operating System
  Target OS (linux)  --->

                

对应的配置参数是:GEN_CHOICE_KERNEL中的CT_KERNEL_linux

对应的help的解释是:


  ┌────────────────────────────────────────── linux ──────────────────────────────────────────┐
  │ CT_KERNEL_linux:                                                                          │
  │                                                                                           │
  │ Build a toolchain targeting systems running Linux as a kernel.                            │
  │                                                                                           │
  │ Symbol: KERNEL_linux [=y]                                                                 │
  │ Type  : boolean                                                                           │
  │ Prompt: linux                                                                             │
  │   Defined at config.gen/kernel.in:8                                                       │
  │   Depends on: GEN_CHOICE_KERNEL [=y] && KERNEL_linux_AVAILABLE [=y]                       │
  │   Location:                                                                               │
  │     -> Operating System                                                                   │
  │       -> Target OS (GEN_CHOICE_KERNEL [=y])                                               │
  │   Selects: KERNEL_SUPPORTS_SHARED_LIBS [=y]                                               │


                

3.1.2.4. 交叉编译器名字中的system部分

system,直译为,系统

其实主要表示的,交叉编译器所选择的库函数和目标系统

最常见的一些值有,gnu,gnueabi,uclibcgnueabi等等。

其中,此处有几方面的值,表示了几方面的含义:

3.1.2.4.1. system中的gnu

好像都是gnu

不是很明白,貌似是:

gnu == gnu libc == glibc

即,gnu,就是表示用的是glibc的意思。

3.1.2.4.1.1. crosstool-ng中system为gnu的情况

crosstool-ng中,和system中gnu对应的值,应该就是"C-library"中的"C library"的值设置为"glibc"了。


C-library
  C library (glibc)  ---> 

                    

对应的配置参数是:CT_LIBC_glibc

对应的help的解释是:


  ┌────────────────────────────────────────── glibc ──────────────────────────────────────────┐
  │ CT_LIBC_glibc:                                                                            │
  │                                                                                           │
  │ The de-facto standard for Linux distributions.                                            │
  │ Feature-rich, but large...  Most usefull for desktop-like systems.                        │
  │                                                                                           │
  │ Symbol: LIBC_glibc [=y]                                                                   │
  │ Type  : boolean                                                                           │
  │ Prompt: glibc                                                                             │
  │   Defined at config.gen/libc.in:53                                                        │
  │   Depends on: GEN_CHOICE_LIBC [=y] && LIBC_glibc_AVAILABLE [=y] && !WINDOWS [=n] && !\    │
  │ BARE_METAL [=n] && ARCH_USE_MMU [=y]                                                      │
  │   Location:                                                                               │
  │     -> C-library                                                                          │
  │       -> C library (GEN_CHOICE_LIBC [=y])                                                 │
  │   Selects: LIBC_SUPPORT_NPTL [=y] && CC_CORE_PASSES_NEEDED [=y]                           │

                    

3.1.2.4.2. system中的eabi

与此相对应的,之前早期的是oabi

eabi和oabi的对比,详见:

[整理]EABI和OABI

3.1.2.4.2.1. crosstool-ng中system为eabi的情况

crosstool-ng中,和system中eabi对应的值,应该就是"Target options"中的"-*- Use EABI"的值了。


Target options
  -*- Use EABI

                    

注意:此处是选择的ARM,EABI在此处,已经是默认,无法修改的值,只能是EABI了。

好像是因为,Linux内核等其他选择导致的,此处无法更改EABI。

对应的配置参数是:CT_ARCH_ARM_EABI

对应的help的解释是:


  ┌──────────────────────────────────────── Use EABI ─────────────────────────────────────────┐
  │ CT_ARCH_ARM_EABI:                                                                         │
  │                                                                                           │
  │ Set up the toolchain so that it generates EABI-compliant binaries.                        │
  │                                                                                           │
  │ If you say 'n' here, then the toolchain will generate OABI binaries.                      │
  │ OABI has long been deprecated, and is now considered legacy.                              │
  │                                                                                           │
  │ Symbol: ARCH_ARM_EABI [=y]                                                                │
  │ Type  : boolean                                                                           │
  │ Prompt: Use EABI                                                                          │
  │   Defined at config/arch/arm.in.2:54                                                      │
  │   Depends on: ARCH_arm [=y]                                                               │
  │   Location:                                                                               │
  │     -> Target options                                                                     │
  │   Selected by: ARCH_ARM_EABI_FORCE [=y] && ARCH_arm [=y]                                  │

                    
3.1.2.4.3. system中的uclibc

uclibc,是c库中的一种

crosstool-ng中,目前支持三种:glibc,eglibc,uclibc

关于三种的关系,详见:

【整理】uclibc,eglibc,glibc之间的区别和联系

3.1.2.4.3.1. crosstool-ng中system为uclibc的情况

crosstool-ng中,和system中uclibc对应的值,应该就是"C-library"中的"C library"的值设置为"uClibc"了。


C-library
  C library (uClibc)  --->

                    

对应的配置参数是:CT_LIBC_uClibc

对应的help的解释是:


  ┌───────────────────────────────────────── uClibc ──────────────────────────────────────────┐
  │ CT_LIBC_uClibc:                                                                           │
  │                                                                                           │
  │ The de-facto standard for embeded linux systems.                                          │
  │                                                                                           │
  │ Highly configurable, thus as feature-rich as you                                          │
  │ need, without compromising for size.                                                      │
  │                                                                                           │
  │ Symbol: LIBC_uClibc [=y]                                                                  │
  │ Type  : boolean                                                                           │
  │ Prompt: uClibc                                                                            │
  │   Defined at config.gen/libc.in:24                                                        │
  │   Depends on: GEN_CHOICE_LIBC [=y] && LIBC_uClibc_AVAILABLE [=y] && !WINDOWS [=n] && !\   │
  │ BARE_METAL [=n]                                                                           │
  │   Location:                                                                               │
  │     -> C-library                                                                          │
  │       -> C library (GEN_CHOICE_LIBC [=y])                                                 │
  │   Selects: LIBC_SUPPORT_LINUXTHREADS [=y] && LIBC_SUPPORT_THREADS_NONE [=y] && \          │
  │ CC_CORE_PASSES_NEEDED [=y]                                                                │

                    

所以,针对上述,gnu,eabi,uclibc等几个选项,对应的常见的一些组合的含义是:

  • gnu

    等价于:glibc+oabi

  • gnueabi

    等价于:glibc+eabi

  • uclibc

    等价于:uclibc+oabi(待确认)

例 3.4. 举例:交叉编译器中的system的值

  • arm-cortex_a8-linux-gnueabi中的gnueabi,即glibc+eabi
  • mips-ar2315-linux-gnu中的gnu,即glibc+oabi
  • powerpc-e500v2-linux-gnuspe中的gnuspe,没搞懂啥意思。。
  • x86_64-unknown-mingw32中的mingw32,用的是Windows下的mingw32的库