多个嵌套项目和库的 CMake 脚本和目录结构

Posted

技术标签:

【中文标题】多个嵌套项目和库的 CMake 脚本和目录结构【英文标题】:CMake script and directory structure for multiple nested projects and libraries 【发布时间】:2017-05-24 07:13:25 【问题描述】:

我想知道为使用 cmake 构建的多个依赖 c++ 项目制作目录结构的最佳方法是什么,以及在这种情况下 cmake 脚本应该是什么样子。 (如果重要的话,我会在 linux 中使用 gcc 进行。)

我有多个独立项目AB。我还有多个库XY

当这些库由其他开发人员制作时没有问题。我可以使用现有的FindX.cmake 或自己编写来跟踪它们。

XY 是我自己的库时,就会出现问题。让A 依赖于XY,项目B 依赖于Y。此外,让Y 依赖于X(因为我重用了一些常见的,与任务无关的代码)。但是,我认为可以有更多的库、项目和更大的嵌套深度。第二个假设是库(例如X)不仅可以提供*.so之类的库,还可以提供一些可执行文件(不仅用于测试)。

当我重建我的项目时,我想重建所有依赖项,因为我可以同时在项目和库中进行修改。此外,我想将库彼此分开,并为我的所有项目创建一个目录code,其中将包含4个子目录:~/code/A~/code/B~/code/X~/code/Y。每个项目都有自己的测试,并将被推送到单独的代码存储库中。

我发现关于构建正确目录结构的最佳链接是this 和this。但是作者建议创建嵌套目录结构,这在我的示例中似乎很难做到,因为如果我这样做,我最终会得到这样的目录结构:

A/X
A/Y/X
B/Y/X

我可以通过使用符号链接获得。但是然后在我的单独目录中为每个项目编译二进制文件(A/buildB/buildX/buildY/build)我将拥有来自不同库的库和可执行文件的副本。如果我为所有构建调用make install,这些副本将由于二进制文件和库的重复而造成混乱。

更新(解决方案):

答案很简单,经过几天的 cmake 试验和阅读文档,我找到了答案。

    图书馆。添加接下来的两行:

    export(PACKAGE <pkgName>)
    export(TARGETS <libTarget> FILE <pkgName>Config.cmake)
    

    第一行将在~/.cmake/packages/ 中创建条目,这将告诉库的构建目录位于何处。其他项目中的 Cmake 调用从该路径开始搜索。

    第二行将在构建目录中创建Find&lt;pkgName&gt;.cmake

    可执行文件。添加下一行:

    find_package(<pkgName> QUIET)
    
    if($<pkgName>_FOUND)
      message(STATUS "Found <pkgName>.")
    else($<pkgName>_FOUND)
      message(FATAL_ERROR "Could not locate <pkgName>!")
    endif($<pkgName>_FOUND)
    

    因此,如果没有构建库,我们将看到错误消息,否则我们将能够使用目标 &lt;libTarget&gt;

当然,如果对库源进行了一些更改,构建可执行文件不会触发重新构建库。为了克服这个问题,我编写了 bash 脚本,首先在库中调用 make,然后在可执行构建目录中调用。

P。 S.如果你知道更好的解决方案,我还在等待。

【问题讨论】:

【参考方案1】:

我个人使用的是这样的

~/my_project
~/my_project/src
~/my_project/src/A
~/my_project/src/B
~/my_project/src/X
~/my_project/src/Y

CMakeLists.txt使用add_subdirectory添加src目录。 src/CMakeLists.txt 依次使用add_subdirectory 来添加ABXY

CMakeLists.txt 文件中正确设置依赖项后,CMake 将正确处理依赖项,并重建所需的一切(因此,如果您在 X 中进行更改,那么 YAB 应该是正确重建)。

【讨论】:

如果 A 和 B 完全独立,我将它们推送到不同的在线存储库中,~/my_project/CMakeLists.txt、~/my_project/src/CMakeLists.txt 应该放在哪里? @BhavinChirag 如果AB 是真正独立的,那么我的方案将不起作用,因为它会将AB 视为包或子项目的一部分.在这种情况下,我的建议是使XY也独立,创建自己可以使用的FindX.cmakeFindY.cmake文件,并独立构建库,然后分别构建和安装每个库,以正确的顺序。

以上是关于多个嵌套项目和库的 CMake 脚本和目录结构的主要内容,如果未能解决你的问题,请参考以下文章

使用 cmake 创建多个 Debian 软件包

Clion(CMake工具)中创建父子项目,引入第三方库的方法

C++Cmake使用教程(看这一篇就够了)

带有库的 rush setup angular monorepo

CLion 中的嵌套 CMakeLists.txt 文件

CMAKE --- 一个完整的cmake工程示例