CMake中WIN32和CMAKE_HOST_WIN32的使用差异
在 CMake 中,WIN32
和 CMAKE_HOST_WIN32
是两个完全不同的变量,其作用域和用途有本质区别。它们是否受 CMAKE_SYSTEM_NAME
影响也截然不同。
如果是想判断cmake运行在什么主机系统上,建议使用CMAKE_HOST_WIN32
排除干扰!
以下是详细解析:
📌 核心区别
变量 | 作用域 | 含义 | 何时定义 |
---|---|---|---|
WIN32 | 目标平台 | 表示 当前构建的目标系统是否为 Windows(包括 Win32/UWP) | 在 project() 命令执行后自动设置 |
CMAKE_HOST_WIN32 | 构建主机 | 表示 运行 CMake 的主机系统是否为 Windows(与目标系统无关) | CMake 启动时自动检测 |
🔧 关键行为分析
1. WIN32
的行为
- 依赖
CMAKE_SYSTEM_NAME
:
当显式设置CMAKE_SYSTEM_NAME
时(如set(CMAKE_SYSTEM_NAME Generic)
),WIN32
的值会被覆盖:set(CMAKE_SYSTEM_NAME Generic) # 强制目标系统为 Generic project(MyProject) if(WIN32) # 此时为 FALSE!因为目标系统被设为 Generic
- 典型用途:
在CMakeLists.txt
中判断编译产物的运行平台:add_executable(my_app main.cpp) if(WIN32)target_sources(my_app PRIVATE win_compat.cpp) # 仅 Windows 目标添加特殊源码 endif()
2. CMAKE_HOST_WIN32
的行为
- 完全独立于
CMAKE_SYSTEM_NAME
:
即使设置CMAKE_SYSTEM_NAME=Linux
,只要主机是 Windows,该变量仍为TRUE
:set(CMAKE_SYSTEM_NAME Linux) # 交叉编译到 Linux if(CMAKE_HOST_WIN32) # 在 Windows 主机上运行 CMake 时为 TRUEmessage("CMake is running on Windows!") endif()
- 典型用途:
在脚本级逻辑中判断当前 CMake 的运行环境:if(CMAKE_HOST_WIN32)set(TOOL_PATH "C:/tools/bin") # Windows 主机工具路径 else()set(TOOL_PATH "/opt/tools/bin") endif()
⚠️ 受 CMAKE_SYSTEM_NAME Generic
的影响对比
变量 | 是否受 Generic 影响 | 原因 |
---|---|---|
WIN32 | ✅ 是 | Generic 显式声明目标系统非 Windows,覆盖默认检测 |
CMAKE_HOST_WIN32 | ❌ 否 | 主机系统是物理事实,与目标系统无关 |
🛠️ 实际案例演示
场景:交叉编译到嵌入式设备(目标系统 Generic
)
cmake_minimum_required(VERSION 3.20)
set(CMAKE_SYSTEM_NAME Generic) # 目标系统设为 Genericproject(EmbeddedApp)message("WIN32 = ${WIN32}") # 输出:WIN32 =
message("CMAKE_HOST_WIN32 = ${CMAKE_HOST_WIN32}") # 输出:CMAKE_HOST_WIN32 = 1 (若主机是 Windows)if(CMAKE_HOST_WIN32)# 主机是 Windows:设置 Windows 专用工具链set(CMAKE_C_COMPILER "arm-none-eabi-gcc.exe")
else()set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
endif()if(WIN32)# 此代码块不会执行!因为目标系统不是 Windowsmessage(FATAL_ERROR "This should not happen!")
endif()
💎 总结:选择正确的变量
你需要判断 | 应使用的变量 | 示例场景 |
---|---|---|
编译后的程序是否在 Windows 运行? | WIN32 | 添加 Windows API 依赖、.rc 资源文件 |
CMake 脚本当前是否在 Windows 执行? | CMAKE_HOST_WIN32 | 设置主机工具路径、处理路径分隔符 \ vs / |
✅ 黄金法则:
- 目标平台 →
WIN32
- 构建主机 →
CMAKE_HOST_WIN32
- 显式设置
CMAKE_SYSTEM_NAME=Generic
会破坏WIN32
的自动检测(需手动处理平台逻辑)。