如何创建依赖于外部头文件的cmake header-only库?

X. *_*Liu 12 c++ cmake

我有一个具有以下文件结构的项目:

project
 |
 |-------> lib1
 |           |----> lib1.h
 |
 |-------> lib2
 |           |----> lib2.h
 |
 |-------> main.cc
Run Code Online (Sandbox Code Playgroud)

这两个库lib1,并lib2只包含头文件,同时lib2.h包括lib1.h,和main.cc包括lib2.h.

我现在如何为这个项目编写cmake文件?我试图创建一个接口库lib2,但是编译器无法找到lib1.h.以下是我的cmake文件的内容:

lib2的CMakeLists.txt:

add_library(lib2 INTERFACE)
target_sources(lib2 INTERFACE lib2.h)
target_include_directories(lib2 INTERFACE ../lib1/lib1.h)
Run Code Online (Sandbox Code Playgroud)

整个项目的CMakeLists.txt:

add_executable(project main.cc)
target_link_libraries(project lib2)
Run Code Online (Sandbox Code Playgroud)

cmake文件中有什么问题?

was*_*ful 19

如评论中所述,target_include_directories应该给出目录的路径,而不是文件.

此外,如果要为lib2on 创建依赖项lib1,则应该通过target_link_libraries以下方式执行:依赖项不仅包括目录,还包括编译选项,定义,目标属性......

target_sources不适用于接口库.从这个答案中,您可以使用没有命令的自定义目标将源关联到目标而不影响构建过程(对于msvc,QtCreator和其他基于GUI的工具,这使得可以通过IDE访问源; AFAIK对其他无用)构建工具).

您的cmake可能如下所示:

add_library(lib1 INTERFACE)
target_sources(lib1 INTERFACE lib1.h)

target_include_directories(lib1 INTERFACE
    "${PROJECT_SOURCE_DIR}/lib1"
)

add_library(lib2 INTERFACE)
if(MSVC)
    add_custom_target(lib2.headers SOURCES lib2.h)
endif()

target_include_directories(lib2 INTERFACE
    "${PROJECT_SOURCE_DIR}/lib2"
)

target_link_libraries(lib2 INTERFACE lib1)

add_executable(project main.cc)
target_link_libraries(project lib2)
Run Code Online (Sandbox Code Playgroud)

高级提示:您可以target_include_directories为构建树和安装树指定其他目录(请参阅文档):

target_include_directories(lib1 INTERFACE
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/lib1>
    $<INSTALL_INTERFACE:${YOUR_INSTALL_DIR}/lib1>
)
Run Code Online (Sandbox Code Playgroud)

  • `target_sources` 不应该被需要,因为 target 是“INTERFACE”类型,并且不是自己编译的。将源直接传递给 `add_library` 甚至会出现以下错误:`add_library INTERFACE library requires no source arguments.` (2认同)

Mic*_*cki 5

我使用空_only_for_compiling_the_lib.cpp文件作为最简单、最快的解决方法,但显然强烈建议使用上述解决方案。

我根本不知道INTERFACE关键字。