如何创建一个依赖于外部头文件的 cmake 头文件库?

2021-12-26 00:00:00 cmake c++

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

I have a project with the following file structure:

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

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

The two libs lib1 and lib2 only contain header files while lib2.h includes lib1.h, and main.cc includes lib2.h.

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

How do I write the cmake file for this project now? I tried to create an interface library for lib2, but the compiler can't find lib1.h. Here are the contents of my cmake files:

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 文件有什么问题?

What's the problem in the cmake files?

推荐答案

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

As stated in the comments, target_include_directories should be given a path to a directory, not to a file.

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

Moreover, if you want to create a dependency for lib2 on lib1, you should do it through target_link_libraries: a dependency is not only about include directories, but also about compile options, definitions, target properties...

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

target_sources doesn't work with interface libraries. From this answer, You can use a custom target without commands to associate the sources to a target without impacting the build process (for msvc, QtCreator and other GUI-based tools, this makes the sources accessible through the IDE; AFAIK it's useless for other build tools).

您的 cmake 可能如下所示:

Your cmake may look like this:

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 中为构建树和安装树指定不同的目录(请参阅 文档):

Advanced tip: you can specify a different directory in target_include_directories for the build tree and the install tree (see documentation):

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

相关文章