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

问题描述 投票:8回答:3

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

project
 |
 |-------> lib1
 |           |----> lib1.h
 |
 |-------> lib2
 |           |----> lib2.h
 |
 |-------> main.cc

两个库lib1lib2只包含头文件,而lib2.h包含lib1.h,而main.cc包含lib2.h

我现在如何为这个项目编写cmake文件?我试图为interface library创建一个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)

整个项目的CMakeLists.txt:

add_executable(project main.cc)
target_link_libraries(project lib2)

cmake文件中有什么问题?

c++ cmake
3个回答
16
投票

如评论中所述,target_include_directories应该被赋予目录的路径,而不是文件。

此外,如果你想在lib2上为lib1创建一个依赖项,你应该通过target_link_libraries来实现:依赖项不仅包括目录,还包括编译选项,定义,目标属性......

target_sources不适用于接口库。从this answer,您可以使用没有命令的自定义目标将源关联到目标而不影响构建过程(对于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)

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

target_include_directories(lib1 INTERFACE
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/lib1>
    $<INSTALL_INTERFACE:${YOUR_INSTALL_DIR}/lib1>
)

1
投票

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

我根本不知道INTERFACE关键字。


0
投票

此问题是由INTERFACE库文件的完整路径问题引起的,该问题已在cmake 3.13版中得到修复。

欲了解更多信息:https://gitlab.kitware.com/cmake/cmake/issues/17556

此页面还包含一个更好理解的示例。

© www.soinside.com 2019 - 2024. All rights reserved.