具有许多第三方依赖关系的大型跨平台C++项目的磁盘上的物理布局

Fra*_*une 6 c++ cross-platform build cmake organization

我正在重新组织使用CMake构建的具有许多第三方依赖关系的大型跨平台C++项目的物理(磁盘上)布局.

由于我们需要支持Windows,这是一个没有完善的软件包管理器的平台,我们很久以前就决定在源代码树中包含我们依赖的第三方库.但是,在我们支持的其他平台上,例如Linux和Mac OS X,许多这些第三方库都可以作为软件包提供,或者已经存在于系统中,很容易被CMake找到.

目前的项目布局如下:

root/
    src/
        3rd-party-lib1/       (build system modified to output to build/)
        3rd-party-lib2/       (build system modified to output to build/)
        project-module1/      (our own code)
        project-module2/      (our own code)
    build/                    (CMake is invoked from here)
        3rd-party-lib1-bin/
        3rd-party-lib2-bin/
Run Code Online (Sandbox Code Playgroud)

第三方库已经过调整,因此在构建时,它们会将二进制文件输出到root/build/<lib>/.

这种布局的问题是多方面的:

  • 第三方图书馆不再是100%原创图书馆.这使得更新它们比要求更困难.
  • src/目录包含我们自己的代码和第三方代码的混合,这令人困惑.
  • src/目录是非常大的.因为src/包含第三方库,它与原始源代码的实际数量相比非常大,使得备份我们自己的代码比所需的稍微复杂一些(我们不能再归档整个src/目录).
  • 项目存储库(Git)非常庞大,因为包含了第三方库(可能包含许多非源文件,如文档,测试数据等),每次更新它们时它都会变大.不幸的是,除非我们决定使用新的存储库重新启动(不幸的是丢失整个提交历史记录),否则无法回到这里.
  • 在Linux或Mac OS X上构建项目的用户根本不需要其中许多包括第三方库(例如zlib,libpng),尽管它们大大简化了Windows用户的工作.

另一种布局如下:

root/
    3rdparty/
        3rd-party-lib1/       (100% original, contains built artifacts)
        3rd-party-lib2/       (100% original, contains built artifacts)
    src/
        project-module1/      (our own code)
        project-module2/      (our own code)
    build/                    (CMake is invoked from here)
Run Code Online (Sandbox Code Playgroud)

我们需要修改我们的CMake文件,以便在每个库的正确位置查找第三方头文件和库.

在本地跨平台项目中处理第三方库的最佳实践是什么?哪种布局会为我们的开发人员在各自的平台上带来最令人惊讶的构建体验?现有项目成功布局的具体例子也是受欢迎的.

小智 7

我的经验表明以下是最佳实践:

  • 当第三方开源库完全按原样使用时,在主git仓库中提交下载的压缩tarball的本地副本,以避免网络连接问题阻止软件构建.

  • 当第三方开源库几乎按原样使用时,需要进行调整(这在交叉编译时很常见:许多软件包需要对其配置步骤稍作调整),存储压缩的tarball和"统一差异" "主git仓库中的补丁文件,并在ExternalProject_Add的PATCH_COMMAND步骤中应用补丁.

  • 当第三方开源库被组织大量修改或扩展时,使用单独的git存储库来保存指向上游存储库的指针(当它也使用git时最简单,但也可以管理上游svn) .将组织的更改提交到用于镜像上游的分支的不同分支.如果你愿意,你可以在主git repo和这个之间引入子模块关系,但是因为DOWNLOAD_COMMAND可以直接从任意git repo获取,所以技术上不需要这样做.

  • 通过在主git仓库中存档它们来处理单个目标平台的小型,不常见的第三方专有二进制文件是合理的.但是,可用于各种平台的第三方二进制文件很大,或者经常进化,应该存储在它们自己的git repo中,并通过DOWNLOAD_COMMAND获取,如上所述.