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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39887352/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:51:37  来源:igfitidea点击:

How to create a cmake header-only library that depends on external header files?

c++cmake

提问by X. Liu

I have a project with the following file structure:

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

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

The two libs lib1and lib2only contain header files while lib2.hincludes lib1.h, and main.ccincludes lib2.h.

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

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

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

CMakeLists.txt for lib2:

lib2 的 CMakeLists.txt:

add_library(lib2 INTERFACE)
target_sources(lib2 INTERFACE lib2.h)
target_include_directories(lib2 INTERFACE ../lib1/lib1.h)

CMakeLists.txt for the whole project:

整个项目的 CMakeLists.txt:

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

What's the problem in the cmake files?

cmake 文件中有什么问题?

回答by wasthishelpful

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

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

Moreover, if you want to create a dependency for lib2on 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...

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

target_sourcesdoesn'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).

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

Your cmake may look like this:

您的 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)

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

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

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

回答by Micha? Kawiecki

I've used an empty _only_for_compiling_the_lib.cppfile as the simplest and fastest workaround, but clearly the above solution is strongly advised.

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

I simply wasn't aware of INTERFACEkeyword.

我只是不知道INTERFACE关键字。

回答by Pankaj Misra

This problem was due to full path issue of INTERFACE library files, which got fixed in cmake version 3.13.

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

For more info: https://gitlab.kitware.com/cmake/cmake/issues/17556

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

This page also contains an example for better understanding.

此页面还包含一个示例以便更好地理解。