使用 CMake 从静态库中包含头文件

Hym*_*mir 5 c++ cmake include static-libraries

我在使用静态库构建 CMake 项目时遇到问题。我的项目结构看起来像这样:

Foo/
|-- CMakeLists.txt
|-- lib/
    |-- CMakeLists.txt
    |-- libA/
        |-- CMakeLists.txt
        |-- libA.cpp
        |-- libA.h
        |-- libAB.h
|-- src/
    |-- CMakeLists.txt
    |-- main.cpp
    |-- srcDirA/
        |-- CMakeLists.txt
        |-- srcA.h
    |-- srcDirB/
        |-- CMakeLists.txt
        |-- srcB.cpp
        |-- srcB.h
Run Code Online (Sandbox Code Playgroud)

而 */CMakeLists.txt 看起来像这样:

Foo/CMakeLists.txt:

cmake_minimum_required(VERSION 3.5.1)
project(FOO)

set(CMAKE_CXX_STANDARD 11)

add_subdirectory(lib)
add_subdirectory(src)
Run Code Online (Sandbox Code Playgroud)

Foo/lib/CMakeLists.txt:

add_subdirectory(libA)
Run Code Online (Sandbox Code Playgroud)

Foo/lib/libA/CMakeLists.txt:

add_library (staticLibA STATIC libA.cpp)
Run Code Online (Sandbox Code Playgroud)

Foo/src/CMakeLists.txt:

add_subdirectory(srcDirA)
add_subdirectory(srcDirB)
include_directories(".")

add_executable(foo main.cpp)
target_link_libraries(foo LINK_PUBLIC libA)
Run Code Online (Sandbox Code Playgroud)

Foo/src/srcDirA/CMakeLists.txt 为空

Foo/src/srcDirB/CMakeLists.txt 为空

现在我试图将我的静态库中的标头包含到我的主项目中,如下所示:

Foo/src/main.cpp:

#include "srcDirB/srcB.h"
#include "libA/libA.h"  

int main() {
   //...
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用 CMake 构建它,则会生成 libA,但出现致命错误:

libA/libA.h:没有这样的文件或目录。

有谁知道我做错了什么?我必须创建一个 ProjectConfig.cmake 文件吗?

Rei*_*ica 9

You don't need to create any Config files; these are for importing 3rd-party projects.

Since you're using CMake >= 3.5.1, you can esaily specify usage requirements for your libraries. Usage requirements are things like flags or include directories which clients need to build with the library.

So in Foo/lib/libA/CMakeLists.txt:, you'll do this:

add_library (staticLibA STATIC libA.cpp)
target_include_directories(staticLibA INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/..)
Run Code Online (Sandbox Code Playgroud)

Or, if you want the same include directory to apply to libA itself (which is likely), use PUBLIC instead of INTERFACE.

That's all you really need to do. However, given the modern CMake you're using, you should replace your use of the legacy keyword LINK_PUBLIC with its modern equivalent PUBLIC.

Also, since you mention both CMakeLists in .../srcDir* are empty, why have them there in the first place? You can easily get rid of both them and the related add_subdirectory calls.