61

最近,我将我的开发环境从 Windows 切换到了 Linux。到目前为止,我只使用 Visual Studio 进行 C++ 开发,所以很多概念,比如makeAutotools对我来说都是新的。我已经阅读了 GNU makefile 文档并且对它有了几乎一个想法。但我对 Autotools 有点困惑。

据我所知,makefile 用于简化构建过程。

  1. 为什么我们需要像Autotools这样的工具来创建 makefile?由于所有人都知道如何创建生成文件,因此我没有真正使用 Autotools。
  2. 标准是什么?我们需要使用这样的工具还是只需要手写的 makefile 就可以了?
4

8 回答 8

88

您在这里谈论的是两个独立但相互交织的事情:

  • 自动工具
  • GNU 编码标准

在 Autotools 中,您有几个项目:

  • 自动配置
  • 汽车制造
  • 工具

让我们分别看看每一个。

自动配置

Autoconf 可以轻松扫描现有树以查找其依赖项并创建一个几乎可以在任何类型的 shell 下运行的配置脚本。配置脚本允许用户控制构建行为(即--with-foo--without-foo--prefix--sysconfdir)以及进行检查以确保系统可以编译程序。

Configure 生成一个config.h文件(从模板),程序可以包含该文件以解决可移植性问题。例如,如果HAVE_LIBPTHREAD未定义,请改用 forks。

我个人在许多项目中使用 Autoconf。人们通常需要一些时间来习惯m4。但是,它确实节省了时间。

您可以让 makefile 继承一些配置查找的值,而无需使用 automake。

汽车制造

通过提供一个简短的模板来描述将构建哪些程序以及需要链接哪些对象来构建它们,可以自动创建符合 GNU 编码标准的 Makefile。这包括依赖处理和所有必需的 GNU 目标。

有些人觉得这更容易。我更喜欢编写自己的 makefile。

工具

Libtool 是一个非常酷的工具,用于简化任何类 Unix 系统上共享库的构建和安装。有时我会使用它;其他时候(尤其是在构建静态链接对象时)我手动完成。

还有其他选项,请参阅 StackOverflow 问题Autoconf 和 A​​utotools 的替代方案?.

构建自动化和 GNU 编码标准

简而言之,如果您将代码发布给大众,您真的应该使用某种可移植的构建配置系统。你使用什么取决于你。众所周知,GNU 软件几乎可以在任何东西上构建和运行。但是,您可能不需要遵守这样的(有时是极其迂腐的)标准。

如果有的话,如果您正在为 POSIX 系统编写软件,我建议您尝试一下 Autoconf。仅仅因为 Autotools 生成了与 GNU 标准兼容的构建环境的一部分,并不意味着您必须遵循这些标准(很多人不需要!):) 还有很多其他选择。

编辑

不要害怕 m4 :) 总是有Autoconf 宏存档。大量示例,或检查。自己编写或使用经过测试的内容。Autoconf 经常与Automake混淆。它们是两个不同的东西。

于 2009-04-05T15:12:30.320 回答
33

首先,正如 tinkertim 已经指出的那样,Autotools 不是一个不透明的构建系统,而是一个松散耦合的工具链。让我添加一些关于 Autoconf 和 A​​utomake 的想法:

Autoconf是一个配置系统,它根据应该适用于各种平台的功能检查来创建配置脚本。在其存在的 15 年中,大量系统知识已进入其m4宏数据库。一方面,我认为后者是 Autotools 尚未被其他东西取代的主要原因。另一方面,当目标平台更加异构并且必须支持 Linux、AIXHP-UXSunOS等以及各种不同的处理器架构时,Autoconf 曾经更为重要。如果您只想支持最新的 Linux 发行版和与 Intel 兼容的处理器,我真的不明白它的意义。

Automake是 GNU Make 的一个抽象层,并充当来自更简单模板的 Makefile 生成器。许多项目最终摆脱了 Automake 抽象并恢复为手动编写 Makefile,因为您失去了对 Makefile 的控制,并且您可能不需要所有混淆 Makefile 的罐头构建目标。

现在到替代品(我强烈建议根据您的要求替代 Autotools):

CMake最显着的成就是在KDE中取代了 AutoTools 。如果您想在没有 m4 特性的情况下拥有类似 Autoconf 的功能,这可能是您可以获得的最接近的功能。它带来了 Windows 支持,并已被证明适用于大型项目。我对 CMake 的不满在于它仍然是一个 Makefile 生成器(至少在 Linux 上),存在所有内在问题(例如 Makefile 调试、时间戳签名、隐式依赖顺序)。

SCons是用 Python 编写的 Make 替代品。它使用 Python 脚本作为构建控制文件,允许使用非常复杂的技术。不幸的是,它的配置系统无法与 Autoconf 相提并论。当适应特定需求比遵循约定更重要时,SCons 通常用于内部开发。

如果您真的想坚持使用 Autotools,我强烈建议您阅读Recursive Make Considered Harmful并编写您自己的通过 Autoconf 配置的 GNU Makefile。

于 2009-04-05T16:05:15.217 回答
24

这里已经提供的答案很好,但如果你有任何类似于标准 C/C++ 项目的东西,我强烈建议不要接受编写自己的 makefile 的建议。我们需要 autotools 而不是手写的 makefile,因为由 automake 生成的符合标准的 makefile 以众所周知的名称提供了许多有用的目标,而手动提供所有这些目标既乏味又容易出错。

首先,手工编写 Makefile 一开始似乎是一个好主意,但大多数人不会费心编写比所有规则更多的东西,安装和清理。automake 生成 dist、distcheck、clean、distclean、uninstall 和所有这些小帮手。这些额外的目标对于最终将安装您的软件的系统管理员来说是一个巨大的福音。

其次,以可移植和灵活的方式提供所有这些目标非常容易出错。我最近对 ​​Windows 目标进行了很多交叉编译,并且自动工具的性能非常好。与大多数手写文件相比,这些文件编译起来很麻烦。请注意,可以手动创建一个好的 Makefile。但是不要高估自己,它需要大量不同系统的经验和知识,而 automake 开箱即用地为您创建了出色的 Makefile。

编辑:不要试图使用“替代品”。CMake 和朋友对部署者来说是一种恐惧,因为它们与配置和朋友的界面不兼容。每个能干一半的系统管理员或开发人员都可以做一些很棒的事情,比如交叉编译或简单的事情,比如在他的脑海中设置一个前缀,或者使用一个简单的 --help 和一个配置脚本。但是当你不得不用 BJam 做这些事情时,你该死的花上一三个小时。不要误会我的意思,BJam 可能是一个很棒的底层系统,但使用起来很痛苦,因为几乎没有项目使用它,而且文档很少且不完整。autoconf 和 automake 在已建立的知识方面有着巨大的领先优势。

所以,即使我对这个问题的建议有点晚了:帮自己一个忙,使用 autotools 和 automake。语法可能有点奇怪,但它们比 99% 的开发人员自己做的要好得多。

于 2011-09-20T07:49:51.973 回答
11

对于小型项目,甚至对于仅在一个平台上运行的大型项目,手写的 makefile 都是可行的方法。

当您为需要不同选项的不同平台进行编译时,autotools 真正闪耀的地方。Autotools 往往是典型背后的大脑

。/配置

制作

进行安装

Linux 库和应用程序的编译和安装步骤。

也就是说,我发现自动工具很痛苦,我一直在寻找更好的系统。最近我一直在使用 bjam,但这也有它的缺点。祝你好运找到适合你的东西。

于 2009-04-05T15:08:06.803 回答
7

需要 Autotools 是因为 Makefile 不能保证在不同平台上都一样工作。如果您手写一个 Makefile,并且它可以在您的机器上运行,那么它很可能不会在我的机器上运行。

于 2009-04-05T15:04:21.430 回答
6

您知道您的用户将使用什么 unix 吗?甚至是哪个 Linux 发行版?你知道他们想在哪里安装软件吗?你知道他们有什么工具,他们想在什么架构上编译,他们有多少 CPU,有多少 RAM 和磁盘可供他们使用?

*nix 世界是一个跨平台的环境,您的构建和安装工具需要处理它。


请注意,auto* 工具可以追溯到更早的时代,并且有很多关于它们的有效抱怨,但是用更现代的替代品取代它们的几个项目在发展很多动力方面遇到了麻烦。

在 *nix 世界中很多事情都是这样的。

于 2009-04-05T15:02:54.273 回答
4

Autotools 是一场灾难。

生成的./configure脚本会检查过去 20 年左右没有出现在任何 Unix 系统上的功能。为此,它会花费大量时间。

跑步./configure需要很长时间。尽管现代服务器 CPU 甚至可以有几十个内核,并且每台服务器可能有多个这样的 CPU,但./configure它是单线程的。我们仍然有足够的摩尔定律剩余时间,CPU 内核的数量将随着时间的推移而增加。因此,所花费的时间./configure将大致保持不变,而由于摩尔定律,并行构建时间每 2 年减少 2 倍。或者实际上,我会说./configure由于利用改进的硬件而增加的软件复杂性,所花费的时间甚至可能会增加。

仅将一个文件添加到您的项目中就需要您运行automake,这将需要很长时间,autoconf然后./configure您可能会发现由于一些重要文件已更改,所有内容都将重新编译。所以只添加一个文件,然后make -j${CPUCOUNT}重新编译所有内容。

而关于make -j${CPUCOUNT}. 生成的构建系统是一个递归的。递归 make 长期以来一直被认为是有害的

那么当你安装已经编译好的软件时,你会发现它不起作用。(想要证明吗?从 Github 克隆protobuf存储库,检查 commit 9f80df026933901883da1d556b38292e14836612,将其安装到 Debian 或 Ubuntu 系统,嘿,presto:protoc: error while loading shared libraries: libprotoc.so.15: cannot open shared object file: No such file or directory——因为它在/usr/local/lib而不是/usr/lib;解决方法是export LD_RUN_PATH=/usr/local/lib在输入之前做make)。

理论上,通过使用 autotools,您可以创建一个可以在 Linux、FreeBSD、NetBSD、OpenBSD、DragonflyBSD 和其他操作系统上编译的软件包。事实?每个从源代码构建软件包的非 Linux 系统在其存储库中都有许多补丁文件来解决 autotools 错误。看看例如 FreeBSD /usr/ports:它充满了补丁。因此,在每个项目的基础上为非 autotools 构建系统创建一个小补丁比在每个项目的基础上为 autotools 构建系统创建一个小补丁一样容易。或者甚至更容易,因为标准make比自动工具更容易使用。

事实是,如果您根据标准创建自己的构建系统make(并使其具有包容性而不是递归,遵循“递归使被认为有害”论文的建议),事情会以更好的方式工作。此外,如果您的项目是 10-100 个 C 语言文件的非常小的项目,并且每个 CPU 和多个 CPU 有几十个内核,那么您的构建时间可能会减少一个数量级,甚至可能减少两个数量级。将自定义自动代码生成工具与基于标准的自定义构建系统连接起来也更容易,make而不是处理m4一堆乱七八糟的自动工具。使用标准make,您至少可以在Makefile.

所以,回答你的问题:为什么要使用自动工具?答:没有理由这样做。自从商业 Unix 过时以来,Autotools 就已经过时了。多核 CPU 的出现使自动工具更加过时。为什么程序员还没有意识到这一点,这是一个谜。我很乐意make在我的构建系统上使用标准,谢谢。是的,为 C 语言头文件包含生成依赖文件需要一些工作量,但是由于不必与 autotools 斗争而节省了工作量。

于 2018-01-12T16:58:44.477 回答
1

我不觉得我是回答这个问题的专家,但还是用我的经验给你一个类比。

因为在某种程度上,这类似于为什么我们应该用 C 语言(高级语言)编写嵌入式代码而不是用汇编语言编写。两者都解决了相同的目的,但后者更冗长、乏味、耗时且更容易出错(除非您非常了解处理器的 ISA)。Automake 工具和编写自己的 makefile 也是如此。编写 Makefile.am 和 configure.ac 比编写单个项目 Makefile 非常简单。

于 2017-10-02T17:48:41.917 回答