如何设置 CMake 以生成仅标头项目

How do I set up CMake to generate header-only projects?

本文关键字:项目 CMake 何设置 设置      更新时间:2023-10-16

我想设置仅标头C++(或 C)库项目,但找不到干净的方法。

经过一些搜索,我发现您无法使用add_library来设置普通库,因为它需要可编译的源文件。执行此操作的一种方法是改用add_custom_target,方式如下:

# Get all headers (using search instead of explicit filenames for the example)
file( GLOB_RECURSE XSD_HEADERS 
    *.hxx
)
add_custom_target( libsxsd SOURCES ${XSD_HEADERS} )

但这似乎在这里并不完全有效,因为我看不到VS2010中生成的项目中的源代码。我不知道这是一个错误,还是我做错了,或者是否有首选的方法可以做到这一点。

更新:CMake 将很快包含一个名为 INTERFACE 的库目标,非常适合仅标头项目。此功能当前位于主分支中。参考。

按照您的建议使用命令add_custom_target对我有用(VS2010)。这些文件在我的项目中整齐地列出,但它的缺点是您无法使用自定义目标定义任何"其他包含目录"。相反,我现在使用以下方法:

add_library(HEADER_ONLY_TARGET STATIC test1.hpp test2.hpp)
set_target_properties(HEADER_ONLY_TARGET PROPERTIES LINKER_LANGUAGE CXX)

这会将仅标头项目设置为虚拟存档目标。别担心,如果你尝试构建它,不会生成实际的二进制文件(至少在VS2010和Xcode 4中不会)。命令set_target_properties之所以存在,是因为 CMake 会抱怨它无法仅从 .hpp 文件推断目标语言。

您可以使用最近的接口库功能执行此操作:

add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE my_include_dir1 my_include_dir2)

这将创建一个没有任何源文件的库目标,并将包含目录添加到目标的 INTERFACE_INCLUDE_DIRECTORIES 属性中。这意味着任何链接到此库的目标在构建时都将获得这些目录作为包含路径(-I)。

例如,要将库与可执行目标一起使用,只需执行以下操作:

add_executable(myexec ${MY_SOURCES})
target_link_libraries(myexec mylib)

我认为您正在寻找的只是使用cmake的"include_directories"命令。

执行此操作时,如果它是您无法控制的第三方工具,我还会添加"SYSTEM"标志。

所以你的命令看起来像这样:

include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})