交叉编译(超详细)

1 为什么要交叉编译

在嵌入式开发过程中有宿主机目标机的角色之分:宿主机是执行编译链接嵌入式软件的计算机;目标机是运行嵌入式软件的硬件平台。

clip_image002

  1. 目标平台不具备编译环境:有时候,目标平台(例如嵌入式设备或移动设备)可能没有足够的计算资源或存储空间来支持源代码的本地编译。在这种情况下,使用一台性能更强大的主机进行交叉编译可以更高效地生成目标平台上可执行的代码。

  2. 平台兼容性:不同的体系结构和操作系统具有不同的指令集和库,因此无法直接在一个平台上运行另一个平台的代码。通过交叉编译,可以将源代码编译为适用于目标平台的二进制文件,以确保代码在目标平台上正确运行。

  3. 开发效率:在软件开发过程中,通常会使用高性能的开发主机来编写、调试和测试代码。然而,最终的目标可能是在低功耗设备或嵌入式系统上运行代码。通过交叉编译,可以在开发主机上进行快速的开发、调试和测试,然后将生成的可执行文件部署到目标平台上,提高开发效率。

  4. 跨平台开发:对于跨平台应用程序或库的开发,交叉编译是一种常见的方法。它允许在一台主机上编译和构建适用于多个目标平台的代码,从而简化了跨平台开发的复杂性。

2 交叉编译工具链命名规则

在使用交叉编译链时,常常会看到下面这样的名字:

arm-linux-gnueabihf-
arm-none-linux-gnueabi-
arm-cortex_a8-linux-gnueabi-
mips-malta-linux-gnu-

这些交叉编译链的命名通常会遵循一定的规则:arch-vender-os-abi,各字段说明如下:

  • arch:目标cpu架构,比如mips、arm、x86、riscv等,该字段通常不会省略
  • vendor:提供此编译工具链的厂商名称或是厂商特定信息,该字段只是标识信息,没有实际意义,可以为none、cross、unknow或是直接省略
  • os:目标设备上运行的操作系统,常见的有linux、none(裸机)等
  • abi:应用程序二进制接口(Application Binary Interface),交叉编译链所选择的库函数和目标映像的规范,该字段常见的值有abi 、eabi(embedded abi)、gun(glibc+oabi)、gnueabi(glibc+eabi)、gnueabihf (hf 指默认编译参数支持硬件浮点功能)等

工具链的种类
GCC 的命名规则为: arch [-vendor] [-os] [-(gnu)eabi]-gcc

比如 arm-linux-gnueabi-gcc ,arm-none-eabi-gcc, aarch64-linux-gnu-gcc

带 [] 的是可选部分。
arch: 芯片架构,比如 32 位的 Arm 架构对应的 arch 为 arm,64 位的 Arm 架构对应的 arch 为 aarch64。
vendor :工具链提供商,大部分工具链名字里面都没有包含这部分。
os :编译出来的可执行文件(目标文件)针对的操作系统,比如 Linux。
arm-none-eabi-gcc 一般适用用于 Arm Cortex-M/Cortex-R 平台,它使用的是 newlib 库。

arm-linux-gnueabi-gcc 和 aarch64-linux-gnu-gcc 适用于 Arm Cortex-A 系列芯片,前者针对 32 位芯片,后者针对 64 位芯片,它使用的是 glibc 库。可以用来编译 u-boot、linux kernel 以及应用程序。

另外需要补充一点的是,32 位的 Arm 和 64 位的 Arm,它们的指令集是不同的,所以需要使用不同的工具链。当然,Arm64 为了保证前向兼容,提供了一个 32 位的兼容模式,所以我们用 arm-linux-gnueabi-gcc 编译的应用程序也是可以直接在Arm64 的系统上运行的,但是 Linux Kernel 和 U-Boot 就不行,除非你提前把 CPU 切换到 32 位模式。曾经有个项目使用了一颗四核的 Arm64 芯片,但是内存只有64M,为了节省空间,在 CPU 运行到 U-Boot 之前,我们就把它切到了 32 位模式,后面的 U-Boot、Linux Kernel,应用全部都用 32 位编译,加上 Thumb 指令集,节省了不少空间。

3.GCC交叉编译工具链

GCC(GNU Compiler Collection)是一个广泛使用的编译器套件,提供了用于多种体系结构的交叉编译工具链。对于Linux系统上的交叉编译,GCC交叉工具链是一个常见且强大的选择。

GCC交叉工具链的命名约定通常使用目标体系结构作为前缀,并在后面加上"-"和ABI(Application Binary Interface)标识符。以下是一些常见的GCC交叉工具链示例:

1. arm-linux-gnueabi-gcc:用于ARM体系结构的交叉编译工具链。"arm"表示ARM体系结构,"linux"表示目标操作系统为Linux,"gnueabi"表示使用GNU的嵌入式ABI。

2. arm-linux-gnueabihf-gcc:与上面的工具链类似,但是添加了"hf"表示使用硬浮点(hard-float)的ABI。这意味着该工具链支持使用硬件浮点指令进行浮点运算。

3. x86_64-linux-gnu-gcc:用于x86-64体系结构(也称为AMD64或Intel 64)的交叉编译工具链。"x86_64"表示目标体系结构为x86-64,"linux"表示目标操作系统为Linux,"gnu"表示使用GNU的ABI。

4. mips-linux-gnu-gcc:用于MIPS体系结构的交叉编译工具链。"mips"表示MIPS体系结构,"linux"表示目标操作系统为Linux,"gnu"表示使用GNU的ABI。

这些工具链提供了gcc、g++等编译器和相关工具,可以用于编译C、C++等源代码,并生成适用于特定体系结构的可执行文件。您可以根据目标体系结构和所需的ABI选择适当的GCC交叉工具链。

举个例子

当使用GCC交叉工具链时,以下是一个示例:

假设您正在开发一个嵌入式系统,目标平台是ARM体系结构,并且目标操作系统是Linux。您可以使用arm-linux-gnueabi-gcc来进行交叉编译。

  1. 编写源代码:创建一个名为"hello.c"的C语言源文件,内容如下:
#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}
  1. 执行交叉编译:在命令行中使用arm-linux-gnueabi-gcc工具链进行交叉编译,生成适用于ARM体系结构的可执行文件。命令如下:
arm-linux-gnueabi-gcc -o hello hello.c

这将使用arm-linux-gnueabi-gcc编译器将"hello.c"源文件编译为名为"hello"的可执行文件。


 


 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 安装交叉编译工具链和目标平台的SDK 首先需要安装交叉编译工具链和目标平台的SDK。这里以使用arm-linux-gnueabi交叉编译工具链为例。可以从官网下载对应的工具链和SDK,也可以使用apt-get等包管理器进行安装。 2. 配置交叉编译工具链 在使用交叉编译工具链之前,需要配置环境变量。例如,将arm-linux-gnueabi-gcc添加到PATH环境变量中: ``` export PATH=$PATH:/path/to/arm-linux-gnueabi/bin ``` 3. 下载llvm源码 可以从llvm官网下载最新的llvm源码,也可以使用git从github上获取: ``` git clone https://github.com/llvm/llvm-project.git ``` 4. 进入llvm源码目录,创建build目录 ``` cd llvm-project mkdir build cd build ``` 5. 配置llvm编译选项 使用cmake配置llvm的编译选项,指定交叉编译工具链和目标平台的SDK路径: ``` cmake -DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc -DCMAKE_CXX_COMPILER=arm-linux-gnueabi-g++ \ -DCMAKE_INSTALL_PREFIX=/path/to/install/ \ -DLLVM_TARGET_ARCH=ARM \ -DLLVM_TARGETS_TO_BUILD=ARM \ -DLLVM_DEFAULT_TARGET_TRIPLE=arm-linux-gnueabi \ -DLLVM_ENABLE_PROJECTS=clang ../llvm ``` 其中,-DCMAKE_INSTALL_PREFIX选项指定了llvm安装的路径,-DLLVM_TARGET_ARCH和-DLLVM_TARGETS_TO_BUILD选项指定了目标平台的架构,-DLLVM_DEFAULT_TARGET_TRIPLE选项指定了交叉编译的目标系统。 6. 编译llvm 使用make命令进行编译: ``` make -j4 ``` 其中,-j选项指定了并行编译的线程数。 7. 安装llvm 使用make install命令进行安装: ``` make install ``` 8. 配置环境变量 将llvm安装路径添加到环境变量中: ``` export PATH=$PATH:/path/to/install/bin ``` 至此,llvm交叉编译详细步骤已经完成。可以使用llvm进行交叉编译,生成针对目标平台的二进制文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值