Yan*_*hou 3 cmake git-submodules
考虑以下三个项目。
ProjectA没有任何依赖关系,其CMakeLists.txt顶层如下所示,
cmake_minimum_required(VERSION 2.8.4)
project(A CXX)
add_library(a ${PROJECT_SOURCE_DIR}/liba.cpp)
Run Code Online (Sandbox Code Playgroud)
ProjectB取决于ProjectA,我将其添加ProjectA为git-submodule,因此其结构如下所示,
ProjectB
CMakeLists.txtlibb.cppProjectA (git子模块)
CMakeLists.txtliba.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)
Run Code Online (Sandbox Code Playgroud)
到目前为止,还好。
现在,我们说它来了ProjectC。它取决于ProjectA和ProjectB。并假设我不知道该ProjectB依赖关系ProjectA已经存在(例如,我之前没有创建过这两个ProjectC依赖关系。或者认为实际上有很多依赖关系,因此我不会被迫找出其中的确切依赖关系树)。
无论如何,我都将ProjectA和ProjectB作为git子模块添加到中ProjectC。因此,它具有以下结构,
ProjectC
CMakeLists.txtlibc.cppProjectA (git子模块)
CMakeLists.txtliba.cppProjectB (git子模块)
CMakeLists.txtlibb.cppProjectA(子模块的git子模块ProjectB)
CMakeLists.txtliba.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)
Run Code Online (Sandbox Code Playgroud)
现在,如果我尝试运行cmake了ProjectC,我得到了下面的错误。
add_library cannot create target "a" because another target with the same
name already exists....
Run Code Online (Sandbox Code Playgroud)
我了解此错误的原因。这是因为ProjectA两次被添加为子目录,并且创建的所有目标add_library都是Global。对于这种特殊情况,我可以通过add_subdirectory(ProjectA)在中删除来解决ProjectC/CMakeLists.txt。但是,请考虑ProjectC具有许多依赖性的情况,并且它们之间可能有也可能没有依赖性。从的开发人员的角度来看ProjectC,他不需要关心自己依赖关系之间的相互依赖关系。
在这种情况下,ProjectC包括其依赖项的最佳方法是什么?必须具有ProjectA和ProjectB作为源形式的git-submodule。我知道我可以简单地安装ProjectA和ProjectB显山露水,ProjectC只需要在某个地方找到安装文件。但是,如果可能的话,我想避免这种解决方案(例如,如果安装时使用的ABI与安装的ABI不同,则会ProjectC出现不兼容的问题)。我希望所有三个项目都在的构建树中构建ProjectC。
您可以a在调用之前检查目标是否已经存在add_subdirectory:
if (NOT TARGET a)
add_subdirectory(ProjectA)
endif ()
Run Code Online (Sandbox Code Playgroud)
因此,它只为整个CMake项目添加一次子目录。