静态库子目录和包含路径之间的依赖关系

Dependencies between static library subdirectories and include paths

我正在开发一个由一个可执行文件 link 和两个库组成的项目。
我经常对所有这些进行更改,并且不希望通过 libAlibBsudo make install 循环,所以我按以下方式布置它们:

myProject
├── libA
│   ├── CMakeLists.txt
│   ├── include
│   │   └── libA
│   │       └── *.h
│   └── src
│       └── *.cpp
│
├── libB
│   ├── CMakeLists.txt
│   ├── include
│   │   └── libB
│   │       └── *.h
│   └── src
│       └── *.cpp
│
├── CMakeLists.txt
├── include
│   └── *.h
└── src
    └── *.cpp

我正在使用 CMake 子目录自动将 libA 中的 link 和 myProject 中的 libB 自动生成,并且工作正常。 CMakeList.txt设置如下:

# myProject/CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(myProject)

add_subdirectory(libA)
add_subdirectory(libB)

# Compiler flags, listing of the source files into ${SOURCE_FILES}, etc.

add_executable(myProject ${SOURCE_FILES})

target_link_libraries(myProject libA libB)

# myProject/libA/CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(libA)

# Compiler flags, listing of the source files into ${SOURCE_FILES}, etc.

add_library(libA STATIC ${SOURCE_FILES})
target_include_directories(libA PUBLIC include)

install(
    TARGETS libA
    ARCHIVE DESTINATION lib
)

install(
    DIRECTORY include/glk
    DESTINATION include
)

myProject/libB/CMakeLists.txt类似

现在的问题是:libB 依赖于 libA,包括 libA 的 headers 到 #include <libA/foo.h>,并且需要符号从 libA 到 linking(尽管我猜这是一个带有静态库的 non-issue)。

如何正确设置此依赖关系,以便 libB 找到它需要的关于本地 libA 的所有内容,最好只修改 myProject 的配置?

您需要指定 libBlibA 的 link 依赖性。是的,它们可能是静态库,但 CMake 允许您指定 link 一个库到另一个库,即使它们是静态的。在库是静态的情况下,这样的 link 关系仅用于提供目标之间的传递依赖性(即那些在各种 target_... 命令中作为 PUBLIC 或 INTERFACE 项提供的)。所以我期待你的 libB's CMakeLists.txt to look similar to libA',除非你还要添加以下行:

target_link_library(libB PRIVATE libA)

或者如果 libB 在其自己的 public API 中使用了 libA 的部分,则使上述 link 依赖 PUBLIC 而不是私人的。通过这样做,任何你有目标 link 反对 libB 的地方,CMake 将确保 libA 出现在最终命令行上它之后。在您的示例中,顶级 CMakeLists.txt 文件 links libBlibA 之后,因此如果没有上述 target_link_library() 关系,linker 将抱怨 libA 中的符号丢失,即使 libA 会在 linker 命令行上,只是顺序错误。您的顶级 CMakeLists.txt 文件中 target_link_libraries() 的语法也不正确(可能只是您示例中的拼写错误)。参数不应为 comma-separated.

显式 linking libBlibA 的另一个效果是现在 libB 从 [=12= 中获取 PUBLIC 和 INTERFACE 属性],在本例中将是 libA 定义的 header 搜索路径。您应该会发现 libB 现在也会找到 libA 的 header。