【问题标题】:Getting the compiler to find a Cmake-created file让编译器找到 Cmake 创建的文件
【发布时间】:2014-09-25 02:45:15
【问题描述】:

我在 Cmake 中使用configure_file 命令进行功能可用性检查,如on this page 所述。该页面建议使用如下命令:

configure_file(config.h.in config.h)

这会将${CMAKE_CURRENT_SOURCE_DIR}/config.h.in 转换为${CMAKE_CURRENT_BINARY_DIR}/config.h。但是当我编译我的程序时,编译器只在${CMAKE_CURRENT_SOURCE_DIR} 中查找标题(例如config.h),而不是${CMAKE_CURRENT_BINARY_DIR}。所以很自然,编译器找不到config.h生成它的位置,构建失败。

解决此问题的标准方法是什么?我是否应该更改CMakeLists.txt 以便在源目录中创建config.h?还是应该更改它以将构建目录添加到包含路径? (真的,为什么我必须手动处理这个问题?[半反问])

This question 关注类似的问题,但建议将这两个选项作为可能的解决方案;我想知道是否有标准做法,或者这是否表明我遗漏了有关如何使用 Cmake 的内容。

【问题讨论】:

  • 对于源外构建,添加include_directories(${CMAKE_CURRENT_BINARY_DIR})

标签: c path cmake out-of-source


【解决方案1】:

保持你的源代码树“原始”是正确的,如果你想进行多个不同的构建,或者如果你希望能够通过 rm'ing 构建来清理一个构建,那么不这样做是“错误的” dir(如果你要生成东西到源目录,这还不够)。

在构建目录中生成它并添加包含路径。

设置变量

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)

自动添加每个源目录的相应构建目录,并使其成为其他目标使用的传递行为(例如,foo 不必显式添加 bar 的构建目录)。

http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#build-specification-and-usage-requirements

【讨论】:

    【解决方案2】:

    我不认为有一个标准的方法来处理这个问题,但从我自己对其他项目的有限看法来看,似乎并没有一种方法占绝大多数。如果我猜的话,我认为将生成的文件放在构建树而不是源树中更为常见。

    为了清楚起见,我自己的偏好是将它放在像${CMAKE_CURRENT_BINARY_DIR}/GeneratedFiles/config.h 这样的子目录中。这样可以避免 ${CMAKE_CURRENT_BINARY_DIR} 的所有子目录出现在 Visual Studio 等 IDE 的自动完成列表中。它还可以使您的构建根目录更加干净,特别是在您最终生成多个文件的情况下。您必须先创建目录:

    set(GeneratedFilesDir "${CMAKE_CURRENT_BINARY_DIR}/GeneratedFiles")
    file(MAKE_DIRECTORY ${GeneratedFilesDir})
    
    set(ConfigFile "${GeneratedFilesDir}/config.h")
    configure_file(config.h.in ${ConfigFile})
    


    然后,您也许可以通过使用target_include_directories 而不是include_directories 来做更多的“伤害限制”。例如,如果 config.h 仅由库 MyLib 内部使用,您可以这样做:

    add_library(MyLib ${ConfigFile} ... other sources ...)
    target_include_directories(MyLib
        PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${GeneratedFilesDir}
        PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
    

    与使用include_directories 不同,这可以避免所有目标都将${GeneratedFilesDir} 作为包含路径。


    当生成的文件需要作为公共标头公开或添加到install 命令时,事情变得更具争议性。最终,我认为这里没有“错误”的选择。这归结为您是否觉得以更复杂的 CMake 设置为代价来保持源代码树的原始状态更好。

    【讨论】:

      猜你喜欢
      • 2015-06-27
      • 1970-01-01
      • 2015-10-15
      • 1970-01-01
      • 2016-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多