Autotools、Cmake和Scons之间有什么区别?

293

Autotools、CMake和SCons有什么区别?


1
这个主题已经在Scons wiki中讨论过了。我建议您访问以下链接:1. http://www.scons.org/wiki/SconsVsOtherBuildTools 您是否访问了Ubuntu论坛中非常相似的讨论线程? - bhadra
你可以查看这个PDF文件http://www-alt.gsi.de/documents/DOC-2007-Sep-17-1.pdf;它列出了每个工具的优缺点以及一些详细信息。 - Adam
5个回答

228
事实上,Autotools唯一真正的“救星”只在于所有GNU项目都大量使用它。
Autotools存在问题:
- 真正的ARCANE m4宏语法结合冗长、扭曲的shell脚本用于测试“兼容性”等等。 - 如果你不注意,你会搞砸交叉编译能力(应当明确指出,Nokia提出了Scratchbox / Scratchbox2来规避Maemo / Meego的高度破碎的Autotools构建设置。)如果您在测试中有固定的静态路径,则由于它不会遵守您的sysroot规范并且它将从主机系统中获取内容,您将破坏交叉编译支持。如果您破坏了交叉编译支持,则使您的代码无法用于诸如OpenEmbedded之类的东西,并且使发行版在交叉编译器而不是目标上构建其版本时变得“有趣”。 - 做了大量测试来解决与古老、损坏的编译器的问题,这些编译器在现今工业生产中几乎没有人使用。除非您正在一个古老版本的Solaris,AIX或类似系统上构建像glibc、libstdc++ 或GCC这样的东西,否则这些测试是浪费时间的,并且是上述问题的潜在破坏源。 - 要在Windows系统中构建可用代码,需要付出相当痛苦的代价。(虽然我很少使用Windows,但如果您正在开发声称是跨平台的代码,这是一个严重的问题。) - 当它出现故障时,您将会花费数小时追查脚本编写错误以解决您的构建问题(事实上,这正是我正在尝试做的事情(或者说,完全摆脱Autotools - 我怀疑在本月的剩余时间内没有足够的时间来解决混乱...)因为我正在打字的时候,Apache Thrift有着那种破裂的构建系统,无法进行交叉编译。) - “普通”用户实际上不会只执行“./configure; make”,对于许多东西,他们将获取由某人提供的软件包,例如从PPA或其发行版供应商。 “普通”用户不是开发人员,在许多情况下也不会下载tarball。这是每个人都认为那里会出现这种情况的傲慢态度。 tarball的典型用户是做一些事情的开发人员,因此如果出现问题,他们将遭受破坏。自动工具(Autotools)通常能够正常工作,但有时可能不行。它是一个解决GNU项目基础核心工具链代码中出现的一些问题的系统。需要注意的是,这种关注点潜在地存在问题,Heartbleed部分源于此思维方式。使用正确的现代系统,您不应该处理自动工具可以纠正的大部分内容。考虑到Heartbleed事件的发生,GNU可能需要对其代码库进行清理。如果您希望在Linux或GNU工具链明显正常工作的地方之外构建小型项目,则可以使用Autotools。说它“与Linux集成得很好”是相当大胆和不正确的陈述。 它与GNU工具套件相当兼容,并解决了IT对其目标的问题。
这并不是说此处讨论的其他选项没有问题。SCons更像是Make/GMake等的替代品,并且看起来相当不错。但是...
它仍然更适合POSIX工具。您可能可以更轻松地使用此工具生成Windows内容,而不是使用Autotools,但它仍然更适合执行POSIX任务,并且您需要安装Python和SCons才能使用它。它在交叉编译方面存在问题,除非您使用类似于Scratchbox2的东西。从他们自己的比较中可以看出,它比CMake速度慢,稳定性更差。他们对CMake提出了一些不太负责任的(POSIX侧需要make/gmake构建...)负面评价。如果您需要比其他解决方案更多的可扩展性,您应该问自己是否项目过于复杂。
此处给出的CMake示例有点虚假。然而...
您需要学习一门新语言。
如果您习惯于Make、SCons或Autotools,则有些事情可能不直观。
您需要在正在构建的系统上安装CMake。
如果没有预构建的二进制文件,则需要一个强大的C++编译器。
实际上,您的目标应该决定您选择什么。
  • 你是否需要处理大量的损坏工具链以生成有效的工作二进制文件?如果是,您可能需要考虑使用Autotools,但要注意我上面提到的缺点。CMake可以处理很多这些问题,但与Autotools相比,它处理得更少。SCons可以扩展以处理此问题,但这不是一个即插即用的答案。
  • 您是否需要考虑Windows目标?如果是,则Autotools应该完全排除在外。此时,SCons可能是一个好选择。如果是这样,CMake是一个可靠的选择。
  • 您是否需要担心交叉编译(通用应用程序/库,例如Google Protobufs,Apache Thrift等)?如果是,则Autotools可能适合您,只要您不需要担心Windows,但您将花费大量时间来维护配置系统,因为事情在变化。 SCons几乎是不可行的,除非您使用Scratchbox2-它真的没有处理交叉编译的经验,您将需要使用该可扩展性并像使用Automake一样进行维护。如果是这样,您可能需要考虑CMake,因为它支持跨平台编译,而不会出现太多从沙盒泄漏出来的问题,并且可以与/不与类似Scratchbox2的东西一起使用,并与OpenEmbedded等东西集成良好。

有很多项目放弃了qmake、Autotools等工具,并转向CMake,这其中有原因。到目前为止,我可以干净地预期基于CMake的项目可以轻松地适用于跨编译环境或Visual Studio设置,或者只需要进行少量的清理,因为该项目没有考虑到仅限于Windows或OSX代码库的部分。我真的不能指望在基于SCons的项目中做到这一点——而我完全预料到三分之一或更多的Autotools项目会出现某些问题,导致除主机构建环境或Scratchbox2环境外无法正确构建。


16
这一段提到了Heartbleed漏洞,但这并不是重点。问题出在OpenSSL没有使用配置器类型软件包来检测损坏的malloc函数,而是重新实现了系统库,挫败了平台开发人员生产能够更早检测缺陷的库的努力。移植程序的一个原因是它们变得更高质量,因为它们不再依赖那些你甚至没有意识到自己正在做出的小假设。 - Rob11311
9
重点是它并没有削弱它的价值。使用Autotools时,你需要考虑如何弥补这样的事情- 这些重新实现是这种思维的扩展,相当于将其提升到一个新的水平。你应该从这个背景中来看待它……在这一点上,它并不会减少它的价值。你的推理没有找出根本原因- 只是发生了什么。我找出了导致这一切以及Shellshock和其他类似漏洞的确切思路。如果有破绽,就应该修复它。如果不能修复,那就应该问为什么还要继续使用它。 - Svartalf
5
我不怀疑 autotools 和 scons 很差,但是这个答案没有很好地指出 CMake 的缺点(我偏爱的构建系统,只是因为构建系统非常非常糟糕)。基本上,CMake 是一个不一致性的分形,具有内置支持个别边缘情况而不是处理大多数事情的核心抽象。它肯定是编程中的“胶带和铁丝”。我确定我做错了什么,但是它不支持 VisualStudio,除非你认为每个 CMakeLists.txt 对应一个 VS 项目是可以接受的(我不是 VS 用户,但我的 Winfriends 告诉我这很糟糕)。 - weberc2
7
与其他备受诟病的编程工具不同,CMake 没有足够的材料来写一本名为“CMake, the good parts”的书(或许只能写成小册子或博客文章),而且它更像是一个设计失误的分形图案,比起PHP还要复杂。 - weberc2
2
@JAB 我被VS用户告知这不是惯用语。事实上,CMake已经被替换为我们项目的构建系统,因为没有人能够弄清楚如何生成所谓的“惯用”的VS项目文件。 - weberc2
显示剩余11条评论

84
重要的区别必须在使用工具的人之间进行。Cmake是一个工具,必须由用户在构建软件时使用。Autotools用于生成发行版tarball,只需使用任何SuS兼容系统上可用的标准工具即可构建软件。换句话说,如果您从使用autotools构建的tarball安装软件,则您不是在使用autotools。另一方面,如果您正在安装使用Cmake的软件,则正在使用Cmake并且必须安装它以构建该软件。
绝大多数用户不需要在其计算机上安装autotools。历史上,由于许多开发人员分发格式错误的tarball,强制用户运行autoconf重新生成配置脚本,因此引起了很多混乱,这是一个打包错误。 大多数主要的Linux发行版安装了多个版本的autotools,这会导致更多的混乱,因为默认情况下不应安装它们中的任何一个。开发人员试图使用版本控制系统(例如cvs、git、svn)来分发其软件而不是构建tarballs也会导致更多混乱。

7
没错,虽然你的措辞让人觉得使用版本控制系统来分发软件是不好的。如果从检出或克隆的内容与tar包的内容相同,为什么你会推荐使用tar包呢? - d-_-b
6
我不理解你的问题。我所参与的所有项目都会生成一个tarball,这与版本控制系统(VCS)的检出是不同的。将这两者区分开有助于可靠地分发。 - William Pursell
15
许多项目要求使用版本控制系统来获取最新的发布版本,但这仅适用于开发人员。不幸的是,许多用户无法理解发行包和版本控制系统之间的区别。尝试从版本控制系统构建会增加更多依赖关系。用户可能需要 asciidochelp2mandoxygen,或者更重要的是正确的 autotools 组合。这已经成为 autotools 的一个巨大营销问题。用户错误地认为他们需要安装 autoconf,因为他们不理解发行包和版本控制系统之间的区别。 - William Pursell
4
虽然我认为讨论中提到的观点是正确的,但我认为这次讨论没有抓住重点。用户需要安装整套其他东西,无论他是否需要额外安装cmake都不应该成为一个大问题。我更担心的是构建软件所需的库、编译器工具链和其他工具。 - lanoxx
3
有点晚加入讨论,但你说得很清楚:“CMake的最大缺点是软件包依赖于用户安装了CMake。”听起来对我来说是个致命缺陷。我最近因为各种原因从autotools切换到了CMake,并且尝试过寻找一种方法来创建一个包含源代码、特定目标的Makefile以及可选的预编译二进制文件的软件包。但使用CMake就没有办法实现这一点。 - nicolaum
显示剩余31条评论

29

这不是关于GNU编码规范的问题。

目前,使用autotools(特别是与automake一起使用)的好处在于它们与Linux发行版的构建非常相容。

例如,在使用cmake时,你总是会问自己:“我需要-DCMAKE_CFLAGS还是-DCMAKE_C_FLAGS?”其实都不是,正确的是“-DCMAKE_C_FLAGS_RELEASE”或“-DCMAKE_C_FLAGS_DEBUG”。这很令人困惑。而在autoconf中,只需简单地运行“./configure CFLAGS="-O0 -ggdb3"”即可。

在构建基础设施集成方面,scons的问题在于你无法使用“make %{?_smp_mflags}”,其中“_smp_mflags”是一个RPM宏,大致展开为(管理员可以设置)系统能力。人们会通过环境变量将像-jNCPUS这样的东西放到这里。但是,对于使用scons的包来说,这个方法行不通,因此它们只能按顺序在发行版中进行构建。


12
如果这是真的,世界会变得更美好。但令人遗憾的是,在某些要求用户运行 ./configure --enable-debug 的软件包中,使用 ./configure CFLAGS=-O0 通常会失败,因为它们覆盖了 makefile 中的 CFLAGS。例如,tmux。 - William Pursell
4
这段话的意思是:它并不比Autotools更令人困惑,正如William所指出的那样,如果在makefile中不正确地设置CFLAGS = "<foo>",它会被完全破坏。简单来说,这只是另一个“老掉牙”的问题。而且CMake的示例是虚假的...再次失败。如果没有指定RELEASE或DEBUG,可以实现第一个。失败了。 - Svartalf

18

关于 Autotools,需要知道的重要信息是它们不是通用的构建系统 - 它们实现 GNU 编码标准,没有其他功能。如果你想制作符合所有 GNU 标准的软件包,那么 Autotools 是完成此任务的绝佳工具。如果不需要符合这些标准,建议使用 Scons 或 CMake。(例如,请参见此问题) 这种常见误解就是大多数人对 Autotools 感到沮丧的原因。


12
在您的 Makefile.am 中使用 AUTOMAKE_OPTIONS = -foreign(或在 autogen.sh 中使用 -foreign)可以禁用 Automake 中的 GNU 标准。我认为几乎每个人都会使用这个选项。 - Dietrich Epp
9
是的,但这仅仅控制Automake是否强制执行表面上的GNU规则,例如是否需要README文件。它不会改变使用GNU风格的tarball构建基本前提,例如installcheckdistclean等规则。如果您尝试在仍然使用Autotools的情况下更改这种行为,那么您只是在浪费时间。 - ptomato
1
(理论上)它们允许所有软件包以完全相同的方式构建和安装。 - ptomato
从理论上讲,与其他工具相比,它们可以更适当地处理损坏的编译器和操作系统,并应用像@ptomato在那里突出显示的表面规则。如果您正在使用现代(例如GCC或clang)工具,在没有真正怪异的情况下,例如Linux或当前的BSD上运行的__modern__操作系统,则不需要那里的“规则”。 实际上,它们会为您带来更多的工作量,并且对于交叉编译而言并没有帮助。 近一半的用法现在用于嵌入式Linux和BSD。 为什么要选择那些在这方面无法帮助您的东西呢? - Svartalf
不确定为什么你会对答案进行负评,因为你在评论中似乎承认了它...? - ptomato

9

从开发者的角度来看,对于现在来说,CMake是最易于使用的,但从用户的角度来看,Autotools有一个大优势。

Autotools生成一个单一的配置脚本文件,并且生成它所需的所有文件都随着分发一起提供。可以轻松地使用grep/sed/awk/vi等工具进行理解和修复。相比之下,CMake中有许多文件位于/usr/share/cmak*/Modules,除非用户具备管理员权限,否则无法修复。

因此,如果某些东西不太正常,通常可以通过使用标准Unix工具(grep/sed/awk/vi等)以榔头方式“修复”而无需了解构建系统来解决问题。

你是否曾经挖掘过你的CMake构建目录,以找出问题所在?与可以从上到下阅读的简单shell脚本相比,跟踪生成的CMake文件以找出问题会更加困难。此外,使用CMake调整FindFoo.cmake文件不仅需要了解CMake语言,还可能需要超级用户权限。


8
相较于 CMake,我认为 Autotools 的问题不是“容易修复”的。 - sleske
9
因为Autotools是一个复杂的系统(就像CMake一样)。如果你认为Autotools很容易修复(可能有理由这么想),那么在回答中解释哪些问题更容易修复会是一个好主意。 - sleske
6
Autotools 会生成一个配置脚本的单一文件,所有用于生成此文件的文件都随发布一起传送。使用 grep/sed/awk/vi 工具可以轻松理解和修复。相比之下,Cmake 中有很多文件位于 /usr/share/cmak*/Modules,除非用户拥有管理员访问权限,否则无法进行修改。你是否曾经浏览过 Cmake 构建目录以找出问题所在?与可以从上到下阅读的简单 Shell 脚本相比,跟踪生成的 Cmake 文件了解情况就变得更加困难。 - arved
2
是的,那很有道理,谢谢。我冒昧地将其添加到您的答案中。随意还原 :-). - sleske
2
你可以随时使用自己本地的cmake版本;没有理由使用系统级别安装的版本。对于任何进行跨平台工作的人来说,这是完全正常的;这肯定是我大部分时间使用cmake的方式。 - James Moore
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接