考虑以下三个项目。
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)
。它取决于ProjectC
和ProjectA
。我们假设我不知道ProjectB
已经取决于ProjectB
(例如,我之前没有创建过这两个。或者认为ProjectA
实际上有许多依赖关系,我不会被迫弄清楚其中的确切依赖树。)
无论如何,我在ProjectC
中添加了ProjectA
和ProjectB
作为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
包含其依赖关系的最佳方法是什么?将ProjectC
和ProjectA
作为源代码形式的git-submodule是必须的。我知道我可以在某处安装ProjectB
和ProjectA
,ProjectB
只需要在某处找到已安装的文件。但是,如果可能的话,我想避免使用这种解决方案(例如,如果使用与ProjectC
使用的ABI不同的ABI构建安装,则会出现不兼容问题)。我希望所有三个项目都在ProjectC
的构建树中构建。
答案 0 :(得分:4)
您可以在致电a
之前检查目标add_subdirectory
是否已存在:
if (NOT TARGET a)
add_subdirectory(ProjectA)
endif ()
这样它只会为整个CMake项目添加一次子目录。