Linux下CMake二进制路径传递给C++时路径异常问题排查与解决
问题:Linux下CMake传递路径宏定义时"linux"被替换为"1"
项目目录结构
+-src | +-CMakeLists.txt +-example | +-CMakeLists.txt +-_builds | +-win | | +-src | | +-example | +-linux | | +-src | | +-example +-CMakeLists.txt
相关代码
CMake代码(example/CMakeLists.txt)
target_compile_definitions(vulkan_tutorial PRIVATE EXAMPLE_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR})
C++代码
#define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define GET_EXAMPLE_BIN_DIR() TOSTRING(MYLIB_EXAMPLE_BIN_DIR) std::cout << GET_EXAMPLE_BIN_DIR() << std::endl;
异常现象
Windows环境下可正常输出路径,但Ubuntu虚拟机中,路径中的"linux"被替换为"1",输出为/mnt/hgfs/dev/mylib/_builds/1/example。已确认目录结构无名为1的文件夹,且CMake编译命令中的路径参数正确。
原因分析
linux是CMake的内置布尔变量,当系统为Linux时,它的取值为1。在CMake的target_compile_definitions中,直接使用${CMAKE_CURRENT_BINARY_DIR}展开路径时,路径里的linux会被CMake识别为内置变量并替换成它的取值1。而Windows下路径中的win不是CMake内置变量,所以不会被替换,因此正常工作。
另外注意:C++代码中使用的宏是MYLIB_EXAMPLE_BIN_DIR,但CMake定义的是EXAMPLE_BIN_DIR,两者名称不匹配,虽然Windows下能输出可能是笔误,但建议统一名称避免后续问题。
解决方法
方法一:给编译定义项加双引号
将CMake代码修改为:
target_compile_definitions(vulkan_tutorial PRIVATE "EXAMPLE_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR}")
用双引号包裹整个定义项后,CMake会把${CMAKE_CURRENT_BINARY_DIR}的展开值当作完整的字符串字面量,不会解析其中的linux作为内置变量。
方法二:统一宏定义名称
将C++代码中的MYLIB_EXAMPLE_BIN_DIR改为EXAMPLE_BIN_DIR,和CMake中的定义保持一致:
#define GET_EXAMPLE_BIN_DIR() TOSTRING(EXAMPLE_BIN_DIR)
内容的提问来源于stack exchange,提问作者Khardan
相关产品推荐
相关产品推荐

