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

时间:2016-10-06 04:08:32

标签: c++ cmake

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

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

两个图书馆lib1lib2仅包含标题文件,而lib2.h包含lib1.hmain.cc包含lib2.h

如何为此项目编写cmake文件?我尝试为lib2创建interface library,但编译器找不到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文件中有什么问题?

3 个答案:

答案 0 :(得分:15)

正如评论中所述,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 :(得分:1)

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

我根本不知道INTERFACE关键字。

答案 2 :(得分:0)

此问题是由于INTERFACE库文件的完整路径问题所致,而该问题已在cmake版本3.13中得到修复。

有关更多信息: https://gitlab.kitware.com/cmake/cmake/issues/17556

此页面还包含一个示例,可以使您更好地理解。

相关问题