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

C++ 大型跨平台C+磁盘上的物理布局+;具有许多第三方依赖关系的项目,c++,build,cmake,cross-platform,organization,C++,Build,Cmake,Cross Platform,Organization,我正在重新组织使用CMake构建的具有许多第三方依赖关系的服务器的物理(磁盘上)布局 由于我们需要支持Windows,一个没有完善的包管理器的平台,我们很久以前就决定在源代码树中包含我们所依赖的第三方库。然而,在我们支持的其他平台上,如Linux和Mac OS X,这些第三方库中的许多都可以作为软件包提供,或者已经存在于系统中,CMake很容易找到它们 当前项目布局如下所示: root/ src/ 3rd-party-lib1/ (build system m

我正在重新组织使用CMake构建的具有许多第三方依赖关系的服务器的物理(磁盘上)布局

由于我们需要支持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/
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)
对第三方库进行了调整,以便在构建时将二进制文件输出到
root/build/

此布局存在多个问题:

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

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/
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)
我们的CMake文件需要修改,以便在每个库的正确位置查找第三方头文件和库


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

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

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

  • 当第三方开源库几乎按原样使用,但需要调整时(此 交叉编译时很常见:许多包需要稍微调整其配置步骤),将压缩的tarball和“统一的diff”补丁文件存储在主git repo中,并在ExternalProject\u Add的patch\u命令步骤中应用补丁

  • 当组织对第三方开源库进行了大量修改或扩展时,请使用单独的git存储库来保存指向上游存储库的指针(当它也使用git时最简单,但也可以管理上游svn)。将组织的更改提交到不同于用于镜像上游的分支的分支。如果愿意,您可以在主git repo和此git repo之间引入子模块关系,尽管由于DOWNLOAD_命令可以直接从任意git repo获取数据,因此从技术上讲不需要这样做

  • 通过将小型、不太频繁的第三方专有二进制文件归档到主要的git repo中,将其用于单个目标平台是合理的。但是,可用于各种平台、较大或经常演变的第三方二进制文件应存储在其自己的git repo中,并通过下载_命令获取,如上所述


也许Windows数据包管理器可以解决这个问题。我试着自己建立一个:-现在只支持boost和Qt。在我自己的项目中,我使用了一种混合方法—Boost、Qt、OptiX、Cuda、Windows SDK假定由用户安装—其他库(如gtest、OpenEXR、zlib、freetype、glews等)都附带了源代码。感谢您的输入。我们还希望用户已经在他们的机器上安装了Qt和Boost。我真正关心的是其他较小的、鲜为人知的库,如ILMBase、OpenEXR、Alembic、zlib、libpng等。只需发现C++的NuGet::。一些LIB已经被支持了:但我没有使用它的实际经验。为什么不为Windows构建一个FindPackage.cmake文件并使用cmake_MODULE_PATH呢?这样,您就可以使用find_包编写“标准”CMakeLists.txt,并通过迁移FindPackage.cmake将您的第三方LIB从项目中迁移出来?这是一个有趣的想法,Andre。到目前为止,我已经将所有第三方LIB移到了顶级的
3rdparty/libs/
目录中;我将它们全部构建到位,并指示CMake在
3rdparty/install/
目录中“安装”它们。您的建议可能允许简化我自己的CMakeLists.txt文件。+1,但我不需要将tarball/二进制文件提交到主git repo。为什么不简单地制作发布快照并使用
ExternalProject\u Add
从自定义位置下载它呢?根据具体情况,这可能是一个合理的选择——甚至只使用ExternalProject\u Add\u步骤就足够了。但是,随着时间的推移,有关如何构造快照的知识将丢失,这是一个严重的风险。为了防止这种情况,快照产品