C++构建系统 - 使用什么?

Gra*_*ham 132 c++ build

我正在考虑用C++开始一个新项目 - 最初只是在我自己的时间 - 我正在调查可用的构建系统.似乎答案是"很多,而且它们都很可怕".

我特别需要的功能是:

  1. C++ 11支持
  2. 跨平台(Linux作为主要目标,但至少能够在Windows上构建)
  3. 体面的单元测试支持
  4. 支持多个模块以分离代码
  5. 支持代码生成(使用asn1c或protobuf - 尚未100%确定)
  6. 易于维护

现在,我知道我可以轻松地完成1-4个使用CMake和Autotools的人.可能还有SCons和Waf以及其他几个人.问题是我从来没有弄清楚如何使用它们正确地进行代码生成 - 这是在第一次运行构建过程之前不存在的源文件,因此构建系统必须能够转换为可执行代码的源文件但实际上并没有知道,直到构建开始......(ASN1C特别生成了几十个必须能够一起工作的头文件和源文件,并且生成的实际文件集取决于你的asn文件的内容)事实上,这些都不是特别容易维护 - CMake和Autotools有他们自己需要管理的大量脚本,Waf和Scons要求任何与他们一起工作的人都有很好的python知识(I不要与他们合作......

那么 - 对于这样的东西,建议使用哪些构建系统?或者我现在还会遇到make文件和shell脚本吗?

cha*_*ley 112

+1,"很多,他们很糟糕."

但是,"最富有"和"最具可伸缩性"的可能是CMake,它是一个Makefile生成器(也生成本机MSVC++ *.proj/ *.sln).奇怪的语法,但是一旦你学会了它,它可以让你很好地为不同的平台生成构建.如果我"开始新鲜",我可能会用CMake.它应该处理你的列表,虽然你的"代码生成"可以在构建系统之外"自己生活",具体取决于你想做什么.(见下文.)

对于简单的项目,QMake生成器是可以的(您不需要使用Qt库来使用QMake).但是,你并没有描述"简单" - 代码生成和"额外阶段"意味着你可能想要CMake或者为你自己的扩展提供丰富的API,比如Scons(或Waf).

我们在工作中使用Scons.它产生"防弹建筑",但它真的很慢.没有其他系统像防弹一样Scons.但是,它很慢.它是用Python编写的,我们扩展了"workspace-organization"的接口(我们只指定模块依赖项),这是Scons设计意图的一部分(这种类型的扩展通过Python).方便,但构建速度很慢.您可以获得防弹版本(任何开发人员框都可以进行最终版本),但速度很慢.而且,它很慢.不要忘记,如果你使用Scons它,它会很慢.而且,它很慢.

我认为,在2000年之后的十年,我们仍然没有飞行汽车.我们可能要等上一百年才能得到它们.而且,我们可能会在我们的飞行汽车中飞来飞去,这些飞行汽车仍在使用蹩脚的构建系统.

是的,他们都很可怕.

[关于代码生成]

Scons适用于"阶段",它们"有些静止".它可以构建作为构建的一部分生成的代码(人们以几种不同的方式执行此操作),但这被描述为"非常类似Scons的东西".

如果它很简单"预处理一些文件并生成源文件",那么没有大问题(你有很多选择,这就是为什么qmake写的 - 用于文件的moc预处理*.hpp/*.cpp).

但是,如果您以"沉重的方式"执行此操作,则需要编写自己的脚本.例如,我们有一个部分构建脚本,用于查询数据库并生成C++类以在"层"之间进行接口(在传统的3层应用程序开发中).类似地,我们通过IDL和嵌入式版本信息生成服务器/客户端源代码,以允许多个客户端/服务器同时运行不同版本(对于相同的"客户端"或"服务器").大量生成的源代码.我们可以"假装"这是"构建系统",但实际上,它是"配置管理"的一个非平凡的基础架构,其中一部分是"构建系统".例如,该系统必须"拆卸"和"启动"服务器作为此过程的一部分.同样,回归测试作为此过程的一部分执行,版本之间有大量的"报告"和"差异测试" - 所有这些都是我们"构建脚本"的一部分.

  • 我也喜欢Scons - 但我觉得它很慢. (35认同)
  • 差不多2年了,你还认为SCons慢吗?当我选择构建系统时,我遇到了[这个](http://www.scons.org/wiki/WhySconsIsNotSlow),这促成了我决定使用SCons. (3认同)
  • @Ben,是的,但这也很慢。 (2认同)
  • 任何看这个的人都应该考虑Meson(使用忍者). (2认同)
  • :@ CMake 太糟糕了。我是 C++ 的新手(但编码了 22 年)我花了 6 周的时间试图理解它,我只是想让它下载依赖项并编译它们(就像其他语言的现代构建系统一样),但我放弃了。移至 bazel.io,它使用简单的配置文件完成此操作。我仍然感到震惊的是,C/C++ 在构建工具方面远远落后于 8ball。没有库描述的中央存储库。项目没有标准的方式来描述跨平台的构建需求。没有从该描述中测试代码的标准方法。男人... (2认同)

Nat*_*enn 30

您现在可以使用Gradle:https://docs.gradle.org/current/userguide/native_software.html

自从我最初发布这个以来,这似乎已经成熟了很多年.该项目正在"孵化"的页面已经消失,但我找不到任何正式声明删除此状态.

  • 过去两天我一直在与 Gradle 进行斗争,只是试图创建一个“hello world”库、应用程序和 gtest,但我不能说我可以将它推荐给新项目。工具可能都在那里,但文档却没有(假设是有好处的)。也许那些认为可行的人可以指出您最喜欢的资源? (4认同)

lee*_*ade 14

我最近发现了这些,我还没有亲自使用它们:

Ninja,一个专注于速度的小型构建系统.谷歌现在使用Ninja来构建Android而不是Make:link.

Shake,一个强大而快速的构建系统.

Tup,一个高性能的构建系统.基于算法的设计. Tup的分析.

现在所有这些都是跨平台的并且支持Windows.我还不确定你的其他要求,因为我还没有自己测试它们.它们被用于商业开发,CIG选择了Ninja.前两个类似于Scons,Ant等.

  • @KerrekSB 可以,但这不是符号查找的问题。Tup 使用 [FUSE](http://fuse.sourceforge.net/),并将自己的中间件挂载到 `.tup/mnt` 中。然后它运行一个文件夹(即`.tup/mnt/@tupjob-XXXXX`)中的所有构建程序作为工作目录,以监控读/写,强制构建配置。它运行良好,除非路径是绝对存储的(即带有符号)。编译二进制文件时,符号路径存储在二进制文件本身中。这意味着当 GDB 尝试加载符号时,它会查找该 `tupjob` 路径,该路径不存在导致错误。 (2认同)

小智 11

Scons是非常友好和灵活的系统,但你说得对,洛萨,它真的很慢.

但是有一种方法可以提高用Python编写的程序的性能.这种使用JIT.在所有已知的项目中,PyPy是一个非常强大,快速增长且有动力的JIT支持的Python 2.7实现.PyPy与Python 2.7的兼容性简直令人惊叹.但是,Scons在PyPy兼容性维基上声明为不受支持的项目. 另一方面,Waf建模为基于python的autotools sucessor,完全由PyPy基础设施支持.在我的项目中,在向PyPy过渡时,组装的速度增加了5-7倍.您可以从PyPy中看到性能报告.

对于现代和相对快速的构建系统,Waf是不错的选择.


Mik*_*e B 8

Google构建系统是一个不错的选择:http://bazel.io/

  • 我不确定它是系统本身还是设置该项目的人,但我在后面使用它@the work遇到了很大的痛苦.这是非常不灵活的(从某种意义上说,它只支持一种做事方式,通常不是最理想的,如果不是令人毛骨悚然的),不够强大,记录不佳(除了基本情况),几乎没有社区所以不要指望stackoverflow来拯救你,相当依赖本身,在大多数系统等大多数IDE都不能很好地兼容等等.所以,除非你是谷歌的粉丝 - 远离它(顺便说一下,有一个facebook版本,叫做Buck - 为Facebook粉丝) (3认同)
  • "跨平台(Linux作为主要目标,但至少能够在Windows上构建)".Bazel的常见问题解答称:"我们目前正积极致力于改进Windows支持,但它仍然无法使用." (2认同)

Tor*_*ten 6

我使用SCons并对这个构建系统印象深刻.SCons可以通过python和python本身扩展 - 它很棒,因为Python拥有你需要的所有东西,只需编写逻辑代码,所有的低级功能都已经在SCons和Python中实现,并且是跨平台的.如果具有良好的编程技能,那么您的构建脚本将看起来完美而简单.

Make,CMake和类似的构建系统似乎是宏的垃圾.Waf是SCons模拟的.我正在尝试Waf,但SCons会更友好,所以我和SCons呆在一起.

通过群众意见SCons太慢了,但是在项目中间,我没有看到make和SCons之间的构建速度有任何区别.相反,SCons已经很好地使用了并行构建,而make则有很大的麻烦.

此外,SCons允许您获得 - 从模板配置,构建,部署,生成配置,运行测试以及执行可以使用python和SCons编码的任何其他任务 - 一体化.这是一个非常大的优势.

对于一个简单的项目,CMake也是一个不错的选择.

  • 我的问题在于我被宠坏了.我是专业的Java开发人员,Java世界中像Gradle这样的工具是我真正希望用于C++开发的工具.我可以使用单行构建文件设置一个没有外部依赖项的gradle项目.而已.具有大量依赖关系的多模块项目仍然很容易实现,并且实际上比简单的C++项目更少配置... (3认同)

use*_*992 5

只是为了增加我的分数:premake

http://industriousone.com/premake

维基上还有一个专门的网页.

  • 不幸的是,Premake不支持按照OP的要求生成代码.我不会称它支持单位测试"体面",尽管你可以做一些事情. (2认同)