【问题标题】:__FILE__ gives different result when built with CMake/ninja than when built with CMake/make__FILE__ 在使用 CMake/ninja 构建时与使用 CMake/make 构建时给出不同的结果
【发布时间】:2021-12-19 03:15:56
【问题描述】:

__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 构建的行为方式相同?

【问题讨论】:

  • 您的问题的答案是:是的。 (可能__FILE__ 设置为作为参数传递给编译器以编译源文件的任何内容。)
  • 显然我问错了问题。为什么 cmake 会创建向编译器提供不同参数的构建文件?
  • 为什么不呢?编译器必须能够找到要编译的文件。因此,(以及许多其他应用程序)您可以选择相对或绝对文件路径。看来你不能依赖任何东西。 - 我曾经注意到我在 VS2013 中使用 x86 获得绝对文件路径,而使用 x64 获得相对文件路径(反之亦然)。 (或者是VS2008?这是不久前。我忘了...);-)
  • 如果您确实需要绝对或相对文件路径,您可能需要添加一些额外的操作(也许,甚至在应用程序本身的自定义代码中)。您可以传递源代码文件目录。作为一个宏(由您自己在构建脚本的命令行中定义)并处理__FILE__ 和该宏,以便在必要时将一个转换为另一个。 std::filesystem 肯定会有所帮助。 AFAIR,你甚至不能指望规范化的文件路径,即我曾经在我的例如“蹦床”路径中看到过。类似./src/../build/file.cc。但是,再次:使用std::filesystem 轻松修复...

标签: c++ cmake c-preprocessor ninja


【解决方案1】:

有没有人知道如何让 ninja 构建的行为与 make 构建的行为方式相同?

使用 CMake 3.21,来自3.21 release notes

Ninja 生成器现在使用绝对路径将源文件和包含目录传递给编译器。这使得诊断消息和调试符号更加一致,并且与 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__

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-15
    • 2019-03-16
    • 2014-04-22
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    相关资源
    最近更新 更多