2014-09-25 195 views
2

我在Cmake中使用configure_file命令进行功能可用性检查,如on this page所述。这页建议使用的命令是这样的:让编译器找到Cmake创建的文件

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的使用方法。

+0

对于出源的构建,添加'include_directories($ {CMAKE_CURRENT_BINARY_DIR})'。 – 2014-09-25 03:40:45

回答

6

保持你的源代码树'原始'是正确的,而不是'错误'如果你想做多个不同的构建,或者如果你想能够清理构建通过rm'ing构建目录(如果你正在向源目录生成东西,则不够用)。

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

设置变量

set(CMAKE_INCLUDE_CURRENT_DIR ON) 
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) 

使自动添加每个源目录对应的build目录,并做出对其他目标的传递行为,消费(这样foo没有添加例如明确指定bar的目录)。

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

3

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

为了清楚起见,我自己的选择是把它放在一个像${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安装为代价。