ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CMake 工具链与交叉编译完全指南:从 Toolchain File 到各平台实战

CMake 工具链与交叉编译完全指南:从 Toolchain File 到各平台实战 构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载导读工具链Toolchain是 CMake 构建系统的基石它决定了编译、链接、归档等全部构建动作由哪一组工具完成。本指南以 CMake 官方手册 cmake-toolchains(7) 为骨架系统讲解语言启用机制、编译器相关变量与属性、try_compile能力探测以及面向 Linux、Cray、Clang、QNX、Windows CE/Store/Phone、ADSP、Android、Apple 平台、Emscripten 与 Renesas 等十余类交叉编译场景的 Toolchain File 编写方法。读完本文你将能够独立编写一份可用的 Toolchain File理解CMAKE_FIND_ROOT_PATH_MODE_*等搜索规则的底层行为并能针对具体嵌入式与移动平台完成配置。引言什么是 CMake 工具链CMake 使用一组工具Toolchain来完成编译、库链接、归档创建等构建任务。这组工具由启用的语言决定例如启用了 C 语言就需要 C 编译器启用了 Fortran就需要 Fortran 编译器与对应的归档工具。工具链的获取方式分为两种本机构建host buildCMake 通过系统内省system introspection与默认值自动探测编译器路径和配套工具无需人工指定交叉编译cross-compiling通过Toolchain File工具链文件显式提供编译器与工具路径等信息。从 CMake 3.19 起还可以通过 cmake-presets(7) 指定 Toolchain Filepreset 中的toolchainFile字段。在源码层面Source/cmake.cxx 中定义了命令行参数--toolchain file见 Source/cmake.cxx#L310并在 Source/cmake.cxx#L2150-L2153 处将 preset 展开后的ToolchainFile写入CMAKE_TOOLCHAIN_FILE缓存变量Source/cmake.cxx#L2693-L2696 还支持从环境变量CMAKE_TOOLCHAIN_FILE读取该值。关键事实Toolchain File 本身是在配置阶段早期被加载的普通 CMake 脚本set(...)赋值即生效它并非一个被include()的普通模块而是在检测编译器之前由cmake主流程注入因此其中的变量赋值会直接作用于后续的编译器探测。语言启用机制语言由 project() 命令启用。调用project()时CMake 会设置该语言相关的内建变量例如 CMAKE_CXX_COMPILER、CMAKE_CXX_COMPILER_ID 等。若顶层 CMakeLists.txt 中没有project()命令CMake 会隐式生成一个。默认启用C和CXX两种语言。只启用 C 语言project(C_Only C)不启用任何语言可用于纯数据/配置项目project(MyProject NONE)在project()之后通过 enable_language() 追加启用语言enable_language(CXX)启用一种语言时CMake 会为该语言查找编译器并探测其供应商vendor与版本、目标架构与位宽、配套工具位置等信息。当前已启用的语言集合记录在 ENABLED_LANGUAGES 全局属性中。从源码实现看project()触发语言启用后cmGlobalGenerator::EnableLanguages会加载对应的Modules/CMakeDetermine*Compiler.cmake与Modules/Platform/Platform-Compiler.cmake例如Modules/CMakeDetermineCCompiler.cmake、Modules/Platform/Linux-GNU.cmake等这些文件共同完成编译器 ID、版本和 ABI 探测。与工具链相关的变量与属性语言级编译器变量以下变量与当前启用的语言一一对应LANG可替换为C、CXX、Fortran、ASM、CUDA等变量含义CMAKE_ _COMPILER用于LANG的编译器完整路径CMAKE_ _COMPILER_IDCMake 使用的编译器标识如GNU、Clang、MSVC、AppleClangCMAKE_ _COMPILER_VERSION编译器版本CMAKE_ _FLAGS会附加到该语言所有编译与链接调用的标志含各配置对应的CMAKE_LANG_FLAGS_CONFIG如CMAKE_C_FLAGS_RELEASECMAKE_ _LINK_FLAGS4.3 新增仅附加到由该语言驱动链接的调用同样存在配置化等价变量注意CMAKE_LANG_FLAGS同时作用于编译与链接驱动调用而CMAKE_LANG_LINK_FLAGS4.3 起只作用于链接驱动二者在链接阶段的语义差异是排查“链接时标志被吞”的关键。链接语言的选择CMake 需要决定用哪个编译器来驱动链接器。规则如下由目标target中各源文件的 LANGUAGE 属性决定对静态库还参考其依赖库的LANGUAGE可通过 LINKER_LANGUAGE 目标属性覆盖默认选择。典型场景一个项目同时包含 C 与 Fortran 源文件时链接通常应交给 Fortran 编译器驱动以引入其运行时库此时可显式设置set_target_properties(mylib PROPERTIES LINKER_LANGUAGE Fortran)。工具链能力探测CMake 提供 try_compile() 命令与多个模块用于测试工具链的特定能力与可用性CheckSourceCompiles以及CheckCSourceCompiles、CheckCXXSourceCompiles、CheckFortranSourceCompiles等CheckCXXSymbolExistsCheckIncludeFile这些 API 会以某种方式测试工具链并将结果缓存Cache 变量避免下次运行 CMake 时重复探测。这也是为什么更换工具链后常常需要清理 CMakeCache.txt——缓存中的能力结论可能已失效。部分工具链特性由 CMake 内建处理无需编译测试POSITION_INDEPENDENT_CODE指定目标构建为位置无关代码-fPIC等前提是编译器支持_VISIBILITY_PRESET与 VISIBILITY_INLINES_HIDDEN在编译器支持时添加隐藏可见性标志。从实现上看try_compile会生成一个临时项目并在独立目录中执行编译见 Source/cmTryCompileCommand.cxx。这也是手册强调“Toolchain File 中不要依赖CMAKE_SOURCE_DIR/CMAKE_BINARY_DIR”的原因在try_compile的上下文中这些变量会被重定向到临时项目取值不可预期应优先使用始终有确定值的 CMAKE_CURRENT_LIST_DIR 来解析路径。交叉编译概述加载 Toolchain File若以命令行参数--toolchain path/to/file或-DCMAKE_TOOLCHAIN_FILEpath/to/file调用 cmake(1)该文件会在早期被加载以设置编译器相关值。当 CMake 处于交叉编译时CMAKE_CROSSCOMPILING 变量被置为true。典型的交叉编译配置流程为$ cmake ../src -DCMAKE_TOOLCHAIN_FILE/path/to/toolchain.cmake在源码层面toolchain 文件路径会写入缓存Source/cmGlobalGenerator.cxx#L717-L739 显示配置阶段会读取构建目录下的CMakeSystem.cmake若检测到CMAKE_TOOLCHAIN_FILE与本次输入值不一致会将该变量标记为需要删除的缓存变更并重新配置因为“toolchain 文件变化会使内省结果失效”。Toolchain File 编写注意事项不要使用CMAKE_SOURCE_DIR或CMAKE_BINARY_DIR它们在try_compile等不同上下文中取值不同应使用 CMAKE_CURRENT_LIST_DIR 定位 Toolchain File 同目录下的工具它始终具有明确、可预期的值。通用 Toolchain File 骨架综合多平台场景一份通用 Toolchain File 通常包含# 目标平台与架构CMake 标识符 set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) # 交叉根文件系统与安装暂存路径均可选 set(CMAKE_SYSROOT /path/to/rootfs) set(CMAKE_STAGING_PREFIX /path/to/stage) # 编译器完整路径或可搜索的名字 set(CMAKE_C_COMPILER /path/to/arm-gcc) set(CMAKE_CXX_COMPILER /path/to/arm-g) set(CMAKE_ASM_COMPILER /path/to/arm-as) # 如启用 ASM # 查找规则程序只在宿主上找库/头/包只在目标上找 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)关键变量语义变量说明CMAKE_SYSTEM_NAME目标平台的 CMake 标识符Linux、Android、WindowsCE、QNX等也是触发交叉编译的关键开关CMAKE_SYSTEM_PROCESSOR目标架构的 CMake 标识符如arm、aarch64CMAKE_SYSROOT可选sysroot 根目录find_*命令会在此查找CMAKE_STAGING_PREFIX可选宿主上用于install的暂存路径。注意 CMAKE_INSTALL_PREFIX始终是运行时安装位置交叉编译时也不变CMAKE_ _COMPILER可设为完整路径或设为名字让 CMake 在标准位置搜索CMAKE_TRY_COMPILE_TARGET_TYPE设为STATIC_LIBRARY可让 CMake 在能力检查时不尝试链接可执行文件适合无法直接链接二进制的工具链CMAKE_TRY_COMPILE_TARGET_TYPE在源码中对应 Source/cmTryCompileCommand.cxx#L57-L63当其值为STATIC_LIBRARY时try_compile 生成的目标类型为静态库。Renesas CC-RL 一节中正是用它规避测试可执行文件超出 const section 大小限制的问题。CMAKE_FIND_ROOT_PATH_MODE_*的查找语义默认情况下find_*命令会依次查找 sysroot、CMAKE_FIND_ROOT_PATH 条目以及宿主系统根前缀。交叉编译时通常希望头文件、库、包只在目标系统前缀中查找ONLY必须作为构建一部分在宿主上运行的程序编译器、链接器、打包工具等只在宿主上查找NEVER。这就是CMAKE_FIND_ROOT_PATH_MODE_PROGRAM/LIBRARY/INCLUDE/PACKAGE四个变量的用途取值均为NEVER、ONLY或BOTH默认。实现上Source/cmFindCommon.cxx#L160 会按查找路径类别动态读取CMAKE_FIND_ROOT_PATH_MODE_类别对应的值来约束搜索范围。面向 Linux 的交叉编译一份典型的面向 Linux如树莓派的交叉编译 Toolchain Fileset(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs) set(CMAKE_STAGING_PREFIX /home/devel/stage) set(tools /home/devel/gcc-4.7-linaro-rpi-gnueabihf) set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc) set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)说明CMAKE_SYSTEM_NAME与CMAKE_SYSTEM_PROCESSOR是必填项CMAKE_SYSROOT与CMAKE_STAGING_PREFIX可选。若工具链无法直接链接可执行文件可追加set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)。面向 Cray Linux 环境CLE的交叉编译Cray 登录节点与计算节点交叉编译无需单独的 Toolchain File在命令行指定-DCMAKE_SYSTEM_NAMECrayLinuxEnvironment即可保证正确的构建设置与搜索路径对应平台模块为 Modules/Platform/CrayLinuxEnvironment.cmake 与 Modules/Platform/CrayLinuxEnvironment-Initialize.cmake。平台会从当前环境变量拉取配置并在存在且已加载时使用 Cray Programming Environment 的PrgEnv-*模块中的编译器包装器。CLE 默认仅支持静态库设置环境变量CRAYPE_LINK_TYPEdynamic可启用共享库。不指定CMAKE_SYSTEM_NAME时配置阶段按标准 Linux 环境以主机模式运行此时若未覆盖PrgEnv-*包装器会被使用——登录节点构建通常不希望这样。例外直接在 NID 上构建而非从登录节点交叉编译时可以使用包装器。若为登录节点构建软件要么先unload已加载的PrgEnv-*模块要么显式让 CMake 使用/usr/bin下的系统编译器。若为计算节点构建如上所述指定CMAKE_SYSTEM_NAMECrayLinuxEnvironment即可。使用 Clang 交叉编译Clang 等编译器本身即是交叉编译器。通过CMAKE_ _COMPILER_TARGET向编译器传递目标三元组tripleset(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(triple arm-linux-gnueabihf) set(CMAKE_C_COMPILER clang) set(CMAKE_C_COMPILER_TARGET ${triple}) set(CMAKE_CXX_COMPILER clang) set(CMAKE_CXX_COMPILER_TARGET ${triple})另外某些编译器不自带链接器等配套工具但允许指定外部工具链位置供编译器驱动使用。可在 Toolchain File 中设置CMAKE_ _COMPILER_EXTERNAL_TOOLCHAIN来传递该路径。典型场景用 Clang 驱动 GNU 工具链--gcc-toolchain其配套 binutils 来自交叉 GCC 安装目录。面向 QNX 的交叉编译QNX 的 QCC 编译器与 Clang 一样是天然的交叉编译器同样通过CMAKE_LANG_COMPILER_TARGET传递目标set(CMAKE_SYSTEM_NAME QNX) set(arch gcc_ntoaarch64) set(CMAKE_C_COMPILER qcc) set(CMAKE_C_COMPILER_TARGET ${arch}) set(CMAKE_CXX_COMPILER q) set(CMAKE_CXX_COMPILER_TARGET ${arch}) set(CMAKE_SYSROOT $ENV{QNX_TARGET})arch的值如gcc_ntoaarch64是 QNX 定义的目标变体名决定 QCC 选择的 CPU 目标sysroot 直接取环境变量QNX_TARGET。面向 Windows CE 的交叉编译面向 Windows CE 交叉编译要求系统安装对应 SDK通常位于C:/Program Files (x86)/Windows CE Tools/SDKs。配置 Visual Studio 生成器的 Toolchain File 形如set(CMAKE_SYSTEM_NAME WindowsCE) set(CMAKE_SYSTEM_VERSION 8.0) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_GENERATOR_TOOLSET CE800) # 8.0 可省略 set(CMAKE_GENERATOR_PLATFORM SDK_AM335X_SK_WEC2013_V310)CMAKE_GENERATOR_PLATFORM 告诉生成器使用哪个 SDKCMAKE_SYSTEM_VERSION 告诉生成器使用哪个 Windows CE 版本。目前开箱支持 8.0Windows Embedded Compact 2013其他版本可能需要将 CMAKE_GENERATOR_TOOLSET 设置为正确值。面向 Windows 10 通用应用UWP的交叉编译配置 Visual Studio 生成器构建 Windows 10 通用应用set(CMAKE_SYSTEM_NAME WindowsStore) set(CMAKE_SYSTEM_VERSION 10.0)Windows 10 通用应用同时面向 Windows Store 与 Windows Phone。CMAKE_SYSTEM_VERSION需设为10.0或更高。CMake 按 CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION 变量文档所述选择 Windows SDK。面向 Windows Phone / Windows Store 的交叉编译Windows Phoneset(CMAKE_SYSTEM_NAME WindowsPhone) set(CMAKE_SYSTEM_VERSION 8.1)Windows Storeset(CMAKE_SYSTEM_NAME WindowsStore) set(CMAKE_SYSTEM_VERSION 8.1)二者均用于配置 Visual Studio 生成器。面向 ADSP SHARC/Blackfin 的交叉编译面向 ADSP SHARC 或 Blackfin 交叉编译设置 CMAKE_SYSTEM_NAME 为ADSP设置 CMAKE_SYSTEM_PROCESSOR 为去掉ADSP-前缀的“部件号”例如21594、SC589该值不区分大小写。CMake 会自动在默认安装位置搜索 CCES 或 VDSP 安装并选择最近版本两者都装时优先 CCES。自定义安装路径可通过 CMAKE_ADSP_ROOT 变量或 ADSP_ROOT 环境变量设置。编译器cc21k对应 SHARCccblkfn对应 Blackfin会根据CMAKE_SYSTEM_PROCESSOR自动选择。面向 Android 的交叉编译环境选择规则将 CMAKE_SYSTEM_NAME 设为Android即可启用 Android 交叉编译其余配置取决于使用的 Android 开发环境Visual Studio 生成器需要 NVIDIA Nsight Tegra Visual Studio Edition 或 Visual Studio Tools for AndroidMakefile 生成器 / Ninja需要 NDK 或 Standalone Toolchain。CMake 按以下顺序选择环境任一命中即止若 CMAKE_ANDROID_NDK 已设置 → 使用指定位置的 NDK否则若 CMAKE_ANDROID_STANDALONE_TOOLCHAIN 已设置 → 使用 Standalone Toolchain否则若 CMAKE_SYSROOT 形如ndk/platforms/android-api/arch-arch→ 提取ndk作为 NDK否则若CMAKE_SYSROOT形如standalone-toolchain/sysroot→ 提取standalone-toolchain作为 Standalone Toolchain否则若 CMake 变量ANDROID_NDK已设置 → 用作 NDK否则若 CMake 变量ANDROID_STANDALONE_TOOLCHAIN已设置 → 用作 Standalone Toolchain否则若环境变量ANDROID_NDK_ROOT或ANDROID_NDK已设置 → 用作 NDK否则若环境变量ANDROID_STANDALONE_TOOLCHAIN已设置 → 用作 Standalone Toolchain否则报错找不到 NDK 或 Standalone Toolchain。从 3.20 起若选中 NDK其版本号会记录在 CMAKE_ANDROID_NDK_VERSION 变量中。平台模块实现位于 Modules/Platform/Android-Initialize.cmake其会按需include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/...)将 NDK 自带的钩子hooks纳入配置流程。使用 NDK 交叉编译可配置 Makefile、Ninja 或 Visual Studio 生成器。相关变量变量说明CMAKE_SYSTEM_NAME必须为AndroidCMAKE_SYSTEM_VERSIONAndroid API level。未指定时若 CMAKE_ANDROID_API 已设置则用之否则若CMAKE_SYSROOT已设置则从 NDK 目录结构检测否则用 NDK 中最新的 API levelCMAKE_ANDROID_ARCH_ABIAndroid ABI架构。未指定时默认取armeabi、armeabi-v7a、arm64-v8a中第一个受支持的CMAKE_ANDROID_ARCH 会自动由它计算得出。另参见 CMAKE_ANDROID_ARM_MODE 与 CMAKE_ANDROID_ARM_NEONCMAKE_ANDROID_NDKNDK 根目录的绝对路径未指定时按上述选择规则取默认CMAKE_ANDROID_NDK_DEPRECATED_HEADERS置真以使用已废弃的按 API level 划分的头文件而非统一头文件默认 falseNDK 不提供统一头文件时除外CMAKE_ANDROID_NDK_TOOLCHAIN_VERSIONNDK r19 及以上必须不设置或设为clangr18 及以下设为要选用的 NDK 工具链版本默认最新 GCC 工具链CMAKE_ANDROID_STL_TYPE指定使用的 C 标准库未指定时按变量文档选择默认自动计算并提供以下变量CMAKE_ _ANDROID_TOOLCHAIN_PREFIXNDK 工具链中 binutils 的绝对路径前缀CMAKE_ _ANDROID_TOOLCHAIN_SUFFIXNDK 工具链中 binutils 的宿主平台后缀。Toolchain File 示例set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION 21) # API level set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) set(CMAKE_ANDROID_NDK /path/to/android-ndk) set(CMAKE_ANDROID_STL_TYPE gnustl_static)也可不使用 Toolchain File直接在命令行指定$ cmake ../src \ -DCMAKE_SYSTEM_NAMEAndroid \ -DCMAKE_SYSTEM_VERSION21 \ -DCMAKE_ANDROID_ARCH_ABIarm64-v8a \ -DCMAKE_ANDROID_NDK/path/to/android-ndk \ -DCMAKE_ANDROID_STL_TYPEgnustl_static使用 Standalone Toolchain 交叉编译可配置 Makefile 或 Ninja 生成器。相关变量变量说明CMAKE_SYSTEM_NAME必须为AndroidCMAKE_ANDROID_STANDALONE_TOOLCHAINStandalone Toolchain 根目录的绝对路径其下必须存在sysroot子目录未指定时按上述规则取默认CMAKE_ANDROID_ARM_MODE当工具链面向 ARM 时可选设为ON以面向 32 位 ARM 而非 16 位 ThumbCMAKE_ANDROID_ARM_NEON当工具链面向 ARM v7 时可选设为ON以面向 ARM NEON 设备自动计算并提供CMAKE_SYSTEM_VERSION从 Standalone Toolchain 检测出的 API levelCMAKE_ANDROID_ARCH_ABI从 Standalone Toolchain 检测出的 ABICMAKE_ _ANDROID_TOOLCHAIN_PREFIX与CMAKE_ _ANDROID_TOOLCHAIN_SUFFIXbinutils 前缀与宿主后缀。Toolchain File 示例set(CMAKE_SYSTEM_NAME Android) set(CMAKE_ANDROID_STANDALONE_TOOLCHAIN /path/to/android-toolchain)命令行等价写法$ cmake ../src \ -DCMAKE_SYSTEM_NAMEAndroid \ -DCMAKE_ANDROID_STANDALONE_TOOLCHAIN/path/to/android-toolchain使用 NVIDIA Nsight Tegra Visual Studio Edition配置 Visual Studio 生成器以使用 Nsight Tegra 构建 Android 应用set(CMAKE_SYSTEM_NAME Android)CMAKE_GENERATOR_TOOLSET 可用于选择 Nsight Tegra 的 Toolchain Version 值。还可参见以下目标属性ANDROID_API、ANDROID_API_MIN、ANDROID_ARCH、ANDROID_ASSETS_DIRECTORIES、ANDROID_GUI、ANDROID_JAR_DEPENDENCIES、ANDROID_JAR_DIRECTORIES、ANDROID_JAVA_SOURCE_DIR、ANDROID_NATIVE_LIB_DEPENDENCIES、ANDROID_NATIVE_LIB_DIRECTORIES、ANDROID_PROCESS_MAX、ANDROID_PROGUARD、ANDROID_PROGUARD_CONFIG_PATH、ANDROID_SECURE_PROPS_PATH、ANDROID_SKIP_ANT_STEP、ANDROID_STL_TYPE 与 ANDROID_ANT_ADDITIONAL_OPTIONS。面向 iOS、tvOS、visionOS、watchOS 的交叉编译向这些 Apple 平台交叉编译时推荐使用 Xcode 生成器Unix Makefiles 或 Ninja 也可用但需要项目自行处理目标 CPU 选择与代码签名等更多环节。将 CMAKE_SYSTEM_NAME 设为下表对应值即可定位对应平台默认选择最新的 Device SDK与所有 Apple 平台一致可通过 CMAKE_OSX_SYSROOT 选择不同 SDK如模拟器 SDK但通常无需显式设置见下文“设备与模拟器切换”。可用xcodebuild -showsdks列出可用 SDK。OSCMAKE_SYSTEM_NAMEDevice SDK默认Simulator SDKCatalyst SDKiOSiOSiphoneosiphonesimulatormacosxtvOStvOSappletvosappletvsimulatorN/AvisionOSvisionOSxrosxrsimulatorN/AwatchOSwatchOSwatchoswatchsimulatorN/A例如为 iOS 创建 CMake 配置只需cmake .. -GXcode -DCMAKE_SYSTEM_NAMEiOSCMAKE_OSX_ARCHITECTURES 可为设备与模拟器同时设置架构CMAKE_OSX_DEPLOYMENT_TARGET 可设置部署目标。以下示例在一个通用二进制universal binary中安装 5 个架构的 iOS 库并在需要处自动添加-miphoneos-version-min9.3或-mios-simulator-version-min9.3编译标志。注意示例中的 CMAKE_IOS_INSTALL_COMBINED 已废弃此做法不再推荐$ cmake -S. -B_builds -GXcode \ -DCMAKE_SYSTEM_NAMEiOS \ -DCMAKE_OSX_ARCHITECTURESarmv7;armv7s;arm64;i386;x86_64 \ -DCMAKE_OSX_DEPLOYMENT_TARGET9.3 \ -DCMAKE_INSTALL_PREFIXpwd/_install \ -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCHNO \ -DCMAKE_IOS_INSTALL_COMBINEDYES配套的 CMakeLists.txt 与验证命令# CMakeLists.txt cmake_minimum_required(VERSION 3.14) project(foo) add_library(foo foo.cpp) install(TARGETS foo DESTINATION lib)$ cmake --build _builds --config Release --target install用lipo检查通用二进制$ lipo -info _install/lib/libfoo.a Architectures in the fat file: _install/lib/libfoo.a are: i386 armv7 armv7s x86_64 arm64用otool检查最低 iOS 版本$ otool -l _install/lib/libfoo.a | grep -A2 LC_VERSION_MIN_IPHONEOS cmd LC_VERSION_MIN_IPHONEOS cmdsize 16 version 9.3代码签名Apple 嵌入式平台的部分构建产物强制要求代码签名。使用 Xcode 生成器且需要/希望签名时可通过 CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM 指定开发团队 ID该 ID 会写入生成的 Xcode 工程。默认情况下CMake 在内部配置阶段编译器 ID 探测与特性检测会避免代码签名需求。设备与模拟器切换配置任一嵌入式平台时可面向真机或模拟器两者有各自独立的 SDK而 CMake 在配置阶段只支持指定一个 SDK因此必须在配置时二选一。使用 Xcode 生成器时这个限制影响较小——Xcode 仍允许在配置只针对其一的情况下同时为设备或模拟器构建从 Xcode IDE 构建时按所选 destination 平台进行命令行构建时可直接向底层构建工具xcodebuild传-sdk参数$ cmake --build ... -- -sdk iphonesimulator注意配置阶段所做的检查针对配置时的 SDK未必适用于其他 SDK。find_package()、find_library() 等命令只存储和使用所配置 SDK/平台的信息跨设备/模拟器切换时可能出问题。让“设备 模拟器”配置同时工作的规则使用显式-l链接标志例如target_link_libraries(foo PUBLIC -lz)使用显式-framework链接标志例如target_link_libraries(foo PUBLIC -framework CoreFoundation)只对通过 CMAKE_IOS_INSTALL_COMBINED 特性安装的库使用find_package。面向 EmscriptenWebAssembly的交叉编译4.2 新增支持。将 CMAKE_SYSTEM_NAME 设为Emscripten即可配置面向 Emscripten 的交叉编译。Toolchain File 示例set(CMAKE_SYSTEM_NAME Emscripten) set(CMAKE_C_COMPILER /path/to/emcc) set(CMAKE_CXX_COMPILER /path/to/em)对应的平台模块为 Modules/Platform/Emscripten.cmake其中将共享库后缀设为.wasm、可执行文件后缀设为.js见 Modules/Platform/Emscripten.cmake#L18-L19即链接产物为.wasm模块与.js加载器。另有配套的 Modules/Platform/Emscripten-Clang.cmake、Emscripten-Determine-*.cmake等文件处理编译器探测细节。面向 Renesas 编译器的交叉编译Renesas 交叉编译至少需要指定变量说明CMAKE_SYSTEM_NAME设为Generic必须指定以启用交叉编译CMAKE_C_COMPILERRenesas C 编译器路径如ccrx、ccrl、ccrhCMAKE_C_FLAGS编译器要求的-isa或-cpu标志Renesas CC-RXset(CMAKE_SYSTEM_NAME Generic) set(CMAKE_C_COMPILER ccrx.exe) set(CMAKE_ASM_COMPILER ccrx.exe) # 如启用 ASM 语言 set(CMAKE_C_FLAGS -isarxv3) # 指定目标 RX CPU 版本 set(CMAKE_EXE_LINKER_FLAGS -lnkoptyour linker option here)Renesas CC-RLset(CMAKE_SYSTEM_NAME Generic) set(CMAKE_C_COMPILER ccrl.exe) set(CMAKE_ASM_COMPILER ccrl.exe) # 如启用 ASM 语言 set(CMAKE_C_FLAGS -cpuS3) # 指定目标 RL CPU 版本 # 避免测试可执行文件超出 const section 大小限制 set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) # 通过编译器驱动指定设备文件与段布局链接选项 set(CMAKE_EXE_LINKER_FLAGS -lnkopt-devicedr5f10y14.dvf -lnkopt-auto_section_layout)Renesas CC-RHset(CMAKE_SYSTEM_NAME Generic) set(CMAKE_C_COMPILER ccrh.exe) set(CMAKE_ASM_COMPILER ccrh.exe) # 如启用 ASM 语言 set(CMAKE_C_FLAGS -Xcommonrh850) # 指定目标 RH850 CPU 版本 set(CMAKE_EXE_LINKER_FLAGS -lnkoptyour linker option here)实战总结编写 Toolchain File 的检查清单必填CMAKE_SYSTEM_NAME触发交叉编译模式的开关目标平台不同其余必填项不同如 Android 还需CMAKE_ANDROID_NDK或CMAKE_ANDROID_STANDALONE_TOOLCHAIN架构CMAKE_SYSTEM_PROCESSORARM 平台还需CMAKE_ANDROID_ARCH_ABI等编译器CMAKE_LANG_COMPILER必要时补CMAKE_LANG_COMPILER_TARGETClang/QCC、CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN外部 binutils根文件系统CMAKE_SYSROOT可选安装布局CMAKE_STAGING_PREFIX可选仅宿主暂存CMAKE_INSTALL_PREFIX始终是运行时安装位置查找范围根据产物类型设置CMAKE_FIND_ROOT_PATH_MODE_{PROGRAM,LIBRARY,INCLUDE,PACKAGE}为NEVER/ONLY/BOTH能力检查无法链接可执行文件时设CMAKE_TRY_COMPILE_TARGET_TYPESTATIC_LIBRARY路径安全Toolchain File 内解析路径用CMAKE_CURRENT_LIST_DIR不要依赖CMAKE_SOURCE_DIR/CMAKE_BINARY_DIR与 preset 集成3.19 起可在 cmake-presets(7) 中通过toolchainFile字段指定替代命令行--toolchain缓存失效更换 Toolchain File 后 CMake 会检测到CMAKE_TOOLCHAIN_FILE变化并触发重新配置Source/cmGlobalGenerator.cxx#L724-L739若能力探测结果异常清理构建目录的CMakeCache.txt与CMakeFiles/重新配置。上述所有变量、属性与命令的权威定义均可进一步查阅本仓库 Help/variable828 个变量文档、Help/prop_tgt456 个目标属性文档与 Help/command148 个命令文档目录对应实现位于 Source 与 Modules含 Modules/Platform 下 779 个平台相关.cmake文件。围绕具体平台的落地配置可结合 Modules/Platform 中对应平台模块如Linux-GNU.cmake、Android-Initialize.cmake、Emscripten.cmake、CrayLinuxEnvironment.cmake等进一步核对默认行为。赞分享构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载相关推荐Academic Research Skills 全景上手10 阶段流水线、30 秒装好插件四款技能加三个伙伴讲透Academic Research Skills 全景上手10 阶段流水线、30 秒装好插件四款技能加三个伙伴讲透 写论文最磨人的往往不是动笔那一刻而是动AI 技能科研AI 评测人工智能F´ CMake Toolchain 文件完全指南交叉编译工具链与平台文件配置实战F´ CMake Toolchain 文件完全指南交叉编译工具链与平台文件配置实战 导读 本文基于 F´飞行软件与嵌入式系统框架官方用户指南中的 CMak嵌入式系统编程Wireshark CMake工具链交叉编译终极实战指南想要在嵌入式设备上运行强大的网络协议分析工具Wireshark吗 本教程将带你一步步掌握Wireshark的CMake工具链交叉编译技巧让你的网络分析能网络通信上一篇GraphQL Playground实时数据处理订阅实现原理下一篇告别手动API文档gh_mirrors/fr/frontend-stuff 自动化文档生成实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表