CMake基础:常用内部变量和环境变量的引用

CMake基础:常用内部变量和环境变量的引用 目录1.常用 CMake 变量1.1.编译与构建控制1.2.路径与目录变量1.3.项目信息变量1.4.系统与平台变量1.5.工具链与交叉编译1.6.测试与安装变量1.7.高级编译选项2.常用环境变量2.1.编译器与工具链2.2.依赖库路径2.3.CMake 专用环境变量2.4.系统环境变量Path3.变量与环境变量的区别4.变量引用实践5.常见问题排查6.查看所有内部变量相关链接1.常用 CMake 变量1.1.编译与构建控制CMAKE_BUILD_TYPE构建类型Debug、Release、RelWithDebInfo、MinSizeRel影响优化和调试选项。CMAKE_C_COMPILER/CMAKE_CXX_COMPILER指定 C/C 编译器路径如gcc、clang。CMAKE_C_FLAGS/CMAKE_CXX_FLAGS全局 C/C 编译选项如-Wall、-stdc17。CMAKE_EXE_LINKER_FLAGS可执行文件链接选项如-lpthread。CMAKE_C_STANDARD/CMAKE_CXX_STANDARD指定 C/C 语言标准版本如11、17。CMAKE_C_STANDARD_REQUIRED强制要求编译器支持指定的 C 标准布尔值。引用示例# 根据构建类型设置编译选项 if(CMAKE_BUILD_TYPE STREQUAL Debug) set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g -O0) endif() # 指定 C 标准 set(CMAKE_CXX_STANDARD 20)1.2.路径与目录变量CMAKE_SOURCE_DIR项目源文件根目录的绝对路径。CMAKE_BINARY_DIR构建输出目录的绝对路径外建模式下为独立目录。PROJECT_SOURCE_DIR当前project()命令指定的源目录多项目时区分子项目。CMAKE_INSTALL_PREFIX安装目标路径默认/usr/local可修改为./install等。CMAKE_MODULE_PATHCMake 模块.cmake文件的搜索路径用于find_package或include。CMAKE_CURRENT_SOURCE_DIR当前处理的 CMakeLists.txt 所在的源目录。CMAKE_CURRENT_BINARY_DIR前处理的 CMakeLists.txt 对应的构建目录。CMAKE_CURRENT_SOURCE_DIR(当前处理的CMakeLists.txt所在的源码绝对目录)CMAKE_CURRENT_LIST_DIR(当前执行的任意 CMake 脚本.cmake 或 .txt所在绝对目录)引用示例# 添加源文件 add_executable(my_app ${CMAKE_SOURCE_DIR}/src/main.cpp) # 设置库输出目录 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)cmake_minimum_required(VERSION 3.20) project(cmake_var_demo LANGUAGES CXX) # 设置 C 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 第一步未 include 外部脚本二者等价 message( 未加载外部脚本时 ) message(主 CMake 中 LIST_DIR: ${CMAKE_CURRENT_LIST_DIR}) # 指向 cmake_var_demo/ message(主 CMake 中 SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR})# 指向 cmake_var_demo/ message( 分割线 \n) # 第二步include 工具脚本差异显现 # 加载 cmake/utils.cmake 脚本用 LIST_DIR 定位脚本路径 include(${CMAKE_CURRENT_LIST_DIR}/cmake/utils.cmake) # 第三步使用自定义模块测试 LIST_DIR 在模块中的用法 message( 加载自定义模块 ) # 指定自定义模块目录用 LIST_DIR 定位 modules 目录 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/cmake/modules) # 查找自定义模块触发 FindTestLib.cmake 执行 find_package(TestLib REQUIRED) message( 分割线 \n) # 第四步构建项目实际业务逻辑 # 添加可执行文件用 SOURCE_DIR 定位源码目录语义更清晰 add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp) # 设置头文件目录两种写法均可此处用 SOURCE_DIR 更贴合源码目录语义 target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${TestLib_INCLUDE_DIRS} # 自定义模块返回的头文件目录 ) # 链接自定义模块模拟 if(TestLib_FOUND) message(项目构建成功将链接 TestLib模拟) endif()1.3.项目信息变量PROJECT_NAME项目名称由project()命令定义如project(MyProject)。PROJECT_VERSION项目版本由project()命令指定如project(MyProject VERSION 1.2.3)。PROJECT_VERSION_MAJOR/MINOR/PATCH自动拆分的主 / 次 / 补丁版本号基于PROJECT_VERSION。引用示例# 设置可执行文件版本 set_target_properties(my_app PROPERTIES VERSION ${PROJECT_VERSION})1.4.系统与平台变量CMAKE_SYSTEM_NAME操作系统名称如Linux、Windows、Darwin。CMAKE_SYSTEM_PROCESSOR处理器架构如x86_64、arm64、aarch64。WIN32/UNIX/APPLE布尔变量标识是否为 Windows 或 Unix 类系统APPLE标识 macOS。CMAKE_SIZEOF_VOID_P指针大小用于判断 32 位 / 64 位系统。CMAKE_CXX_PLATFORM_ID: CMake 内置只读变量标识当前 C 编译器所在平台用来区分系统平台。取值只读不能 set 修改。常见值为Windows、Linux、macOS、Android、FreeBSD引用示例# 方式1CXX架构ID if(CMAKE_CXX_ARCHITECTURE_ID STREQUAL X64) message(当前CPUx64) endif() # 方式2跨平台通用写法 if(CMAKE_SYSTEM_PROCESSOR MATCHES x86_64|AMD64) set(CPU_ARCH x64) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES aarch64|arm64) set(CPU_ARCH arm64) else() set(CPU_ARCH x86) endif() message(CPU架构: ${CPU_ARCH}) # 根据平台设置不同的链接库 if(WIN32) target_link_libraries(my_app PRIVATE ws2_32) # Windows 网络库 else() target_link_libraries(my_app PRIVATE pthread) # Unix 线程库 endif()1.5.工具链与交叉编译CMAKE_TOOLCHAIN_FILE工具链文件路径用于交叉编译如arm-linux-gnueabihf.toolchain.cmake。CMAKE_C_COMPILER_FORCED/CMAKE_CXX_COMPILER_FORCED强制指定编译器忽略环境变量和默认搜索。CMAKE_CROSSCOMPILING布尔变量标识是否为交叉编译模式。1.6.测试与安装变量CMAKE_TEST_COMMAND测试执行命令默认ctest可修改为其他测试工具。CMAKE_INSTALL_COMMAND安装命令默认make install对应不同生成器。CMAKE_INSTALL_INCLUDEDIR/LIBDIR安装时头文件 / 库文件的子目录默认include/lib。1.7.高级编译选项CMAKE_EXPORT_COMPILE_COMMANDS布尔变量生成compile_commands.json用于 clangd 等工具。CMAKE_POSITION_INDEPENDENT_CODE布尔变量强制生成位置无关代码PIC用于动态库。CMAKE_CXX_VISIBILITY_PRESET设置符号可见性如hidden减少库暴露符号。2.常用环境变量环境变量在 CMake 中通过$ENV{VAR_NAME}引用常用于传递系统级配置。2.1.编译器与工具链环境变量名描述CCC 编译器如gcc、clangCXXC 编译器如g、clangPATH系统搜索路径影响find_program等命令引用示例# 使用环境变量指定的编译器 if(DEFINED ENV{CC}) set(CMAKE_C_COMPILER $ENV{CC}) endif() # 在 PATH 中查找工具 find_program(CLANG_FORMAT clang-format)2.2.依赖库路径环境变量名描述LD_LIBRARY_PATHLinux 动态库搜索路径DYLD_LIBRARY_PATHmacOS 动态库搜索路径CPATHC/C 头文件搜索路径LIBRARY_PATH静态库搜索路径引用示例# 从环境变量添加头文件搜索路径 include_directories($ENV{CPATH}) # 查找依赖库 find_library(FOO_LIB NAMES foo HINTS $ENV{LD_LIBRARY_PATH})2.3.CMake 专用环境变量环境变量名描述CMAKE_PREFIX_PATHCMake 查找依赖的前缀路径多个路径用;分隔BUILD_TYPE自定义构建类型可替代CMAKE_BUILD_TYPECMAKE_PREFIX_PATH是 CMake 中用于指定依赖包搜索路径的核心变量为find_package()、find_program()、find_library()、find_file()和find_path()等命令提供根搜索目录尤其适用于定位非标准安装路径的第三方库。CMake 按以下顺序查找依赖包优先级从高到低特定包的XXX_DIR变量如OpenCV_DIR— 最高优先级直接指定包配置文件路径CMAKE_PREFIX_PATH— 手动指定的搜索前缀CMAKE_SYSTEM_PREFIX_PATH— 系统默认前缀如/usr/local、/usr、C:\Program FilesPATH 环境变量— 系统可执行文件路径搜索机制CMake 会在每个前缀目录下自动查找标准子目录如bin可执行文件lib/lib64库文件include头文件lib/cmake/XXX包配置文件Config 模式设置方法5 种常用方式1.命令行参数推荐临时生效# Unix/Linux/macOS cmake .. -DCMAKE_PREFIX_PATH/path/to/libA;/path/to/libB # Windows (PowerShell) cmake .. -DCMAKE_PREFIX_PATHC:/path/to/libA;C:/path/to/libB # Windows (Command Prompt) cmake .. -DCMAKE_PREFIX_PATHC:\path\to\libA;C:\path\to\libB2.环境变量全局生效# Unix/Linux/macOS (临时) export CMAKE_PREFIX_PATH/path/to/libA:/path/to/libB # Unix/Linux/macOS (永久添加到 ~/.bashrc 或 ~/.zshrc) echo export CMAKE_PREFIX_PATH/path/to/libA:/path/to/libB ~/.bashrc source ~/.bashrc # Windows (PowerShell 临时) $env:CMAKE_PREFIX_PATH C:\path\to\libA;C:\path\to\libB # Windows (永久通过系统属性设置环境变量) setx CMAKE_PREFIX_PATH C:\path\to\libA;C:\path\to\libB {insert\_element\_4\_} #### 3. CMakeLists.txt 中设置项目级 cmake # 覆盖原有值 set(CMAKE_PREFIX_PATH /path/to/libA;/path/to/libB CACHE PATH My custom prefix path) # 追加路径推荐不影响原有设置 list(APPEND CMAKE_PREFIX_PATH /path/to/new/lib)3.CMake 缓存编辑运行 cmake-gui 或 ccmake 找到 CMAKE_PREFIX_PATH 变量进行编辑 保存并重新配置4.针对特定包的 ROOT 变量3.12# 替代 CMAKE_PREFIX_PATH 的特定包设置 cmake .. -DOpenCV_ROOT/path/to/opencv {insert\_element\_6\_} ### 四、最佳实践与注意事项 1. **路径顺序**越重要的路径越靠前CMake 按顺序搜索找到第一个匹配项即停止 2. **跨平台兼容性** - Unix 系统用冒号 : 分隔路径CMake 内部会自动转换为分号 - Windows 系统用分号 ; 分隔路径避免使用反斜杠 \或用双反斜杠 \\{insert\_element\_7\_} 3. **避免硬编码**优先使用命令行或环境变量设置保持 CMakeLists.txt 通用性 4. **结合 find_package** cmake # 示例查找非标准路径的 Qt set(CMAKE_PREFIX_PATH /opt/Qt5.15.2/5.15.2/gcc_64 CACHE PATH Qt installation path) find_package(Qt5 REQUIRED COMPONENTS Core Widgets)5.本地构建库对于未安装的库可指向其构建目录cmake .. -DCMAKE_PREFIX_PATH/path/to/my_lib/build引用示例# 使用环境变量设置构建类型 if(DEFINED ENV{BUILD_TYPE}) set(CMAKE_BUILD_TYPE $ENV{BUILD_TYPE}) endif() # 从环境变量添加查找路径 list(APPEND CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH})2.4.系统环境变量Path# 将当前项目源码目录下的 dependencies 文件夹追加到系统环境变量 Path 的末尾 set(ENV{Path} $ENV{Path};${CMAKE_CURRENT_SOURCE_DIR}/dependencies)代码片段作用说明set(ENV{Path} ...)CMake 中修改系统环境变量Path的语法ENV表示环境变量$ENV{Path}保留系统原有的Path环境变量值避免覆盖原有配置;Windows 系统下环境变量的路径分隔符Linux 为:${CMAKE_CURRENT_SOURCE_DIR}CMake 内置变量指代当前 CMakeLists.txt 所在的源码目录/dependencies指向项目根目录下的dependencies文件夹用于存放第三方依赖库 / 可执行文件这段代码的目的是让 CMake 构建的项目在运行时能自动加载dependencies文件夹中的第三方动态库如.dll、.so或可执行程序无需手动将依赖路径添加到系统全局的Path中保证项目环境的独立性。我们可以把环境变量分为 3 个层级权限和生命周期完全不同系统全局环境变量你在电脑设置里查的永久生效所有程序都能用修改需要手动配置 / 管理员权限CMake无权、也不会修改它。用户环境变量同样是永久配置CMake 也不会碰。进程临时环境变量CMake 唯一能改的当你运行 CMake 构建项目时系统会单独启动一个 CMake 进程这个进程会复制一份系统的Path给自己用。set(ENV{Path})只是修改这个临时复制的副本仅对当前 CMake 构建过程CMake 启动的子进程比如编译器、生成的程序生效。永久修改系统环境变量的正确方式:Windows此电脑 → 属性 → 高级系统设置 → 环境变量 → 编辑PathLinux/macOS修改~/.bashrc/~/.zshrc配置文件3.变量与环境变量的区别特性CMake 变量环境变量定义方式set(VAR value)系统命令如export VARvalue作用域局部或全局取决于设置方式全局整个 shell 会话引用方式${VAR}$ENV{VAR}典型用途项目内部配置、路径拼接系统级配置、跨项目共享设置4.变量引用实践1.避免硬编码路径# 不推荐 include_directories(/usr/local/include) # 推荐 include_directories(${CMAKE_INSTALL_PREFIX}/include)2.环境变量默认值# 使用环境变量或默认值 set(MY_LIB_PATH $ENV{MY_LIB_PATH} CACHE PATH 自定义库路径) if(NOT MY_LIB_PATH) set(MY_LIB_PATH /usr/local) endif()3.条件编译与平台适配if(WIN32) set(PLATFORM_LIBS ws2_32) elseif(APPLE) set(PLATFORM_LIBS -framework CoreFoundation) else() set(PLATFORM_LIBS pthread) endif() target_link_libraries(my_app PRIVATE ${PLATFORM_LIBS})5.常见问题排查1.变量未定义错误使用message(STATUS VAR ${VAR})打印变量值通过if(DEFINED VAR)检查变量是否存在2.环境变量不生效确保环境变量在运行 CMake 前已设置使用message(STATUS ENV_VAR $ENV{VAR})验证环境变量值3.跨平台差异Windows 环境变量区分大小写Linux/macOS 通常不区分路径分隔符Windows 使用\Unix 使用/CMake 中统一用/6.查看所有内部变量在命令行中运行cmake -L列出所有变量含内部变量。使用cmake-gui并勾选Advanced选项查看完整变量列表。在 CMake 脚本中通过message(STATUS ${VARIABLE_NAME})打印变量值。这些内部变量覆盖了编译、平台适配、路径管理等核心功能合理使用可大幅提升 CMake 脚本的灵活性和可移植性。更多细节可查阅 CMake 官方变量文档。相关链接CMake 官网 CMake - Upgrade Your Software Build SystemCMake 官方文档CMake Tutorial — CMake 4.0.3 DocumentationCMake 源码https://github.com/Kitware/CMakeCMake 源码CMake · GitLab中文版基础介绍: CMake 入门实战 | HaHackwiki: Home · Wiki · CMake / Community · GitLabModern CMake 简体中文版: Introduction · Modern CMake