CMake:构建并安装本地存储的子模块

CMake: Build and install locally stored submodule

Stack Overflow 上有许多类似的问题,但 none 接近回答我的问题。

我有一个使用 CMake 构建的 C++ 库:

mylib
| - CMakeLists.txt
| - src/
|   | - m.h
|   | - m.cpp
| - include/
|   | - mylib/
|   |   | - a.h
|   |   | - something/
|   |   |   | - some.h
| - cmake/
|   - mylibConfig.cmake.in
|   - mylibConfigVersion.cmake.in

然后我创建另一个包含上述库的库或可执行文件:

myapp
| - CMakeLists.txt
| - src/
|   | - main.cpp
| - include/
|   | - myapp/
|   |   | - b.h
| - libs
|   | - mylib

并且想像这样在 myapp 中使用 mylib。请注意如何将 mylib headers 包含在格式如下的目录中:

#include <mylib/a.h>
#include <mylib/something/some.h>

mylib 应在构建 myapp 时构建,以便以下工作 无需任何其他构建步骤:

$ cd myapp/build
$ cmake ..
$ make

这是我查看过的一些 Stack Overflow 帖子的列表。每一个我都尝试过,但它们根本不起作用:

所以,我实际上在我的一个项目中这样做了。

首先,需要使用 ADD_LIBRARY() 构建库,但我假设您这样做了。像

ADD_LIBRARY (${MyLibName} ${SOURCES}) 在图书馆的 CMakeLists.txt

这会将库添加到 cmake 的库列表中。

其次,使用

将库添加到项目中

target_link_libraries (${PROJECT_NAME} ${MyLibName}) 在可执行文件的 CMakeLists.txt 中,与 add_executable (${PROJECT_NAME} ${SOURCES})

相同

这将设置依赖链以强制 MyLibName 在 PROJECT_NAME 之前显式构建。

假设在所描述的项目中,只考虑 mylib/include 目录中的头文件 public:

mylib 的顶级 CMakeLists.txt 需要包含:

cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
project(mylib VERSION 0.1 LANGUAGES CXX)

add_library(${MyLibName} ${MyLib_SOURCES})

target_include_directories(${MyLibName}
    PUBLIC
        $<INSTALL_INTERFACE:include>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)

这确保了包括 mylib 在内的项目只能访问 include/ 目录中的文件。 include/ 中的文件可以像 #include <myfile.h> 一样使用,include/mylib(通用约定)中的文件可以像 #include <mylib/myfile.h>.

一样使用

myapp 的顶级 CMakeLists.txt 应包括:

cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
project(myapp VERSION 0.1 LANGUAGES CXX)

add_subdirectory(libs/mylib)

add_executable(${MyAppName} ${MyApp_SOURCES})
target_link_libraries(${MyAppName} ${MyLibName}

使用 add_subdirectory 确保 mylib 将在 myapp 之前构建,并且 target_link_librariesmylib 添加到可执行文件中。

如 Tzalumen 所述,请务必查看 CMake tutorials 并更喜欢使用 cmake --build . 而不是 make