CMake 并使用 git-submodule 进行依赖项目
CMake and using git-submodule for dependence projects
考虑以下三个项目。
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-子模块,因此其结构如下所示,
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
实际上有很多依赖关系,我不会被迫找出它们之间的确切依赖树)。
无论如何,我在 ProjectC
中添加了 ProjectA
和 ProjectB
作为 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
for ProjectC
,我会收到以下错误。
add_library cannot create target "a" because another target with the same
name already exists....
我明白这个错误的原因。这是因为 ProjectA
被添加为子目录两次,并且 add_library
创建的所有目标都是 Global。对于这种特殊情况,我可以通过删除 ProjectC/CMakeLists.txt
中的 add_subdirectory(ProjectA)
来修复它。但是,考虑 ProjectC
有很多依赖关系的情况,它们之间可能存在依赖关系,也可能不存在依赖关系。从ProjectC
的开发者的角度来看,他应该不需要关心自身依赖之间的相互依赖关系。
在这种情况下,让 ProjectC
包含其依赖项的最佳方法是什么?将 ProjectA
和 ProjectB
作为源代码形式的 git 子模块是必须的。我知道我可以简单地在某处安装 ProjectA
和 ProjectB
,而 ProjectC
只需要在某处找到已安装的文件。但是,如果可能的话,我想避免这种解决方案(例如,如果安装是使用与 ProjectC
使用的 ABI 不同的 ABI 构建的,则会出现不兼容问题)。我希望所有三个项目都构建在 ProjectC
.
的构建树中
你可以在调用add_subdirectory
之前检查目标a
是否已经存在:
if (NOT TARGET a)
add_subdirectory(ProjectA)
endif ()
这样它只会为您的整个 CMake 项目添加一次子目录。
考虑以下三个项目。
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-子模块,因此其结构如下所示,
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
实际上有很多依赖关系,我不会被迫找出它们之间的确切依赖树)。
无论如何,我在 ProjectC
中添加了 ProjectA
和 ProjectB
作为 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
for ProjectC
,我会收到以下错误。
add_library cannot create target "a" because another target with the same
name already exists....
我明白这个错误的原因。这是因为 ProjectA
被添加为子目录两次,并且 add_library
创建的所有目标都是 Global。对于这种特殊情况,我可以通过删除 ProjectC/CMakeLists.txt
中的 add_subdirectory(ProjectA)
来修复它。但是,考虑 ProjectC
有很多依赖关系的情况,它们之间可能存在依赖关系,也可能不存在依赖关系。从ProjectC
的开发者的角度来看,他应该不需要关心自身依赖之间的相互依赖关系。
在这种情况下,让 ProjectC
包含其依赖项的最佳方法是什么?将 ProjectA
和 ProjectB
作为源代码形式的 git 子模块是必须的。我知道我可以简单地在某处安装 ProjectA
和 ProjectB
,而 ProjectC
只需要在某处找到已安装的文件。但是,如果可能的话,我想避免这种解决方案(例如,如果安装是使用与 ProjectC
使用的 ABI 不同的 ABI 构建的,则会出现不兼容问题)。我希望所有三个项目都构建在 ProjectC
.
你可以在调用add_subdirectory
之前检查目标a
是否已经存在:
if (NOT TARGET a)
add_subdirectory(ProjectA)
endif ()
这样它只会为您的整个 CMake 项目添加一次子目录。