__FILE__ 使用 CMake/ninja 构建时与使用 CMake/make 构建时给出不同的结果

__FILE__ gives different result when built with CMake/ninja than when built with CMake/make

__FILE__ 给出绝对路径(用 make 构建)或相对路径(用 ninja 构建)。这是一个简单的测试器:

#include <iostream>

int main(int argc, char *argv[]) {
    std::string thisFile = __FILE__;
    std::cout << "thisFile = " << thisFile << "\n";

    return 0;
}

下面是同样简单的 CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)

project(file_test)

add_executable(app main.cpp)

如果我在 build 目录中,我将键入 cmake ..cmake -GNinja ..(我还尝试过明确说明要使用哪个 c++ 编译器-D 命令行参数 - 结果不变。

如果我用 ninja 构建,app 的输出是:

thisFile = ../main.cpp

如果我用 make 构建,app 的输出是:

thisFile = /home/myname/sandbox/cmake/main.cpp

我已经在 Ubuntu 和 Pop!OS 上试过了 - 结果相同。

有谁知道让 ninja 构建的行为与 make 构建相同的方法吗?

Does anyone know of a way to get the ninja build to behave in the same way that the make build does?

使用 CMake 3.21,来自 3.21 release notes:

The Ninja Generators now pass source files and include directories to the compiler using absolute paths. This makes diagnostic messages and debug symbols more consistent, and matches the Makefile Generators.

或者,围绕您的编译器编写包装器脚本。这样的脚本将解析编译器选项并提取源文件路径并将相对路径更改为绝对路径,然后使用绝对路径调用编译器。使用 CMAKE_CXX_COMPILER_LAUNCHER 将该包装器传递给 CMake 以启动您的脚本。

或者,在 CMake 中迭代要编译的每个文件,在 CMake 中使用 get_filename_component 提取该文件的完整路径,然后在该文件上使用 set_source_file_properties 添加 COMPILE_DEFINITION 喜欢 ABSFILE=${the_absolute_path_to_that_file} 并在源文件中使用该编译定义作为完整路径。我认为,可能取决于编译器,您也可以那样覆盖 __FILE__