最近,我将开发环境从Windows切换到了Linux。到目前为止,我只使用Visual Studio进行C ++开发,因此许多概念,如make和Autotools对我来说都是新的。我已经阅读了GNU makefile文档并且几乎了解了它。但我对Autotools感到困惑。
据我所知,makefile用于简化构建过程。
答案 0 :(得分:77)
你在谈论两个独立但交织在一起的事情:
在Autotools中,您有几个项目:
让我们分别看一下。
<强>的Autoconf 强>
Autoconf可以轻松扫描现有树以查找其依赖项,并创建一个可在几乎任何类型的shell下运行的配置脚本。 configure脚本允许用户控制构建行为(即--with-foo
,--without-foo
,--prefix
,--sysconfdir
等。)以及进行检查以确保系统可以编译程序。
配置生成config.h
文件(来自模板),程序可以包含这些文件以解决可移植性问题。例如,如果未定义HAVE_LIBPTHREAD
,请改用叉号。
我个人在许多项目中使用Autoconf。通常需要一些时间来适应m4。但是,它确实可以节省时间。
您可以让makefile继承一些配置查找的值,而无需使用automake。
<强>的Automake 强>
通过提供一个简短的模板来描述将构建哪些程序以及需要链接哪些对象来构建它们,可以自动创建符合GNU编码标准的Makefile。这包括依赖项处理和所有必需的GNU目标。
有些人发现这更容易。我更喜欢写自己的makefile。
<强> Libtool程序强>
Libtool是一个非常酷的工具,可以在任何类Unix系统上简化共享库的构建和安装。有时候我会用它;其他时候(特别是在构建静态链接对象时)我手工完成。
还有其他选项,请参阅StackOverflow问题 Alternatives to Autoconf and Autotools? 。
构建自动化&amp; GNU编码标准
简而言之,如果您向大众发布代码,您真的应该使用某种类型的可移植构建配置系统。你用的是由你自己决定的。众所周知,GNU软件可以在几乎任何东西上构建和运行。但是,您可能不需要遵守这些(有时极其迂腐)的标准。
如果有的话,如果您正在为POSIX系统编写软件,我建议您尝试使用Autoconf。仅仅因为Autotools生成的部分构建环境与GNU标准兼容并不意味着你必须遵循这些标准(很多都没有!):)还有很多其他的选择。
修改强>
不要害怕m4 :)总有Autoconf macro archive。大量的例子,或支票下降。自己写或使用经过测试的。 Autoconf经常与Automake混淆。它们是两个不同的东西。
答案 1 :(得分:31)
首先,Autotools不是一个不透明的构建系统,而是一个松散耦合的工具链,正如tinkertim已经指出的那样。让我在Autoconf和Automake上添加一些想法:
Autoconf 是一个配置系统,它根据应该在各种平台上运行的功能检查来创建配置脚本。在其存在的15年中,许多系统知识已经进入其m4宏数据库。一方面,我认为后者是Autotools尚未被其他东西取代的主要原因。另一方面,当目标平台更加异构并且Linux AIX,HP-UX,SunOS,......以及各种各样的不同时,Autoconf会变得更加重要必须支持处理器架构。如果您只想支持最新的Linux发行版和兼容英特尔的处理器,我真的不明白这一点。
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。
答案 2 :(得分:19)
这里已经提供的答案很好,但是如果你有类似标准的C / C ++项目的话,我强烈建议你不要自己编写makefile。我们需要autotools而不是手写的makefile,因为automake生成的符合标准的makefile在众所周知的名称下提供了许多有用的目标,并且手动提供所有这些目标是繁琐且容易出错的。
首先,手工编写Makefile似乎是一个好主意,但大多数人都不会费心去编写所有规则,安装和清理。 automake生成dist,distcheck,clean,distclean,uninstall以及所有这些小帮手。这些额外的目标对于最终安装软件的系统管理员来说是一个很大的好处。
其次,以便携和灵活的方式提供所有这些目标非常容易出错。我最近对Windows目标做了很多交叉编译,而autotools的表现非常好。与大多数手写文件形成对比,这些文件大多是编译时的痛苦。请注意, 可以手动创建一个好的Makefile。但是不要高估自己,它需要大量的经验和知识来处理一堆不同的系统,而且automake会立即为您创建出色的Makefile。
编辑:不要试图使用“替代品”。 CMake和朋友对部署者来说是一种恐怖,因为它们与配置和朋友不兼容接口。每个中途胜任的系统管理员或开发人员都可以做很棒的事情,比如交叉编译或简单的事情,比如设置一个前缀,或者用一个简单的 - help配置脚本。但是当你不得不和BJam做这些事情时,你会花一两个小时的时间。不要误会我的意思,BJam可能是一个很好的系统,但是使用它是一件痛苦的事情,因为几乎没有任何项目使用它,而且文档很少和不完整。 autoconf和automake在知识方面具有巨大的领先优势。
所以,即使我对这个问题的建议有点迟了:帮自己一个忙,使用autotools和automake。语法可能有点奇怪,但它们比99%的开发人员自己做得更好。
答案 3 :(得分:10)
对于小型项目,甚至只能在一个平台上运行的大型项目,手写的makefile是可行的方法。
autotools真正发挥作用的地方在于编译需要不同选项的不同平台。 Autotools通常是典型
背后的大脑./配置
请
make install
Linux库和应用程序的编译和安装步骤。
那就是说,我觉得autotools很痛苦,我一直在寻找一个更好的系统。最近我一直在使用bjam,但这也有它的缺点。祝你找到对你有用的东西。
答案 4 :(得分:6)
您知道您的用户将使用哪些unix吗?甚至是Linux的哪个发行版?你知道他们想要在哪里安装软件吗?你知道他们有什么工具,他们想要编译什么架构,他们有多少CPU,有多少RAM和磁盘可用?
* nix世界是一个跨平台的环境,您的构建和安装工具需要处理它。
请注意,auto *工具可以追溯到更早的时代,并且有许多有关它们的有效投诉,但是用更现代的替代品替换它们的几个项目却难以发展出很多动力。
很多事情就像在* nix世界中那样。
答案 5 :(得分:6)
需要Autotools,因为不保证Makefile在不同平台上的工作方式相同。如果你手写一个Makefile,它可以在你的机器上运行,很有可能它不会在我的机器上运行。
答案 6 :(得分:2)
Autotools是一场灾难。
生成的./configure
脚本检查过去20年左右在任何Unix系统上都没有的功能。要做到这一点,它会花费大量的时间。
运行./configure
需要很长时间。虽然现代服务器CPU甚至可以有几十个内核,并且每个服务器可能有几个这样的CPU,但./configure
是单线程的。我们仍然有足够多年的摩尔定律,因为CPU内核的数量会随着时间的推移而增加。因此,./configure
所需的时间将保持近似恒定,而由于摩尔定律,平行构建时间每2年减少2倍。或者实际上,我认为由于软件复杂性的增加,利用改进的硬件,./configure
所花费的时间甚至可能会增加。
仅仅为您的项目添加一个文件只需要您运行automake
,autoconf
和./configure
这需要很长时间,然后您可能会发现由于一些重要文件已更改,所有内容都将重新编译。所以只添加一个文件,make -j${CPUCOUNT}
重新编译所有内容。
关于make -j${CPUCOUNT}
。生成的构建系统是递归的。 Recursive make has for a long amount of time been considered harmful
然后,当您安装已编译的软件时,您会发现它无法正常工作。 (想要证明吗?从Github克隆protobuf存储库,检查提交9f80df026933901883da1d556b38292e14836612
,将其安装到Debian或Ubuntu系统,然后pre 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
创建自己的构建系统(并使其具有包容性而非递归性,请遵循&#34;递归制作被视为有害的&#34;纸张的建议),事情以更好的方式运作。此外,如果您的项目是10-100 C语言文件的非常小的项目,并且每个CPU和多个CPU有几十个核心,那么您的构建时间会下降一个数量级,甚至可能下降两个数量级。将自定义自动代码生成工具与基于标准make
的自定义构建系统相关联,而不是处理m4
混乱的autotools,也更加容易。使用标准make
,您至少可以在Makefile
中输入shell命令。
所以,回答你的问题:为什么要使用autotools?答:没有理由这样做。自商业Unix已经过时以来,Autotools已经过时了。而多核CPU的出现使得autotools更加过时了。为什么程序员还没有意识到这一点,这是一个谜。我很高兴在我的构建系统上使用标准make
,谢谢。是的,为C语言头包含生成依赖文件需要花费一些工作量,但是通过不必与autotools战斗来节省工作量。
答案 7 :(得分:0)
我不觉得自己是专家来回答这个问题,但仍然会根据我的经验给你一些比较。
因为在某种程度上它类似于我们应该用C语言(高级语言)编写嵌入式代码而不是用汇编语言编写的原因。 两者都解决了相同的目的,但后者更长,更乏味,更耗时,更容易出错(除非你非常了解处理器的ISA)。 Automake工具和编写自己的makefile的情况也是如此。 编写Makefile.am和configure.ac比编写单个项目Makefile非常简单。