Getting the compiler to find a Cmake-created file

六月ゝ 毕业季﹏ 提交于 2019-12-06 06:27:48

Keeping your source tree 'pristine' is right, and not doing so is 'wrong' if you want to do multiple different builds for example, or if you want to be able to clean up a build by rm'ing the build dir (not sufficient if you're generating stuff to the source dir).

Generate it in the build dir and add the include path.

Set the variables

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)

to make the corresponding build dir of each source dir automatically added, and to make that a transitive behavior for other targets to consume (so that foo doesn't have to add the build dir of bar explicitly for example).

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

I don't think there's a standard way to handle this, but from my own limited view of other projects there doesn't really seem to be an overwhelming majority one way or the other. If I was to guess, I'd think that it's more common to place the generated file in the build tree rather than the source tree.

My own preference would be to put it in a subdirectory like ${CMAKE_CURRENT_BINARY_DIR}/GeneratedFiles/config.h for clarity. This avoids all the subdirectories of ${CMAKE_CURRENT_BINARY_DIR} appearing in autocomplete lists of IDEs like Visual Studio. It also keeps your build root a bit cleaner, particularly if you end up with several generated files. You'd have to create the directory first:

set(GeneratedFilesDir "${CMAKE_CURRENT_BINARY_DIR}/GeneratedFiles")
file(MAKE_DIRECTORY ${GeneratedFilesDir})

set(ConfigFile "${GeneratedFilesDir}/config.h")
configure_file(config.h.in ${ConfigFile})


You can then perhaps do a bit more "damage limitation" by using target_include_directories rather than include_directories. For example, if config.h is only used internally by library MyLib, you can do:

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

Unlike using include_directories, this avoids all targets having ${GeneratedFilesDir} as an include path.


Things become more debatable when the generated file needs to be exposed as a public header, or added to an install command. Ultimately, I don't think there's a "wrong" option here. It boils down to whether you feel it's better to keep your source tree pristine at the expense of a more complicated CMake setup or not.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!