【问题标题】:CMake: Build and install locally stored submoduleCMake:构建和安装本地存储的子模块
【发布时间】:2019-08-04 15:57:02
【问题描述】:

Stack Overflow 上有很多类似的问题,但没有一个能回答我的问题。

我有一个使用 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 标头是如何包含在类似格式的目录中的:

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

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

$ cd myapp/build
$ cmake ..
$ make

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

【问题讨论】:

  • 其他问题似乎与 external 项目有关,而您的项目具有内部库(即它位于 app 项目的目录树内)所以我猜 add_subdirectory应该足够了。不过,我个人会反对这样的项目组织。
  • 我是cmake --build . 的忠实粉丝,而不是make,它更便携。

标签: c++ cmake external-project


【解决方案1】:

假设在所描述的项目中,只有mylib/include 目录中的头文件被认为是公开的:

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 &lt;myfile.h&gt; 一样使用,include/mylib(通用约定)中的文件可以像#include &lt;mylib/myfile.h&gt; 一样使用。

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 将在myapptarget_link_librariesmylib 添加到可执行文件之前构建。

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

【讨论】:

    【解决方案2】:

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

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

    库的 CMakeLists.txt 中的ADD_LIBRARY (${MyLibName} ${SOURCES})

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

    其次,使用

    将库添加到您的项目中

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

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

    【讨论】:

    • 我希望整个过程一次完成。我不想 CMake 并与 myapp 分开构建 mylib。该项目需要 110% 独立。
    • 我说它先做,我指的是单个构建的编译顺序。我的项目建立在一个配置调用和一个构建调用之上。
    • 我有一个脚本可以做到这一点。具体来说,它会创建一个_build 目录,cds 进入其中,调用cmake ..,然后调用cmake --build .,我就坐等编译完成。
    • @paddycakes 很抱歉,如果我还没有完全清楚,这个答案是标准的、正确的构建库并将其添加到您的项目的方法,我直接从 cmake 文档中学到的.
    • 我已经完成了教程,但我正在寻找关于每行目的的进一步详细说明。我发现我的问题是没有正确地将包含目录添加到 mylibtarget_include_directories。我添加了一个包罗万象的答案。
    猜你喜欢
    • 2020-08-11
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多