考虑以下三个项目。
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子模块)
  • CMakeLists.txt
  • liba.cpp

  • ProjectBCMakeLists.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)
    

    到目前为止,还好。

    现在,我们说它带有ProjectC。它取决于ProjectAProjectB。并假设我不知道ProjectB已经依赖于ProjectA(例如,我之前没有创建这两个。或者认为ProjectC实际上具有许多依赖关系,因此我不会被迫找出其中的确切依赖关系树)。

    无论如何,我都将ProjectAProjectB都添加为ProjectC中的git子模块。因此,它具有以下结构,
  • ProjectC
  • CMakeLists.txt
  • libc.cpp
  • ProjectA(git子模块)
  • CMakeLists.txt
  • liba.cpp
  • ProjectB(git子模块)
  • CMakeLists.txt
  • libb.cpp
  • ProjectA(子模块ProjectB的git子模块)
  • 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开发人员的角度来看,他不需要关心自己依赖关系之间的相互依赖关系。

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

    最佳答案

    您可以在调用a之前检查目标add_subdirectory是否已经存在:

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

    因此,它只为整个CMake项目添加一次子目录。

    关于CMake并使用git-submodule进行依赖项目,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43761594/

    10-12 18:50