1、交叉编译工具链
1.1 定义
交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发工具集,它允许开发者在一个平台上(例如高性能的PC或服务器)编译生成另一个平台(例如嵌入式系统或不同的操作系统和硬件架构)上运行的代码。在Linux系统中,交叉编译工具链主要用于嵌入式系统的开发,因为嵌入式系统通常资源有限,难以直接在其上进行编译操作。
1.2 格式
通常其格式定义如下:
arch[-vendor][-os][-(gnu)eabi][-gcc]
arch
:目标平台的体系架构,如arm
、x86
等。vendor
:工具链的供应商或自定义标识符,如果没有特定供应商,通常用none
代替。os
:目标操作系统,如linux
、android
等。如果没有特定操作系统支持,也用none
代替。(gnu)eabi
:嵌入式应用二进制接口(Embedded Application Binary Interface),它指定了文件格式、数据类型、寄存器使用、堆栈组织优化和在一个嵌入式软件中的参数的标准约定。例如,gnueabihf
适用于ARM架构的硬浮点ABI。gcc
:表示这是一个GCC(GNU Compiler Collection)系列的编译器
1.3 工具示例
arm-linux-gnueabihf-gcc
- 架构:ARM
- 操作系统:Linux
- ABI:GNU EABI with Hard Float (hf)
- 描述:用于在Linux下为ARM架构编译带有硬浮点支持的程序。
arm-none-linux-gnueabi-gcc
- 架构:ARM
- 供应商:none(表示没有特定的供应商或定制)
- 操作系统:Linux
- ABI:GNU EABI
- 描述:用于在Linux下为ARM架构编译没有特定供应商标识的程序,使用标准的GNU EABI。
aarch64-linux-gnu-gcc
- 架构:ARM64(也称为AArch64)
- 操作系统:Linux
- ABI:GNU
- 描述:用于在Linux下为ARM64架构编译程序。
mips-linux-gnu-gcc
- 架构:MIPS
- 操作系统:Linux
- ABI:GNU
- 描述:用于在Linux下为MIPS架构编译程序。
关于gnu
、gnueabi
和 gnueabihf
:
gnu
、gnueabi
和gnueabihf
这些后缀在工具链命名中用于描述对EABI的不同支持级别。gnu
通常是一个更通用的标识,而gnueabi
表明对EABI的支持,但不直接指明浮点运算的形式。gnueabihf
则明确表示支持硬件浮点运算。- 对于只包含
gnu
或gnueabi
的工具链命名,需要通过查阅文档或参考编译器选项来确定对浮点运算的具体支持情况。
2、linux下软件的交叉编译
2.1 configure作用
configure脚本将根据当前主机系统的类型和特性来检测系统环境,包括编译器、链接器、标准库、头文件等信息,然后生成一个包含编译选项和其他配置信息的Makefile文件。这个Makefile文件将根据检测到的环境配置编译过程,确保软件能够正确编译并在目标平台上运行。
在交叉编译情况下,configure脚本还会根据用户指定的交叉编译工具链来设置正确的编译器、链接器等工具,以确保生成的可执行文件能够在目标平台上正确运行。
2.2 configure常用选项
- --build=BUILD
- 指定编译所用的机器的平台。通常,如果不特别指定,其默认值将等同于
--host
选项的值。
- 指定编译所用的机器的平台。通常,如果不特别指定,其默认值将等同于
- --host=HOST
- 指定编译出的代码将要运行的目标平台。这是交叉编译中最重要的选项之一。HOST 通常使用目标三元组(target triple)表示,包含 CPU 架构、供应商、操作系统和 ABI。例如,
x86_64-unknown-linux-gnu
表示一个 CPU 架构为 x86_64、操作系统为 Linux、ABI 为 GNU 的系统。
- 指定编译出的代码将要运行的目标平台。这是交叉编译中最重要的选项之一。HOST 通常使用目标三元组(target triple)表示,包含 CPU 架构、供应商、操作系统和 ABI。例如,
- --target=TARGET
- 指定编译出来的工具链(如编译器、链接器等)生成的代码将要运行的目标平台。这个选项在构建交叉编译环境时较为常用,尤其是在编译 gcc、ld 等工具链时。通常情况下,正常编译和交叉编译都不会用到这个选项。
- --prefix=PREFIX
- 指定软件安装的位置。这在交叉编译时尤为重要,因为它决定了编译出的软件将安装到哪个目录。
- --disable-FEATURE
- 禁用某些特性。一些软件包提供了可选的编译时配置,如使用 Kerberos 认证系统或实验性的编译器优化。如果默认是提供这些特性,可以使用此选项来禁用它们。
- --enable-FEATURE[=ARG]
- 启用某些默认被禁止的特性,并可以为特性指定可选的参数。例如,启用特定的缓冲区大小或特定功能的启用/禁用。
- --srcdir=DIR
- 告诉
configure
源码的位置。通常不需要特别指定,因为configure
脚本通常和源码文件在同一个目录下。
- 告诉
- --program-prefix=PREFIX 和 --program-suffix=SUFFIX
- 分别指定将被加到所安装程序的名字上的前缀和后缀。这有助于区分同一台机器上安装的不同版本或不同构建的程序。
- --program-transform-name=PROGRAM
- 使用 sed 脚本来变换安装的程序名。
- LDFLAGS="-L/path/to/libs" 和 CPPFLAGS="-I/path/to/includes"
- 分别用于指定链接器和预处理器使用的额外库和头文件路径。这在交叉编译时尤其有用,因为需要指定目标平台的库和头文件路径。
3、交叉编译sqlite3
3.1 获取源码
从官网获取:SQLite Download Page,直接下载放入虚拟机即可,也可以在资源处点击右键获取下载链接然后通过wget命令下载:
wget https://www.sqlite.org/2024/sqlite-autoconf-3460000.tar.gz
下载完成:
使用tar -xzf sqlite-autoconf-3460000.tar.gz解压:
3.2 配置
进入解压后的目录,创建一个output文件夹,进行如下配置:
./configure --host=aarch64-linux-gnu --prefix=/home/aka_li/linux/mysqlite3/sqlite-autoconf-3460000/output
其中aarch64-linux-gnu要修改为你的目标主机,/home/aka_li/linux/mysqlite3/sqlite-autoconf-3460000/output为你要输出的目录。
然后顺序执行make和make install,最终编译文件输出到前面指定的output文件夹中:
3.3 编程
参考之前文章中的数据库编程代码:Linux应用 sqlite3编程编译可执行程序,其中-L指定动态库位置,-I(大写i)指定头文件目录,-l(小写L)指定动态库名称:
aarch64-linux-gnu-gcc sqlite3.c -L/home/aka_li/linux/mysqlite3/sqlite-autoconf-3460000/output/lib/ -I/home/aka_li/linux/mysqlite3/sqlite-autoconf-3460000/output/include/ -lsqlite3 -o sqlitetest
进入output文件夹打包,命令如下:
tar -czvf sqlitefile.tar.gz .
打包完拷贝至目标板中,解压后将lib目录下的库拷贝到目标板的/lib目录下,将编译完成的应用程序也拷贝至目标板中,:
执行可执行程序,可以正常运行:
4、总结
本文讲解了linux下交叉编译工具链的格式,阐述了交叉编译软件时configure的配置过程,编写了sqlite3的交叉编译示例。