如何在CMake的install(CODE)段获取项目根目录?
在CMake install(CODE)中获取项目根目录的问题与解决方法
你的问题不是CMake的bug,是对install(CODE)的执行时机和变量作用域理解有误。
问题根源
install(CODE)中的代码逻辑是在安装阶段(执行cmake --install命令时)才会运行,而非配置阶段(执行cmake ..时)。你用[[ ]]包裹的是CMake原始字符串字面量,里面的${PROJECT_SOURCE_DIR}不会在配置阶段被解析替换,要等到安装阶段执行这段代码时才会去查找变量。
但在安装阶段,CMake是在构建目录下启动的,此时没有重新执行project()命令,因此PROJECT_SOURCE_DIR未被初始化(输出为空);而CMAKE_SOURCE_DIR会被设置为当前CMake进程的工作目录(也就是你的构建目录/project_root/build/config_type_dir),这就导致了输出不符合预期。
解决方案
有两种可靠的方式可以获取到项目根目录:
方案1:配置阶段提前展开变量值
放弃使用[[ ]]原始字符串,改用双引号包裹install(CODE)的内容,这样CMake会在配置阶段就将${PROJECT_SOURCE_DIR}这类变量替换为实际路径,安装阶段执行时直接输出已解析好的路径:
cmake_minimum_required(VERSION 3.22) project(myProject CXX) ... install(CODE " message(STATUS \"PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}\") message(STATUS \"CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}\") message(STATUS \"CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}\") ")
方案2:缓存项目根目录变量
在配置阶段将项目根目录存入一个内部缓存变量,这样安装阶段的代码就能直接读取这个预定义好的变量值:
cmake_minimum_required(VERSION 3.22) project(myProject CXX) # 将项目根目录存入内部缓存,供安装阶段访问 set(MY_PROJECT_ROOT "${PROJECT_SOURCE_DIR}" CACHE INTERNAL "Root directory of the project") ... install(CODE [[ message(STATUS "PROJECT_ROOT_DIR: ${MY_PROJECT_ROOT}") message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}") ]])
效果验证
执行cmake --install后,两种方案都能正确输出项目根目录/project_root。
内容的提问来源于stack exchange,提问作者Hardwired
相关产品推荐
相关产品推荐

