CMake并使用git-submodule进行依赖项目

时间:2017-05-03 13:33:14

标签: cmake git-submodules

考虑以下三个项目。

ProjectA没有任何依赖关系,顶层的CMakeLists.txt如下所示,

cmake_minimum_required(VERSION 2.8.4)
project(A CXX)
add_library(a ${PROJECT_SOURCE_DIR}/liba.cpp)

ProjectB取决于ProjectA,我将ProjectA添加为git-submodule,因此其结构如下所示,

  • ProjectB
    • CMakeLists.txt
    • libb.cpp
    • ProjectA(git submodule)
      • CMakeLists.txt
      • liba.cpp

ProjectB的{​​{1}}如下所示

CMakeLists.txt

到目前为止还没问题。

现在让我们说它来cmake_minimum_required(VERSION 2.8.4) project(B CXX) add_subdirectory(ProjectA) add_library(b ${PROJECT_SOURCE_DIR}/libb.cpp) target_link_libraries(b a) 。它取决于ProjectCProjectA。我们假设我不知道ProjectB已经取决于ProjectB(例如,我之前没有创建过这两个。或者认为ProjectA实际上有许多依赖关系,我不会被迫弄清楚其中的确切依赖树。)

无论如何,我在ProjectC中添加了ProjectAProjectB作为git子模块。所以它有以下结构,

  • ProjectC
    • ProjectC
    • CMakeLists.txt
    • libc.cpp(git submodule)
      • ProjectA
      • CMakeLists.txt
    • liba.cpp(git submodule)
      • ProjectB
      • CMakeLists.txt
      • libb.cpp(子模块ProjectA的git子模块)
        • ProjectB
        • CMakeLists.txt

它有以下liba.cpp

CMakeLists.txt

现在,如果我尝试为cmake_minimum_required(VERSION 2.8.4) project(C CXX) add_subdirectory(ProjectA) add_subdirectory(ProjectB) add_library(c ${PROJECT_SOURCE_DIR}/libc.cpp) target_link_libraries(c a b) 运行cmake,我会收到以下错误。

ProjectC

我理解这个错误的原因。这是因为add_library cannot create target "a" because another target with the same name already exists.... 被添加为子目录两次,而ProjectA创建的所有目标都是全局。对于这种特殊情况,我可以通过移除add_library中的add_subdirectory(ProjectA)来解决此问题。但是,请考虑ProjectC/CMakeLists.txt具有许多依赖关系的情况,并且它们之间可能存在也可能不存在依赖关系。从ProjectC的开发人员的角度来看,他不应该关心自己的依赖关系之间的依赖关系。

在这种情况下,让ProjectC包含其依赖关系的最佳方法是什么?将ProjectCProjectA作为源代码形式的git-submodule是必须的。我知道我可以在某处安装ProjectBProjectAProjectB只需要在某处找到已安装的文件。但是,如果可能的话,我想避免使用这种解决方案(例如,如果使用与ProjectC使用的ABI不同的ABI构建安装,则会出现不兼容问题)。我希望所有三个项目都在ProjectC的构建树中构建。

1 个答案:

答案 0 :(得分:4)

您可以在致电a之前检查目标add_subdirectory是否已存在:

if (NOT TARGET a)
  add_subdirectory(ProjectA)
endif ()

这样它只会为整个CMake项目添加一次子目录。