考虑以下三个项目。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
和
ProjectB
的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)
到目前为止,还好。
现在,我们说它带有
ProjectC
。它取决于ProjectA
和ProjectB
。并假设我不知道ProjectB
已经依赖于ProjectA
(例如,我之前没有创建这两个。或者认为ProjectC
实际上具有许多依赖关系,因此我不会被迫找出其中的确切依赖关系树)。无论如何,我都将
ProjectA
和ProjectB
都添加为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
包括其依赖项的最佳方法是什么?必须将ProjectA
和ProjectB
作为源形式的git-submodule。我知道我可以在某个地方简单地安装ProjectA
和ProjectB
,而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/