C ++构建系统-使用什么?[关闭]


136

我正在寻找一个用C ++开始的新项目-最初只是在我自己的时间里-我正在研究可用的构建系统。答案似乎是“很多,他们都很糟糕”。

我为此特别需要的功能是:

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

现在,我知道我可以轻松完成1-4个使用CMake和Autotools的任务。也许还有SCons和Waf以及其他几个人。问题是我从来没有想过如何使用它们正确地执行代码生成-那是在首次运行构建过程之前不存在的源文件,因此构建系统必须能够将其转换为可执行代码但实际上直到构建开始才知道...(特别是ASN1C生成了数十个必须能够协同工作的头文件和源文件,而实际生成的文件集取决于您的asn文件的内容)还有一个事实是,这些都不是特别容易维护的事实-CMake和Autotools有自己的庞大脚本集,您需要对其进行管理才能使其正常工作,

那么-推荐什么样的构建系统来进行类似的事情?还是我现在会被make文件和shell脚本卡住?


11
我的印象也是:“看来答案是'很多,他们都很糟糕'”(加上“从我的角度来看很糟糕”;我不喜欢用这些术语来概括太多) )。正是出于这个原因,我实际上建立了自己的公司,它的效果比预期的要好,因为它可以满足我的要求以及我一直希望事情能够正常进行的方式。为了节省一些时间,您可能必须浏览现有的工具,并选择一种比其他工具少一些麻烦的工具。
克里斯汀·斯蒂伯

4
尝试tup
Kerrek SB 2012年


8
您希望构建系统提供什么样的C ++ 11支持?这是从编译器得到的东西,构建系统不会解析甚至读取实际的源文件,只是将它们传递给需要它们的人,不是吗?
巴鲁克(Baruch)2013年

5
没错,但是很容易告诉编译器使用C ++ 11支持会很好。g ++需要一个标志,用clang传递另一个标志,msvc显然不需要任何标志,依此类推。同样,支持检测可用的c ++ 11功能将很有用,因为编译器之间也有所不同……
Graham

Answers:


117

+1表示“很多,他们很糟糕”。

但是,“最丰富”和“最可扩展”的可能是CMake,它是一个Makefile生成器(还生成本机MSVC ++ *.proj/ *.sln)。很奇怪的语法,但是一旦学习了它,就可以让您很好地为不同平台生成构建。如果我“从头开始”,我可能会使用CMake。它可以处理您的列表,尽管您的“代码生成”可能会在构建系统之外承担“自己的一生”,具体取决于您想做什么。(见下文。)

对于简单的项目,可以使用QMake生成器(无需使用Qt库即可使用QMake)。但是,您并不是在描述“简单”,而是代码生成和“额外阶段”,这意味着您可能想要CMake或带有丰富API的用于自己的扩展的东西,例如Scons(或Waf)。

我们在工作中使用Scons。它会产生“防弹产品”,但速度确实很慢。没有其他系统可以像一样防弹Scons。但是,它很慢。它是用Python编写的,并且已经扩展了“工作空间组织”的接口(在这里我们仅指定模块依赖项),这是Scons设计意图的一部分(通过Python进行的这种扩展)。方便,但是构建缓慢。您可以获得防弹版本(任何开发人员都可以制作最终版本),但是速度很慢。而且,它很慢。不过请不要忘记,如果使用Scons,它会很慢。而且,它很慢。

我很难想到,在2000年之后的十年,我们仍然没有飞行的汽车。为了获得它们,我们可能不得不再等一百年。而且,那时我们所有人都可能会乘坐我们仍在使用笨拙的构建系统建造的飞行汽车四处飞行。

是的,他们都很糟糕。

[关于代码生成]

Scons在“阶段”上工作,它们是“有点静态”的。它可以构建作为构建的一部分而生成的代码(人们以几种不同的方式来执行此操作),但是这被描述为“非常不像Scons的东西”。

如果是简单的“预处理一些文件并生成源文件”,那么就没什么大不了了(您有很多选择,这就是为什么qmake要编写文件moc预处理的原因*.hpp/*.cpp)。

但是,如果您以“繁重的方式”执行此操作,则需要编写自己的脚本。例如,我们有一部分构建脚本,这些脚本查询数据库并生成C ++类以在“层”之间进行接口(在传统的3层应用程序开发中)。同样,我们通过IDL生成了服务器/客户端源代码,并嵌入了版本信息,以允许多个客户端/服务器以不同的版本(对于同一“客户端”或“服务器”)同时运行。很多生成的源代码。我们可以“假装”为“ the-build-system”,但实际上,它是“配置管理”的重要基础,其中一部分是“ build-system”。例如,该系统必须“删除”和“


37
我也喜欢Scons-但我认为它很慢。
Lothar

1
您可以让CMake使用Makefile包装器处理代码生成,以在生成代码时执行可选的第二阶段。我能够支持完整的依赖性跟踪,在代码生成后提早退出以触发重新生成等。请参见:javaglue.com/javaglue.html#tag : JavaGluecode.google.com/p/javaglue
sdw

3
近2年了,您仍然认为SCons速度慢吗?当我选择一个构建系统时,我遇到了这个问题,这有助于我决定使用SCons。
JBentley 2014年

2
@Ben,是的,但这也很慢。
查理

2
任何查看此内容的人都应该考虑Meson(使用忍者)。
马修·斯科尔菲尔德

33

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

自从我最初发布此信息以来,这几年似乎已经成熟了很多。表示该项目正在“孵化”的页面已经消失,但是我找不到任何取消此状态的官方公告。


我同意Gradle。Gradle设计为可扩展的。但是,这取决于插件的实现速度。gradle本身也有一些开销。另请注意,某些插件可能需要针对您的用例进行自定义。
JE42

有趣的是看到gradle对支持C ++的兴趣。希望他们为我们所有人都缺少的c ++项目提供一个不错的,坚实的构建系统。
hbobenicio 2014年

@鱿鱼谢谢,更新。
Nate Glenn

1
Gradle功能强大而简单。没有奇怪的语法,一个gradle.build文件通常足以构建具有多个可执行输出(主要,测试等)的整个项目。所有源目录之间都没有文件转储。超级友好的版本控制。
Overdrivr

1
在过去的两天里,我一直在与Gradle作战,只是试图创建一个“ hello world”库,应用程序和gtests,我不能说我可以为一个新项目推荐它。这些工具可能全部都存在,但是没有提供文档(带来了疑问的好处)。也许你们中那些认为可行的人可以指向您喜欢的资源?
jwm

16

我找到了这些,但我还没有亲自使用它们:

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

,强大而快速的构建系统。

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

现在,所有程序都是跨平台的,并支持Windows。我还不确定您的其余要求,因为我还没有自己进行测试。他们被用于商业发展,CIG选择了忍者。我曾经使用过项目生成器,并且喜欢Ninja的便捷性和速度。前两个类似于Scons,Ant等。


1
Tup会弄乱符号查找,在任何其他构建系统上都无法很好地发挥作用(实际上,根本无法),在随机输出中(例如,由javac内部类生成的类(被分隔成class$1.class文件)所产生的类)不能很好地发挥作用编写不当,并使用系统黑客来实现其功能。这对于小型系统非常有用;大型项目无法维护。
Qix-蒙尼卡(Monica)

@Qix:您不能将输出与存储库分开吗?
Kerrek SB 2015年

1
@KerrekSB您可以,但这不是符号查找的问题。Tup使用FUSE并将其自己的中间件安装到.tup/mnt。然后,它会在一个文件夹(即.tup/mnt/@tupjob-XXXXX)中作为工作目录运行所有构建程序,以监视读写操作,从而强制执行构建配置。除非路径是绝对存储的(即带有符号),否则它会很好地工作。编译二进制文件时,符号路径存储在二进制文件本身中。这意味着,当GDB尝试加载符号时,它将查找该tupjob路径,该路径不存在而导致错误。
Qix-蒙尼卡(Monica)

Tup和Ninja都是非常低级的工具,其性能甚至低于或低于Make。它们不是针对C ++量身定制的。我什至不称这些工具为构建系统,因为它们缺少许多重要的高级功能,这些功能是真正的构建系统提供的,用于处理复杂的现实世界项目。其中一些系统可能会将Ninja用作后端。
约翰·布勒(JohanBoulé)'18年

11

Scons是非常友好和灵活的系统,但是,对了,Lothar,它真的很慢。

但是有一种方法可以提高用Python编写的程序的性能。这种使用JIT。在所有已知的项目中,PyPy是一个功能强大,快速增长且有动机的JIT支持的Python 2.7实现。PyPy与Python 2.7的兼容性简直令人赞叹。但是,Scons在PyPy兼容性Wiki上声明为不受支持的项目。 另一方面,Waf被建模为基于python的autotools继承者,受到PyPy基础架构的完全支持。在我的项目中,组装到PyPy的速度提高了5到7倍。您可以从PyPy查看性能报告

对于现代且相对较快的构建系统,Waf是不错的选择。


值得注意的是,现在scons在链接的Wiki页面上被标记为“兼容”,因此显然它现在可以与PyPy一起使用。
假名称

8

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


3
“跨平台(Linux是主要目标,但也能够至少在Windows上构建)”。Bazel的常见问题解答说:“我们目前正在积极致力于改善Windows支持,但是仍然无法使用。”
Michael Mrozek '16

3
我不确定是系统本身还是项目的建立者,但是我在使用@ work时感到非常痛苦。它非常不灵活(从某种意义上说,它仅支持一种做事方式,通常是次优的,如果不是令人毛骨悚然的话),功能不够强大,文档不足(基本情况除外),社区很少,所以不要期望stackoverflow会节省您的时间,它本身是一个依赖项,在大多数系统上的大多数IDE等,等等等等上不能很好地发挥作用。因此,除非您是google的粉丝-否则请远离它(顺便说一句,它有一个Facebook版本,称为Buck-针对Facebook粉丝)
Slava

嘿,花了6周的时间让CMake正常工作后,我发现它真的很容易使用。我希望它下载第三方依赖项并进行编译(因为我习惯于使用python和JavaScript构建工具)。这很容易,但是有一个缺点,那就是您可能必须为不支持它的第三方编写自己的bazel文件。他们需要一个中央存储库以将这些存储在i'ze reckon中。
CpILL

6

我使用了SCons,并对该构建系统印象深刻。SCons可通过python和python本身进行扩展-太好了,因为Python具有您所需的全部内容,只需对逻辑进行编码,所有低层功能都已在SCons和Python中实现,并且是跨平台的。如果您具有良好的编程技能,则您的构建脚本将看起来完美而轻松。

Make,CMake和类似的构建系统似乎是宏的垃圾。Waf是SCons模拟。我正在尝试Waf,但SCons会更加友好,因此我选择了SCons。

根据群众的意见,SCons太慢了,但是在项目的中间,我没有发现make和SCons在构建速度上有什么区别。相反,SCons在并行构建方面做得很好,而make却遇到了很大的麻烦。

而且,SCons允许您从模板中获取,配置,构建,部署,从模板生成配置,运行测试以及执行可以使用python和SCons进行编码的任何其他任务。这是一个很大的优势。

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


3
我的问题是我被宠坏了。我是一名专业的Java开发人员,而Java世界中的Gradle之类的工具正是我真正想要用于C ++开发的工具。我可以使用一个单独的行构建文件来建立一个gradle项目,而没有任何外部依赖。而已。具有许多依赖关系的多模块项目也仍然很容易做,实际上甚至比简单的C ++项目还要轻得多的配置……
Graham

我在构建使用Scons的其他软件包时遇到了问题,因为它没有抽象系统配置标志,例如-I include dirs和-L library dirs。不需要CFLAGS,您通常必须修改每个scons脚本才能使其在正确的位置显示。
ACyclic

5

只是为了增加我的美分:预制

http://industriousone.com/premake

Wiki上还有一个专用网页


2
不幸的是,Premake不支持根据OP的要求生成代码。尽管您可以做一些事情,但我不会称其对单元测试的支持“不错”。
ergosys

@ergosys我注意到没有提到蚂蚁,它ant也支持C / C ++,看看这对您有没有好处,这是我的姓氏,为此我只使用Makefiles和Cmake。
user827992 2012年

2

您可以使用Ceedling。注意,然而,它目前仅支持C,并且与作者的Unity和CMock测试框架紧密结合。

可以对其进行分叉和修改,使其与C ++编译器和单元测试/模拟框架相当容易地一起工作。

此外托普是值得一提。它非常快,但是对测试框架等一无所知。这意味着您必须使用Tup编写自己的构建系统。如果您打算进行TDD,则Tup可能是您要走的路。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.