我有一个依赖于cat
库的C ++项目libzzz
。 libzzz
有自己的git存储库,现在我要为cat
项目创建一个存储库。
如何为cat
组织CMake构建脚本?
选项1:cat
的CMake脚本在系统中构建并安装libzzz
,cat
项目提供搜索FindLibZZZ.cmake
的{{1}}脚本在libzzz
。但是如何处理非Linux平台呢?我一般不喜欢这个选项。
选项2:在GIT存储库/usr/include/libzzz + /usr/lib/libzzz
中添加某种链接或依赖,它会自动从其中检出cat
个来源源于某个libzzz
子目录。因此,cat
的CMakeLists.txt会将cat
放在某个libzzz
的子目录中。怎么做?
答案 0 :(得分:4)
如果libzzz
也是一个CMake项目,那么我建议采用另一种方法(让我们称之为选项3)。您可以考虑将其构建为整个项目的一部分,而不是依赖于libzzz
已经可用于您的系统(这可以更好地集成到CI系统等)。而不是尝试通过git子模块将其添加到cat
(有效,但有自己的缺点,例如参见here),您可以使顶层构建(也称为superbuild)控制两者的构建{ {1}}和libzzz
。
通常使用CMake ExternalProject module将外部项目引入超级构建。这允许您在一个操作中下载和构建项目。不幸的是,它在构建时这样做并且没有为你提供链接的CMake目标,因此你最终必须手动计算出你要链接的库的名称和位置,等等。是的,你可以强有力地为您的构建预测这些,但您必须手动处理所有平台差异。这就是CMake应该为我们照顾的事情!
不是以正常方式使用cat
,而是可以哄它在CMake时执行下载。然后,这会立即使外部项目的源代码可用,您可以调用ExternalProject
将其直接带入主构建。这反过来意味着由不再外部构建定义的任何CMake目标也将是可见的,因此您可以简单地链接这些目标。在您的特定示例中,add_subdirectory
版本可能会定义libzzz
CMake目标或类似内容,而在您的zzz
版本中,您只需添加以下调用:
cat
无需手动设计任何库名称或位置,因为CMake现在可以为您完成。所有这一切的诀窍是让target_link_libraries(cat PUBLIC zzz)
在CMake时执行而不是建立时间。使用GoogleTest作为示例,完整地解释了该方法here。该技术主要涉及使用ExternalProject
通过CMake的脚本模式调用小脚本来立即调用external_process
。该文章包含一个完全通用实现的链接,您应该能够在特定情况下执行ExternalProject_Add
的下载。
答案 1 :(得分:2)
我相信如果您计划将项目分发给其他人(如果您考虑使用非Linux平台,那听起来就是这样),那么选项1是最好的。如果您不打算将cat
分发给更广泛的世界,那么请务必使用选项2,这可能稍微容易实现。但是,假设我想使用cat
,你选择选项2.在这种情况下,可能会出现几个问题:
libzzz
,因为它也被dog
项目使用,那么您正在下载并构建我已经拥有的东西。这至少是浪费时间。libzzz
发布了重要的安全更新,那么我还需要重新下载您的项目。如果我很幸运,您更新了cat
存储库以使用新版本的libzzz
。如果我运气不好,那么你还没有注意到新的安全更新,你正在维护存储库的不同部分,或者你死了,cat
完全没有维护。如果我真的不走运,我不会注意到cat
现在需要更新,因为libzzz
发布了新版本,我遇到了安全问题。cat
项目变得很受欢迎。现在,各地的软件包维护人员需要了解如何使用其存储库中的现有cat
编译libzzz
。我知道我已经看到一个人的文章,他实际上是一个包维护者争论选项1,但我似乎无法再找到它。如果我这样做,我会用链接更新这个答案。