CMake:包含生成文件的仅标头库

时间:2015-02-10 00:15:21

标签: cmake header-only

我有一个库需要携带一些从非源文件内容中注入的常量数据(在本例中为OpenGL着色器代码)。为此,我使用add_custom_command()生成包含文件,然后我可以#include到我的代码中来初始化const静态变量。

这与常规库(静态或共享)完美配合,但现在我想使我的库只有标题库。 C ++允许静态方法返回静态数据而不会冒着在每个翻译单元中复制数据的风险的能力(" magic statics")使这成为可能。

问题是,CMake似乎假设INTERFACE库(我用来创建仅限标题库的CMake功能)不需要构建 - 在这种情况下,这是错误的。

(我意识到我的库没有实际的义务是仅限标题。在这种特殊情况下,我想要的原因是我希望那个做OpenGL的库保持独立于任何特定的绑定库[例如GLEWGLee或新成员glbinding]。通过保留我的库标题,我可以将该选择留给用户 - 他需要做的就是{ {1}}我之前绑定库的标题。)

是否有人看到让CMake触发生成标题的自定义命令的方法,最迟在构建消费者项目时?

编辑:我刚刚意识到我可以拥有两个世界中最好的"因为它保持我的库静态,但仍保留我的所有代码除了以获取头文件中的常量数据。这样,仍然不需要选择特定的OpenGL绑定库。 但是,将库设置为仅限标题仍然具有优势 - 使用简单 - 所以我将问题保持打开状态。

编辑#2:这是我的#include文件的相关部分(我只删除了库依赖项 - 所有标题 - 从最后开始):

CMakeLists.txt

3 个答案:

答案 0 :(得分:3)

您可以在CMake 3.1中使用target_sources告诉使用者编译接口文件:

add_library(source_only INTERFACE)
target_sources(source_only INTERFACE foo.cpp) 

http://www.cmake.org/cmake/help/v3.1/command/target_sources.html

答案 1 :(得分:3)

使用标题创建一个静态库作为唯一的源代码。当然,这只是一种解决方法。

  • 创建仅包含头文件的静态库会导致空库。我说!<arch>是唯一的内容。
  • CMake将自动在子目录中获取正确的依赖关系。
  • 由于所有源都是标头,因此您需要告诉CMake应该使用哪种链接器语言。

代码:

set(OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated_include")
add_custom_command(
    OUTPUT "${OUTDIR}/outfile.h"
    # Replace the next two lines with a proper generating script.
    COMMAND mkdir -p ${OUTDIR}
    COMMAND touch ${OUTDIR}/outfile.h
)

# Note, I am only adding header files to the library.
add_library(generated-headers STATIC 
    "${OUTDIR}/outfile.h"
)
set_target_properties(generated-headers
    PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(generated-headers PUBLIC ${OUTDIR})

在其他目录中使用:

# In any other directory of the same CMake project:
add_executable(main main.cpp)
target_link_libraries(main generated-headers)

在CMake 3.2,3.8和3.9上测试。使用Ninja和Make生成器。

答案 2 :(得分:1)

我在尝试使用高兴时遇到了类似的问题:https://github.com/Dav1dde/glad

它使用自定义CMake命令来构建绑定,这意味着您需要包含在项目中的文件使用很高兴不存在,这样CMake就不会构建高兴(这将创建这些文件)... < / p>

我还没有尝试过,但以下链接的示例3似乎是一个很好的解决方案,我相信它可能适用于您的情况: https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/