交叉编译中configure(Autotools)和CMake是两种主流的构建配置工具,二者在设计理念、使用方式、跨平台性、对交叉编译的支持等方面差异显著。以下从核心维度对比,并结合实际场景分析选型思路。
1、核心定位与基础原理
| 特性 | configure(Autotools) | CMake |
|---|---|---|
| 本质 | 基于 Autoconf 生成的 Shell 脚本(.configure) |
跨平台构建配置工具,生成 Makefile/VS 工程 / Ninja 等 |
| 设计目标 | 类 Unix 系统下的可移植性(POSIX 兼容) | 全平台统一构建(Windows/Linux/ 嵌入式 / 移动端) |
| 配置文件 | configure.ac(Autoconf)+ Makefile.am(Automake) |
CMakeLists.txt(声明式语法) |
| 依赖解析 | 依赖系统pkg-config/ 手动检测,脚本化逻辑 |
内置find_package/find_library,模块化检测 |
交叉编译的核心是指定目标架构、编译器、库路径,二者的实现方式差异是选型关键:
(1) configure(Autotools)交叉编译
Autotools 是为类 Unix 原生编译设计,交叉编译需通过环境变量 + 参数手动指定,核心依赖--host参数(目标系统)。
典型流程:
# 1. 定义交叉编译工具链前缀(如arm-linux-gnueabihf-)
export CROSS_COMPILE=arm-linux-gnueabihf-
# 2. 指定编译器(也可通过--host隐式推导)
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
export AR=${CROSS_COMPILE}ar
export LD=${CROSS_COMPILE}ld
# 3. 执行configure,指定目标系统和库路径
./configure \
--host=arm-linux-gnueabihf # 关键:声明目标系统(决定编译器前缀)
--prefix=/path/to/target/install # 安装路径(目标机路径)
--with-sysroot=/path/to/sysroot # 目标根文件系统(头文件/库路径)
--disable-shared # 可选:编译静态库
核心特点:
依赖--host参数:需严格匹配target-triple(如aarch64-linux-gnu),否则可能推导错误编译器;
环境变量优先:CC/CXX/AR/LD等变量会覆盖--host的默认推导;
sysroot 支持:需手动指定--with-sysroot,否则可能链接主机库;
灵活性差:复杂交叉编译(如多架构、自定义库路径)需手写 Shell 脚本补充。
(2) CMake 交叉编译
CMake 专为跨平台设计,交叉编译通过工具链文件(Toolchain File) 统一管理,逻辑更清晰、可复用。
典型流程:
步骤 1:编写工具链文件toolchain_arm.cmake(核心)
# 1. 指定目标系统(必填)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# 2. 指定交叉编译器(绝对路径/前缀)
set(CROSS_COMPILE /opt/toolchain/arm-linux-gnueabihf-)
set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++)
set(CMAKE_AR ${CROSS_COMPILE}ar)
set(CMAKE_LINKER ${CROSS_COMPILE}ld)
# 3. 指定目标sysroot(根文件系统)
set(CMAKE_SYSROOT /path/to/arm-sysroot)
# 4. 指定库/头文件搜索路径(可选,sysroot已包含时可省略)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
# 5. 查找策略:优先搜索目标系统(sysroot),不搜索主机
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # 可执行文件(如编译器)不搜sysroot
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # 库只搜sysroot
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # 头文件只搜sysroot
步骤 2:执行 CMake 配置
cmake \
-DCMAKE_TOOLCHAIN_FILE=./toolchain_arm.cmake \ # 指定工具链文件
-DCMAKE_INSTALL_PREFIX=/path/to/target/install \ # 安装路径
-DBUILD_SHARED_LIBS=OFF \ # 禁用动态库
/path/to/source # 源码目录
核心特点:
工具链文件复用:一套配置可复用在多个项目,避免重复设置环境变量;
强类型检测:内置check_function_exists/check_include_file等,自动适配目标系统;
多生成器支持:可生成 Makefile、Ninja、甚至 Windows 的 VS 工程(跨平台优势);
sysroot 自动适配:CMAKE_SYSROOT会自动拼接到头文件 / 库搜索路径,减少手动配置。
3、关键维度对比
| 对比维度 | configure(Autotools) | CMake |
|---|---|---|
| 学习成本 | 高(需懂 Shell/Autoconf 语法) | 中(声明式 CMake 语法,文档丰富) |
| 跨平台支持 | 差(仅类 Unix,Windows 需 MinGW/Cygwin) | 优(Windows/Linux/macOS/ 嵌入式 / 移动端) |
| 交叉编译配置 | 零散(环境变量 + 参数),易出错 | 集中(工具链文件),可维护性强 |
| 依赖管理 | 依赖pkg-config,需手动指定PKG_CONFIG_PATH |
内置find_package,支持Config/Module模式 |
| 调试难度 | Shell 脚本调试复杂(echo/set -x) | 内置cmake --debug-output,日志清晰 |
| 社区支持 | 传统项目多(如开源工具链、老牌库) | 现代项目主流(如 Qt/OpenCV/ROS) |
| 扩展性 | 需手写 Shell 脚本扩展 | 支持自定义函数 / 宏 / 模块,扩展灵活 |
| 构建速度 | 快(纯 Shell 脚本) | 略慢(CMake 生成 Makefile 需额外步骤) |
4、选型建议
(1) 优先选 configure 的场景
a.维护传统开源项目(如 libcurl、zlib 等原生 Autotools 构建的库);
b.仅需类 Unix 单一平台交叉编译,且团队熟悉 Shell;
c.对构建速度要求极高,且配置逻辑简单。
(2) 优先选 CMake 的场景
a.跨平台项目(需支持 Windows/Linux/ 嵌入式多平台);
b.复杂交叉编译(如多架构、自定义 sysroot、依赖多库);
c.团队需统一构建规范(工具链文件复用、配置可维护);
d.现代开源项目开发(如 C++11+、ROS2、嵌入式 SDK)。
(3) 总结
configure是类 Unix 系统的 “传统方案”,适合简单场景或维护老项目,但交叉编译配置零散、易出错;
CMake是 “现代跨平台方案”,通过工具链文件统一管理交叉编译配置,可维护性和扩展性远优于 Autotools,是当前嵌入式 / 跨平台 C/C++ 项目的主流选择。
实际项目中,若遇到 Autotools 构建的库,可通过cmake-convert工具将configure.ac转换为CMakeLists.txt,或直接适配其交叉编译参数;新项目建议优先使用 CMake,降低长期维护成本。
浙公网安备 33010602011771号