让编译器找到Cmake创建的文件

我正在使用Cmake中的configure_file命令进行function可用性检查,如本页所述 。 该页面建议使用如下命令:

 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创建config.h吗? 或者我应该更改它以将构建目录添加到包含路径? (实际上,为什么我必须手动处理这个问题?[半修辞问题])

这个问题涉及类似的问题,但建议两种方案作为可能的解决方案; 我想知道是否有一个标准的做法,或者这是否表明我错过了一些关于如何使用Cmake的内容。

保持你的源代码树’原始’是正确的,如果你想做多个不同的构建,或者如果你想通过rm的构建目录来清理构建,那么不这样做是’错误的’如果您正在为源代码生成内容,那就足够了。

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

设置变量

 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

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

为了清楚起见,我自己的偏好是将它放在像${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设置为代价保持你的源树原始状态。