如何组织具有钻石依赖性的庞大的整体代码库?

时间:2018-12-26 08:04:15

标签: cmake

我们正在使用CMake在一个整体存储库中管理我们的代码,包括多个产品和库。当前,这些项目通过add_subdirectory使用。例如:

回购布局:

Foo
Bar
Baz
Product

Bar Baz 取决于 Foo ,而 Product 取决于 Bar Baz

在文件/Foo/CMakeLists.txt中:

cmake_minimum_required(VERSION 3.10)
include_guard(GLOBAL)
project(Foo)
add_library(foo ......)
# ......

在文件/Bar/CMakeLists.txt中:

cmake_minimum_required(VERSION 3.10)
include_guard(GLOBAL)
project(Bar)
add_subdirectory(../Foo sibling/Foo)
add_library(bar ......)
target_link_libraries(bar foo)
# ......

在文件/Baz/CMakeLists.txt中:

cmake_minimum_required(VERSION 3.10)
include_guard(GLOBAL)
project(Baz)
add_subdirectory(../Foo sibling/Foo)
add_library(baz
target_link_libraries(baz foo)
# ......

在最终产品中,/Product/CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
include_guard(GLOBAL)
project(Product)
add_subdirectory(../Bar sibling/Bar)
add_subdirectory(../Baz sibling/Baz)
add_executable(product ......)
target_link_libraries(product bar baz)
# ......

此布局解决了钻石需求,并允许分别生成每个项目。但是,它具有以下缺点:

  • CMakeLists.txt变得更加复杂。它包含更多行,并使用更多CMake概念,使培训新成员变得更加困难。
  • 当项目号增加时,二进制目录变得混乱,很难找到基础项目的实际二进制目录。例如,Base的实际二进制目录可能位于${CMAKE_BINARY_DIR}/Some/sibling/Very/sibling/Deep/sibling/Dependencies/sibling/Base${CMAKE_BINARY_DIR}/Another/sibling/Damn/sibling/Deep/sibling/Dependencies/sibling/Base中。

我们还尝试了更单一的方法:使用包含所有项目的CMake根文件:

在文件/CMakeLists.txt中:

cmake_minimum_required(VERSION 3.0)
project(MegaProject)

add_subdirectory(Base)
add_subdirectory(Foo)
add_subdirectory(Bar)
add_subdirectory(Product)

这不需要为每个项目编写复杂的CMake文件,您只需要这样的事情:

project(Product)
add_executable(product ......)
target_link_libraries(product bar baz)

减少了很多行。

但是,它有一个关键问题:它需要生成整个代码库,并且在有大量项目时,生成时间变得太长了。

那么,如何使用CMake管理大型的整体代码?

0 个答案:

没有答案