1 何为跨平台构建

跨平台构建是指:

  • 在一个平台(Build)上生成另一个平台(Host)可运行的程序
  • 有时还涉及为第三个平台(Target)生成代码(如交叉编译器)

1.1 Build、Host、Target 平台

跨平台构建的核心是区分平台角色

角色说明典型示例
Build 平台执行构建工具(如 CMake、Conan、make)的系统Windows 开发机
Host 平台构建出来的程序 要运行的系统Android、iOS、Linux
Target 平台构建出的程序生成的代码将运行在哪(通常是工具链的目标平台通常用于交叉编译器,例如为 iOS 构建一个能生成 ARM64 代码的 Clang

target 是跨平台构建中最不常用但也最容易混淆的角色,它主要用于 构建编译器本身工具链程序 时,指定这些工具将来要生成哪种平台的代码。 或者简单地理解,target 一般只适用与工具链相关的程序

1.2 举例:Visual Studio BuildTools

如安装 Visual Studio BuildTools 后,用 VSCode 扫描工具链可以得到 4 个:

{
    "name": "Visual Studio 生成工具 2022 Release - amd64",
    "visualStudio": "5356875b",
    "visualStudioArchitecture": "x64",
    "isTrusted": true,
    "preferredGenerator": {
      "name": "Visual Studio 17 2022",
      "platform": "x64",
      "toolset": "host=x64"
    }
  },
  {
    "name": "Visual Studio 生成工具 2022 Release - amd64_x86",
    "visualStudio": "5356875b",
    "visualStudioArchitecture": "x64",
    "isTrusted": true,
    "preferredGenerator": {
      "name": "Visual Studio 17 2022",
      "platform": "win32",
      "toolset": "host=x64"
    }
  },
  {
    "name": "Visual Studio 生成工具 2022 Release - x86",
    "visualStudio": "5356875b",
    "visualStudioArchitecture": "x86",
    "isTrusted": true,
    "preferredGenerator": {
      "name": "Visual Studio 17 2022",
      "platform": "win32",
      "toolset": "host=x86"
    }
  },
  {
    "name": "Visual Studio 生成工具 2022 Release - x86_amd64",
    "visualStudio": "5356875b",
    "visualStudioArchitecture": "x86",
    "isTrusted": true,
    "preferredGenerator": {
      "name": "Visual Studio 17 2022",
      "platform": "x64",
      "toolset": "host=x86"
    }
  }

信息整理成如下表格:

配置名称主机平台(Toolset)目标平台(Platform)说明
Visual Studio 生成工具 2022 Release - amd64host=x64platform=x64在 64 位系统上,用 64 位编译器构建 64 位程序(推荐 x64 构建)
Visual Studio 生成工具 2022 Release - amd64_x86host=x64platform=win32在 64 位系统上,用 64 位编译器构建 32 位程序
Visual Studio 生成工具 2022 Release - x86host=x86platform=win32在 32 位工具链环境下构建 32 位程序(已过时,较少使用)
Visual Studio 生成工具 2022 Release - x86_amd64host=x86platform=x64用 32 位工具链构建 64 位程序(交叉编译,用于兼容老工具)

1.3 举例:GCC 的交叉构建流程

我们来看 GCC 交叉编译器的构建三种情况:

  1. 原生构建(Native)

你在 Ubuntu x86_64 上构建 GCC 供自己使用:

buildhosttarget
x86_64-linux-gnux86_64-linux-gnux86_64-linux-gnu
  1. 跨平台应用构建(普通开发者常用)

你在 Ubuntu 上为 ARM Linux 编译一个程序:

buildhosttarget
x86_64-linux-gnuarm-linux-gnueabihfarm-linux-gnueabihf
  1. 跨平台交叉工具链构建(仅工具链作者才需)

你在 Ubuntu 上构建一个 “为 Windows 上运行,并能生成 ARM Linux 程序” 的 GCC 编译器:

buildhosttarget
x86_64-linux-gnux86_64-w64-mingw32arm-linux-gnueabihf

这种场景就用到了 target程序本身不是目标,而是它生成的程序的目标


2 平台三元组(Triplet)与通用模型

在跨平台构建系统(特别是 GNU 工具链、LLVM、CMake 以及 Conan 等工具)中,平台三元组(Triplet) 是一种标准格式,用于明确描述一个目标平台。

基本形式为:

<architecture>-<vendor>-<operating_system>

有时会扩展为四元组,加上 ABI 信息:

<architecture>-<vendor>-<operating_system>-<abi>

这一模型广泛用于描述:

  • 当前系统
  • 编译目标系统(host/target)
  • 工具链适用的系统

2.1 各组成部分解释

部分含义示例
architectureCPU 架构(或 ISA)x86_64, arm, aarch64, mips, riscv64
vendor硬件厂商或平台分发商(常无实际意义)pc, apple, w64, unknown
os操作系统或运行时环境linux, windows, darwin, android, none
abi(可选)ABI 规范、调用约定、C/C++ 运行库gnu, gnueabihf, musl, eabi, msvc

2.2 举例解析

  1. x86_64-pc-linux-gnu

    • x86_64: 64 位 x86 架构
    • pc: 通用 PC 平台
    • linux: 操作系统
    • gnu: GNU ABI(默认运行时)

表示:运行于 GNU/Linux 上的 64 位 PC 平台的程序

  1. arm-none-eabi

    • arm: 32 位 ARM 架构
    • none: 无操作系统(裸机)
    • eabi: ARM Embedded ABI(用于嵌入式)

表示:为裸机嵌入式设备(无 OS)构建的程序

  1. x86_64-w64-mingw32

    • x86_64: 64 位 x86
    • w64: Windows 64-bit
    • mingw32: Windows MinGW 子系统

表示:MinGW 工具链用于构建 Windows x64 应用

  1. aarch64-apple-darwin

    • aarch64: ARM 64 位(苹果 M 系列)
    • apple: Apple 公司
    • darwin: macOS 内核系统

表示:Apple Silicon 上运行的 macOS 程序

2.3 特别说明:ABI 字段

当四元组出现时,ABI 字段表达了运行时细节,比如:

  • gnu:GNU libc
  • musl:轻量级 libc
  • gnueabihf:GNU EABI,支持硬件浮点
  • eabi:嵌入式 ARM 的 ABI
  • msvc:Microsoft Visual C++ ABI

2.4 在各工具链中的使用场景

工具用途使用方式
GCC / Clang指定编译目标--target=arm-none-eabi
CMake设置交叉编译CMAKE_SYSTEM_NAME, 自定义 toolchain 中设定
Conan精确控制构建三元组在 profile 中设置 os/arch/compiler
vcpkgtriplet 配置包平台x64-windows, arm64-linux
Rust目标平台rustup target add riscv64gc-unknown-elf
Go编译环境变量GOOS=linux GOARCH=arm

3 CMake 中的跨平台构建原理

3.1 默认行为(原生构建)

在默认情况下,CMake 假设:

  • Build = Host = Target
  • 使用本机编译器(如 cl, gcc, clang

3.2 跨平台/交叉构建时,必须指定:

  1. Toolchain 文件(最关键!)
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake ..
  1. 目标平台设置(以变量控制)
CMake 变量用途示例
CMAKE_SYSTEM_NAME目标操作系统Linux, Windows, Android
CMAKE_SYSTEM_PROCESSOR目标架构armv7, x86_64, aarch64
CMAKE_C_COMPILER, CMAKE_CXX_COMPILER交叉编译器路径/usr/bin/arm-linux-gnueabihf-gcc
CMAKE_FIND_ROOT_PATH交叉编译头文件、库搜索路径/opt/arm-sysroot/
CMAKE_SYSROOT设置目标系统根目录/opt/sysroot/arm-linux

3.3 一个典型的 toolchain-arm-linux.cmake

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
 
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
 
set(CMAKE_SYSROOT /opt/arm-sysroot)
set(CMAKE_FIND_ROOT_PATH /opt/arm-sysroot)
 
# 只在目标路径中查找 include/lib
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

4 Conan 中的跨平台构建设置

Conan 通过 .profile 文件(或 settings.yml)建模平台三角色:

Conan 设置项含义对应 CMake
os_build / arch_build构建机平台(本机)无直接变量,CMake 自动检测
os / arch目标平台(Host)CMAKE_SYSTEM_NAME, CMAKE_SYSTEM_PROCESSOR
compiler, version, libcxx, cppstd编译器配置CMAKE_C_COMPILER, CMAKE_CXX_COMPILER
build_type构建类型CMAKE_BUILD_TYPE
os_target, arch_target仅用于工具链构建的目标平台CMake 很少使用(除非构建编译器本身)

4.1 示例 Conan Profile:

[settings]
os=Android
arch=armv8
compiler=clang
compiler.version=14
compiler.libcxx=libc++
build_type=Release
 
[env]
CONAN_CMAKE_TOOLCHAIN_FILE=/path/to/android.toolchain.cmake

Conan 可以自动生成 toolchain 文件并传递给 CMake。


5 CMake + Conan 联合使用时的流程

  1. Conan 读取 profile,解析 os/arch/compiler 等设置

  2. Conan 根据目标平台生成一个 CMake toolchain file(如 conan_toolchain.cmake

  3. CMake 使用这个 toolchain 文件设置交叉构建参数

  4. 项目使用正确的交叉编译器与 sysroot 构建出目标平台可运行的程序


6 CMake 与 Conan 的概念对照表

语义ConanCMake
构建平台os_build, arch_build自动检测(不需配置)
运行目标平台os, archCMAKE_SYSTEM_NAME, CMAKE_SYSTEM_PROCESSOR
工具链配置compiler, version, libcxxCMAKE_C_COMPILER, CMAKE_CXX_COMPILER, toolchain 文件
构建类型build_typeCMAKE_BUILD_TYPE
C++ 标准compiler.cppstdCMAKE_CXX_STANDARD
系统根路径CMAKE_SYSROOT, CMAKE_FIND_ROOT_PATH
动态库选择(libcxx)libstdc++, libc++, etc.与编译器默认相关

7 CMake 跨平台构建典型用例

7.1 Windows → Linux ARM 交叉编译:

  • 使用 MinGW-w64 或 ARM Linux 工具链
  • 编写 toolchain-arm.cmake 并使用 -DCMAKE_TOOLCHAIN_FILE

7.2 Linux → Android/iOS 交叉构建:

  • 配合 Android NDK / Xcode SDK
  • 使用官方提供的 CMake toolchain 文件

7.3 Windows → Emscripten(WebAssembly)

emcmake cmake -B build -DCMAKE_BUILD_TYPE=Release .

Emscripten 提供了自己的 emcmaketoolchain 文件。


8 小结

内容CMake 实现Conan 设置
设置目标平台CMAKE_SYSTEM_NAME, PROCESSORos, arch
指定交叉编译器CMAKE_C_COMPILER, etc.compiler, version
设置头文件/库路径CMAKE_SYSROOT, FIND_ROOT_PATHenv + toolchain 文件
控制构建类型/标准CMAKE_BUILD_TYPE, CXX_STANDARDbuild_type, cppstd

跨平台构建的核心在于明确平台角色,并为 CMake 配置合适的交叉工具链。Conan 的 profile 只是围绕 CMake 的变量做了一层抽象包装,最终还得通过 toolchain.cmake 执行构建。