CMake使用make与ninja构建时__FILE__宏路径不一致如何解决
差异原因
这个差异是不同CMake生成器传递源文件路径的规则不同导致的:
- Makefile生成器默认会把源文件的绝对路径传给编译器
- Ninja生成器默认会传递相对于构建目录的相对路径
__FILE__宏的输出内容完全由编译器接收到的源文件路径决定,因此出现了两种不同的结果。
解决方法
方法1:使用CMake内置参数(推荐,CMake 3.20及以上版本适用)
CMake 3.20版本引入了CMAKE_<LANG>_COMPILER_PASSES_FULL_PATH参数,开启后会强制所有生成器都向编译器传递源文件的绝对路径,直接统一两种构建工具的行为。
在你的CMakeLists.txt中添加如下配置即可:
cmake_minimum_required(VERSION 3.10) project(file_test) # 新增以下行,开启C++源文件绝对路径传递 set(CMAKE_CXX_COMPILER_PASSES_FULL_PATH ON) # 如果项目包含C语言代码,同时添加以下行 # set(CMAKE_C_COMPILER_PASSES_FULL_PATH ON) add_executable(app main.cpp)
方法2:编译器前缀替换(适用于CMake 3.20以下版本,GCC/Clang编译器)
如果你的CMake版本低于3.20,可以通过编译器的-ffile-prefix-map参数,将编译时传入的相对路径强制替换为源码目录的绝对路径,配置如下:
cmake_minimum_required(VERSION 3.10) project(file_test) # 针对Ninja生成器添加路径替换编译选项 if(CMAKE_GENERATOR STREQUAL "Ninja") target_compile_options(app PRIVATE -ffile-prefix-map=${CMAKE_CURRENT_BINARY_DIR}/../=${CMAKE_CURRENT_SOURCE_DIR}/ ) endif() add_executable(app main.cpp)
上述配置仅针对Ninja构建生效,不会影响Makefile构建的原有行为。
修改配置后删除原有build目录内容,重新执行cmake -GNinja ..、ninja构建,运行app即可看到__FILE__输出绝对路径,和Make构建结果完全一致。
内容的提问来源于stack exchange,提问作者user888379
相关产品推荐
相关产品推荐

