【发布时间】:2013-11-06 04:10:26
【问题描述】:
我正在重新组织 large cross-platform C++ project 的物理(磁盘上)布局,其中包含许多第三方依赖项,使用 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/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)
需要修改我们的 CMake 文件,以便在每个库的正确位置查找第三方头文件和库。
在原生跨平台项目中处理第三方库的最佳做法是什么?哪种布局会为我们的开发人员在各自的平台上带来最出人意料的构建体验?也欢迎现有项目中成功布局的具体示例。
【问题讨论】:
-
也许 Windows 的数据包管理器可以解决这个问题。我尝试自己构建一个:vertexwahn.de/bluego.html - 现在只支持 boost 和 Qt。在我自己的项目中,我使用混合方法 - Boost、Qt、OptiX、Cuda、Windows SDK 假定由用户安装 - 其他库(如 gtest、OpenEXR、zlib、freetype、glews 等)随源代码一起提供。
-
感谢您的意见。我们还希望用户已经在他们的机器上安装了 Qt 和 Boost。我真正关心的是其他较小且鲜为人知的库,例如 ILMBase、OpenEXR、Alembic、zlib、libpng 等。
-
刚刚发现 NuGet for C++:blogs.msdn.com/b/vcblog/archive/2013/04/26/nuget-for-c.aspx。一些库已经支持:nuget.org/profiles/coapp 但我没有实践经验。
-
为什么不为 Windows 构建 FindPackage.cmake 文件并使用 CMAKE_MODULE_PATH?这样,您可以使用 find_package 编写“标准”CMakeLists.txt,并可以通过迁移 FindPackage.cmake 将您的第 3 方库迁移出项目?
-
这是一个有趣的想法,安德烈。到目前为止,我已将所有第三方库移动到顶级
3rdparty/libs/目录中;我将它们全部构建到位,并指示 CMake 将它们“安装”在3rdparty/install/目录中。您的建议可能允许简化我自己的 CMakeLists.txt 文件。
标签: c++ build cmake cross-platform organization