gpt4 book ai didi

具有多个可执行文件的 CMake 共享库

转载 作者:行者123 更新时间:2023-12-03 03:53:20 26 4
gpt4 key购买 nike

我的项目包含多个可执行文件,它们共享一些通用代码。我想将通用代码放在可执行文件可以链接到的静态库中。 (公共(public)代码非常小,我不喜欢处理共享库)。

源代码树看起来像这样:

  • 项目
    • CMakeLists.txt
    • 常见
      • CMakeLists.txt
      • 来源
      • 包括
    • 应用程序1
      • 来源
      • CMakeLists.txt
    • 应用程序2
      • 来源
      • CMakeLists.txt

app1 和 app2 都依赖于共同的代码。

此通用代码是非常特定于应用程序的,并且永远不需要被此目录树之外的其他项目使用。因此,我不想将该库安装在任何类型的全局位置。

顶级 CMakeLists.txt 文件仅添加子目录:

project(toplevel)
cmake_minimum_required(VERSION 3.1)

add_subdirectory(common)
add_subdirectory(app1)
add_subdirectory(app2)

公共(public)库的CMakeLists.txt文件创建静态库并设置包含目录:

add_library(common STATIC common.cpp) 
target_include_directories(common PUBLIC "${CMAKE_CURRENT_LIST_DIR}/include")

可执行文件如下所示:

project(app1)
cmake_minimum_required(VERSION 3.1)

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} common)

现在回答我的问题。如果我从顶级项目目录运行 CMake,我可以构建 app1 和 app2 并且它们构建成功。但是,如果我想构建其中一个项目(例如,通过从 app1 运行 CMake)而不是从顶级目录构建,则会收到错误,因为未添加 common/include到标题搜索路径。

我明白为什么会发生这种情况。 app1 或 app2 的 CMakeLists.txt 文件中没有任何“拉入”共同点。这仅在顶层完成。

有没有办法解决这个问题,或者这种行为通常被认为是可以接受的?我的设置是否欠佳?我只是想,如果我们开始开发越来越多使用这个通用库的可执行文件,能够单独构建项目而不是从顶层构建项目会很好,但也许这是我不应该做的事情值得关注。

最佳答案

当您设置构建环境时,您应该考虑以下三个主题(除其他主题外,但对于本讨论/答案,我将其简化为我认为与此处相关的三个主题):

  1. 依赖/耦合
  2. 部署
  3. 团队

“强耦合”

我想到了 add_subdirectory()命令支持“强耦合”,并且您当前的设置隐式支持:

  • 经常变化的通用
  • 所有应用的单一部署(流程和时间安排)
  • 一个团队负责完整的源代码库
    • IDE 将在一个解决方案中显示所有内容
    • 您为所有内容生成一个构建环境

“松耦合”

如果您想要更多"loose coupling"您可以使用其他语言的外部脚本或使用 CMake 的 ExternalProject_Add()宏。因此,如果您将 common 库(甚至可能包括“二进制交付”)和每个 app 设置为您支持的单独项目:

  • 不常变化的通用
    • 可能有自己的发布周期
  • 每个应用都有独立的开发/部署周期
  • 由不同开发人员组成的团队负责每个应用

两者的混合

正如您所看到的,有很多事情需要考虑,CMake 可以为您提供对各种方法的支持。考虑到您的项目可能处于早期阶段,您可能会采用混合方法(而不是立即解耦 common 库):

CMakeLists.txt

project(toplevel)
cmake_minimum_required(VERSION 3.1)

include(ExternalProject)

ExternalProject_Add(
app1
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/app1"
PREFIX app1
INSTALL_COMMAND ""
)
ExternalProject_Add(
app2
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/app2"
PREFIX app2
INSTALL_COMMAND ""
)

app1/CMakeLists.txt

project(app1)
cmake_minimum_required(VERSION 3.1)

add_subdirectory(../common common)

add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} common)

这实际上会生成三个构建环境。一个直接位于二进制输出目录中,一个位于 app1app2 子目录中。

在这种方法中,您可能需要考虑常见的 CMake 工具链文件。

引用文献

关于具有多个可执行文件的 CMake 共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33443164/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com