pav*_*din 3 c++ git build cmake
我有一个cat依赖于libzzz库的 C++ 项目。它libzzz有自己的 git 存储库,现在我要为该cat项目创建一个存储库。
如何组织 CMake 构建脚本cat?
选项1:CMake的脚本cat考虑libzzz建造和安装在系统和cat项目提供FindLibZZZ.cmake脚本搜索libzzz中/usr/include/libzzz + /usr/lib/libzzz。但是如何处理非linux平台呢?我个人不喜欢这个选项。
选项 2:在 GIT 存储库中添加某种链接或依赖项,这些链接或依赖项cat会自动将libzzz源从其源签出到某个cat子目录中。所以cat的 CMakeLists.txt 考虑libzzz放在 somecat的子目录中。怎么做?
如果libzzz也是 CMake 项目,那么我建议采用另一种方法(我们称之为选项 3)。与其依赖libzzz已在您的系统上可用(这会使集成到 CI 系统等变得更加困难),您可能还需要考虑将其构建为整个项目的一部分。而不是试图将其添加到cat通过git的子模块(有效的,但有自己的缺点,例如,见这里),你可以做一个顶级版本(又名superbuild)同时控制的建设libzzz和cat。
将外部项目引入超级构建通常是使用 CMake 的ExternalProject 模块完成的。这允许您在一次操作中下载和构建项目。不幸的是,它在构建时这样做,并且没有为您提供链接的 CMake 目标,因此您最终必须手动计算要从中链接的库的名称和位置等。是的,您可以稳健地为您的构建预测这些,但您必须手动处理所有平台差异。这就是 CMake 应该为我们处理的事情!
但是ExternalProject,您可以不以正常方式使用,而是可以诱使它在 CMake 时执行下载。然后,这使得外部项目的源代码立即可用,您可以调用add_subdirectory将其直接带入主构建。这反过来意味着由该不再是外部构建定义的任何 CMake 目标也将可见,因此您可以简单地链接到这些目标。在您的特定示例中,libzzz构建可能会定义zzzCMake 目标或类似目标,并且在您的cat构建中,您只需添加如下调用:
target_link_libraries(cat PUBLIC zzz)
Run Code Online (Sandbox Code Playgroud)
无需手动计算任何库名称或位置,因为 CMake 现在已为您完成。所有这一切的诀窍是ExternalProject在 CMake 时间而不是构建时间执行。此处以 GoogleTest 为例对方法进行了完整说明。该技术本质上涉及使用external_process通过 CMake 的脚本模式调用小脚本以ExternalProject_Add立即调用。该文章包含一个指向完全通用实现的链接,您应该能够使用它来libzzz在您的特定情况下执行下载。