【发布时间】:2017-08-16 03:31:59
【问题描述】:
我们有许多 Git 存储库,其中一些包含我们自己的代码,一些包含稍微修改的第三方库代码。一个简化的依赖图如下所示:
executable_A
| |
| v
| library_B
| |
v v
library_C
所以可执行文件对library_C 有两个依赖项,一个是直接的,一个是传递的。我希望使用 Git 子模块和 CMake 将这一切联系在一起,因此简化的目录结构如下所示:
executable_A/
CMakeListst.txt
library_B/
CMakeLists.txt
library_C/
CMakeLists.txt
library_C/
CMakeLists.txt
如您所见,library_C 存储库作为子模块包含了两次。让我们假设两个子模块都指向同一个提交(任何关于如何强制执行的想法都会受到欢迎,但不是这个问题的主题)。
我们使用add_subdirectory、target_link_libraries 和target_include_directories 来管理这些相互依赖关系。很标准。
问题是如果你两次创建同名目标,CMake 不喜欢它,所以它会报错:
library_C/CMakeLists.txt:13 (add_library) 处的 CMake 错误:
add_library 无法创建目标“library_C”,因为另一个目标 同名的已经存在。现有目标是静态的 在源目录“.../library_B/library_C”中创建的库。
有关详细信息,请参阅政策 CMP0002 的文档。
我宁愿不删除executable_A 对library_C 的直接依赖,因为它通过library_B 拉入的事实是library_B 的一个实现细节,不应依赖它。此外,一旦我们添加另一个依赖项,例如 executable_A --> library_D --> library_C,这种方法就会失效。
(This question 是我能找到的最接近的,但更笼统一些,而且仍然没有答案。)
【问题讨论】:
-
常用的方法是在使用
add_subdirectory()进入项目之前检查是否存在某些特定于项目的目标(if(TARGET library_C))。 -
@Tsyvarev
if(NOT TARGET library_c)然后,当然。听起来是一种可行的方法。愿意将其发布为答案吗?
标签: c++ cmake git-submodules