文章目录

  • 1.介绍
  • 2.autotools介绍
    • 2.1GUN编译系统的介绍
    • 2.2 GNU 构建系统的例子
      • 2.2.1 基础安装
      • 2.2.2 标准makefile目标
      • 2.2.3 标准的目录变量
      • 2.2.4 标准配置变量
      • 2.2.5 使用config.site覆盖默认配置设置
      • 2.2.6 并行构建树(又名VPATH构建)
      • 2.2.7 分为两部分的安装
      • 2.2.8 交叉编译
      • 2.2.9 在安装时重命名程序
      • 2.2.10 使用 DESTDIR 构建二进制包
      • 2.2.11 准备发行版
      • 2.2.12 自动依赖关系跟踪
      • 2.2.13 嵌套软件包
    • 2.3 automake能帮助你干什么
    • 2.4 helloworld的例子
      • 2.4.1 创建amhello-1.0.tar.gz
      • 2.4.2 amhello的configure.ac设置说明
      • 2.4.3 amhello的Makefile.am设置说明
    • 3.通用性概念
    • 4.一些实例软件包
      • 4.1一个简单的例子,从起点到终点
      • 4.2 构建true和false
    • 5.创建Makefile.in
    • 6.扫描configure.in
    • 7.目录相关
    • 8.创建程序和库
    • 9.其他派生对象
    • 10.其他gnu工具
    • 11.创建文档
    • 12.安装了些什么
    • 13.清除了些什么
    • 14.需要发布哪些文件
    • 15.对测试套件(test suites)的支持
    • 16.重构Makefiles
    • 17.改变Automake的行为
    • 18.其它规则
    • 19.包含(include)
    • 20.条件(Conditionals)
    • 21.静默构建(Silencing make)
    • 22.什么时候Automake不够用
    • 23.发布`Makefile.in'

个人水平有限,将就看吧,哈哈.觉得不确定的地方放了原文
本文档基于GNU automake官方手册进行翻译。
另外最近在github找到了一个翻译项目,不过也并没有翻译完成

1.介绍

automake是一个根据Makefile.am文件自动生成Makefile.in的工具。每个Makefile.am文件都基本上是由一系列make变量定义组成(偶尔可能也会夹杂规则)。由Makefile.am生成的Makefile.in文件与GNU Makefile标准兼容。
Gun的Make标准文档很长,很复杂,又容易变化,而Automake的目标就是将Makefile维护的负担从GNU维护人员身上移除(把他放在automake维护者身上)。
最典型的automake输入文件就仅仅是一系列变量定义。每个这样的文件都会被处理并创建成一个Makefile.in文件。
Automake确实在某些方面对项目有要求(Automake does constrain a project in certain ways);例如,它假设项目使用Autoconf,并对configure.ac的内容 强制规定了某些限制。
Automake依赖perl来生成Makefile.in文件。然而,由automake创建的发行包完全兼容GUN标准,当编译时,并不需要依赖于perl。

2.autotools介绍

如果你刚刚接触automake,也许你听说过他是autotools系列工具的一部分。也许你已经研究过一个包含configure, configure.ac, Makefile.in, Makefile.am, aclocal.m4等文件组成的包,其中一些文件声称是由Autoconf或Automake生成的。但是这些文件的确切目的和它们之间的关系可能是模糊的。本章的目的是向你介绍这个机制,向你展示它是如何工作的,它有多么强大。如果你从未安装或见过这样的软件包,请不要担心:本章将带您完成它。
如果你需要一些更多插图,或者一个更少一点的以automake为中心的延伸的教学材料,在这里有一些介绍的幻灯片。本章是这个教程第一部分的书面版本。

2.1GUN编译系统的介绍

一个常识是,作为开发人员开发一个新的软件包,你一定需要一个构建系统。
在unix的世界里,这样一个构建系统通常是使用make命令来完成的。你会在Makefile中书写构建包的方法。这个文件 包含了一系列的规则,来用于编译包中的文件。比如程序prog可能是通过链接main.o,foo.o来生成的,而main.o有是通过main.c编译得来。每次执行make的时候,他都会去检查用到的文件是否存在,以及修改时间等等,来决定哪些文件需要去编译或者重新编译,并且运行相关的命令。
当一个包需要在与开发它的平台不同的平台上编译时,它的Makefile通常需要调整。比如他的编译器可能拥有不同的名字或者需要更多的参数。在1991年,David J. MacKenzie厌倦了为20个平台的Makefile进行手动适配。相反,他手工编写了一个名为configure的小shell脚本来自动调整Makefile。编译他的包现在就像运行./configure && make一样简单。
今天,这个过程已经在GNU工程中标准化了。GNU 编码标准声明了GNU 工程的每个软件包应该拥有的configure脚本,以及它应该具有的最小接口。 makefile也应该遵循一些既定的惯例。结果呢?一个统一的构建系统,使安装者几乎不用区分软件包就能安装。在最简单的场景中,安装者所要做的就是解压缩包,运行 ./configure && make && make install ,然后继续安装下一个包。
我们称这个构建系统为GNU构建系统,因为它是从GNU工程发展而来的。然而,它被大量的其他软件包使用:遵循任何现有的约定都有其益处。
autotools是用来为软件包创建GNU构建系统的工具。Autoconf主要用于configure,而Automake用来生成makefile。在没有这些工具的帮助下,创建一个GNU构建系统也是可行的。然而,这是相当繁琐和容易出错的。在对 GNU 构建系统的实际应用进行一些说明之后,我们将再次讨论这个问题。

2.2 GNU 构建系统的例子

在本节中,我们将探讨 GNU 构建系统的几个例子。您可以在随 Automake 分发的amhello-1.0.tar.gz包上重新尝试所有这些示例。如果您的系统上安装了 Automake,您应该在prefix/share/doc/automake/amhello-1.0.tar.gz中找到此文件的副本,其中prefix是配置期间指定的安装前缀(默认为 /usr/local,但是如果 Automake 是由某些 GNU/Linux 发行版安装的,则很可能已设置为/usr ,像我在macos上用brew安装automake后,这个压缩包在/opt/homebrew/share/doc/automake)。如果您没有安装 Automake 的副本,则可以在 Automake 程序包的doc目录中找到此文件的副本。
以下一些用例所呈现的功能实际上是GNU构建系统的扩展。注意:它们并不是GNU编码标准,但它们仍然是Autotools创建的构建系统的一部分。为了简单起见,我们不指出其中的区别。我们的目标是向您展示Autotools创建的构建系统将为您提供的许多功能。

2.2.1 基础安装

一个最常见的安装过程如下所示:

~ % tar zxf amhello-1.0.tar.gz
~ % cd amhello-1.0
~/amhello-1.0 % ./configure
…
config.status: creating Makefile
config.status: creating src/Makefile
…
~/amhello-1.0 % make
…
~/amhello-1.0 % make check
…
~/amhello-1.0 % su
Password:
/home/adl/amhello-1.0 # make install
…
/home/adl/amhello-1.0 # exit
~/amhello-1.0 % make installcheck
…

用户首先解压缩包。在这里和在下面的示例中,为了简单起见,我们将使用非可移植命令tar zxf。在未安装 GNU tar的系统上,此命令应为gunzip -c amhello-1.0.tar.gz | tar xf -
然后,用户进入新创建的目录以运行configure脚本。此脚本将探测系统的各种功能,并最终创建makefile。在这个示例中,只有两个makefile,但在实际项目中,可能还有更多,通常每个目录就会有一个。
然后可以执行make命令。这将构造需要为包构造的所有程序、库和脚本。在我们的示例中,这将编译hello程序。所有文件都是在源码树中就地构造的;我们稍后将看到如何改变这一点。
make check运行包的测试。此步骤不是强制性的,但在决定安装程序之前,确保已生成的程序按预期运行通常是个好主意。我们的示例不包含任何测试,因此运行make check是无操作的。
在构建所有内容并可能经过测试之后,是时候将其安装在系统上了。这意味着将程序、库、头文件、脚本和其他数据文件从源目录复制到系统上的最终目标。make install命令将执行此操作。但是,默认情况下,所有内容都将安装在/usr/local子目录中:二进制文件将进入/usr/local/bin,库将最终进入/usr/local/lib等。这些目录通常不能被任何用户写入,因此我们假设我们必须成为root才能运行 make install 。在我们的示例中,运行make install会将程序hello复制到/usr/local/bin 中,将README复制到/usr/local/share/doc/amhello中。
最后一个可选步骤是运行make installcheck 。此命令可能会对已安装的文件运行测试。 make check测试源代码树中的文件,而make installcheck测试其已安装的副本。后者运行的测试可能与前者运行的测试不同。例如,有些测试无法在源代码树中运行。反过来,某些包的设置使得make installcheck在不同的文件(未安装与已安装)上运行与 make check相同的测试,当源树的布局与安装的布局不同时这个操作就会很有用。此外,它可能有助于诊断不完整的安装。
目前大多数软件包没有任何install check,因为installcheck的存在鲜为人知,它的用处被忽视了。我们的小示例也好不到哪里去:make install check什么也不做。

2.2.2 标准makefile目标

到目前为止,我们已经遇到了在 GNU 构建系统中运行的四种方法:make, make check, make install, 和 make installcheck 。作为参数传递给make的单词check, install和 installcheck称为目标。make 是make all的简写,是 GNU 构建系统中的默认目标。
以下是 GNU 编码标准指定的最有用的目标的列表。

命令 解释
make all 构建程序、库、文档等(与make相同)(ps:按我的理解,make执行的是第一个目标,而第一个目标并不一定必定是all)
make install 安装需要安装的内容,将文件从包的构建树复制到系统目录。
make install-strip 与make install相同,但是将会去除调试符号。有些用户喜欢用空间换取有用的错误报告…(Some users like to trade space for useful bug reports…)
make uninstall 与make install相反:删除已安装的文件。(这需要从当时安装时的同一构建树中运行)
make clean 从构建树中删除 由make all生成的文件。
make distclean 此外,还会删除./configure创建的任何内容。
make check 运行测试套件(如果有)。
make installcheck 检查已安装的程序或库(如果支持)。
make dist 从所有源文件重新创建package-version.tar.gz。

2.2.3 标准的目录变量

GNU 编码标准还指定了变量的层次结构来表示安装目录。其中一些是:

目录变量 默认值
prefix /usr/local
exec_prefix ${prefix}
bindir ${exec_prefix}/bin
libdir ${exec_prefix}/lib
includedir ${prefix}/include
datarootdir ${prefix}/share
datadir ${datarootdir}
mandir ${datarootdir}/man
infodir ${datarootdir}/info
docdir ${datarootdir}/doc/${PACKAGE}

这些目录中的每一个都有一个角色,通常从其名称中可以明显看出。在包中,任何可安装文件都将安装在这些目录之一中。例如,在amhello-1.0中,hello程序将安装在bindir目录中。此目录的默认值为/usr/local/bin,但用户可以在调用configure时提供不同的值。此外, README 将安装到docdir中,默认为 /usr/local/share/doc/amhello.

作为用户,如果您希望在自己的帐户上安装软件包,可以按以下步骤操作:

~/amhello-1.0 % ./configure --prefix ~/usr
…
~/amhello-1.0 % make
…
~/amhello-1.0 % make install
…

这样所有的文件都会被复制到~/usr下,但是这样可能可执行文件不在PATH中

2.2.4 标准配置变量

GNU 编码标准还定义了一组在构建期间使用的标准配置变量。以下是一些:

命令 解释
CC C 编译器命令
CFLAGS C 编译器标志
CXX C++编译器命令
CXXFLAGS C++编译器标志
LDFLAGS 链接器标志
CPPFLAGS C/C++ 预处理器标志

configure通常能够为这些变量设置适当的值,但在某些情况下,您可能希望覆盖它们。例如,你可能安装了多个版本的编译器,并希望使用另一个版本,还可能将头文件安装在了编译器的默认搜索路径之外,或者可能把库安装在了链接器之外。
下面介绍如何调用configure以强制将gcc-3用作 C 编译器,在编译时使用来自~/usr/include头文件,在链接时使用来自~/usr/lib 库。

~/amhello-1.0 % ./configure --prefix ~/usr CC=gcc-3 \
CPPFLAGS=-I$HOME/usr/include LDFLAGS=-L$HOME/usr/lib

同样,这些变量的完整列表将显示在./configure --help的输出中。

2.2.5 使用config.site覆盖默认配置设置

使用相同的设置安装多个包时,可以方创建一个文件来保存常用设置。如果名为prefix/share/config.site 的文件存在,configure则会在其执行开始时先应用这个文件
回想一下上一节中的命令:

~/amhello-1.0 % ./configure --prefix ~/usr CC=gcc-3 \
CPPFLAGS=-I$HOME/usr/include LDFLAGS=-L$HOME/usr/lib

假设我们要在~/usr中安装许多软件包,并且总是希望使用CC, CPPFLAGS和 LDFLAGS的这些定义,我们可以通过创建~/usr/share/config.site来自动执行:

test -z "$CC" && CC=gcc-3
test -z "$CPPFLAGS" && CPPFLAGS=-I$HOME/usr/include
test -z "$LDFLAGS" && LDFLAGS=-L$HOME/usr/lib

现在,每当configure脚本使用~/usr前缀时,它将执行上述config.site的内容并定义这三个变量。

~/amhello-1.0 % ./configure --prefix ~/usr
configure: loading site script /home/adl/usr/share/config.site
…

需要注意的是,config.site并不是固定位置的–他是根据prefix而决定使用哪一个的

2.2.6 并行构建树(又名VPATH构建)

GNU 构建系统分为了两个树:源代码树和构建树。这两个目录可能相同,也可能不同。
源码树根植于包含了configure脚本的目录中。它包含所有源文件(分发的文件),并且可能分成了多个子目录。
构建树植根于运行configure时所在的目录,这个目录也会保存所有对象文件、程序、库以及从源码构建生成的其他派生文件(因此未分发)。构建树通常具有与源树相同的子目录布局;其子目录由构建系统自动创建。
如果configure在它自己的目录中执行,则源代码树和构建树将混合在一起:派生文件在其源代码相同的目录中构建。在我们的第一个安装示例中就是这种情况(请参阅2.2.1 基础安装)。
用户的一个常见需求是,他们希望将所有生成的文件限制在单个目录中,以保持其源代码目录整洁。以下是我们如何在名为 build/的构建树(即子目录)中运行configure,以保存其创建所有内容。

~ % tar zxf ~/amhello-1.0.tar.gz
~ % cd amhello-1.0
~/amhello-1.0 % mkdir build && cd build
~/amhello-1.0/build % ../configure
…
~/amhello-1.0/build % make
…

这种源树和构建树不同的构建方式通常称为并行构建或 VPATH 构建。并行构建这种说法具有误导性:“并行”一词代表了构建树投影于的源码树的方式,它并不代表构建命令的并发运行(the word parallel is a reference to the way the build tree shadows the source tree, it is not about some concurrency in the way build commands are run.)。出于这个原因,我们在下面使用VPATH构建的名称来描述此类配置。VPATH 是make的一个特性的名字(请参阅 GNU Make Manual 中的 VPATH Search Path for All Prerequisites)。

VPATH 构建还有其他有趣的用途。一种是使用多个配置构建相同的代码。例如:

~ % tar zxf ~/amhello-1.0.tar.gz
~ % cd amhello-1.0
~/amhello-1.0 % mkdir debug optim && cd debug
~/amhello-1.0/debug % ../configure CFLAGS='-g -O0'
…
~/amhello-1.0/debug % make
…
~/amhello-1.0/debug % cd ../optim
~/amhello-1.0/optim % ../configure CFLAGS='-O3 -fomit-frame-pointer'
…
~/amhello-1.0/optim % make
…

对于网络文件系统,可以使用类似的方法在不同的计算机上构建相同的源。例如,假设源代码存在于一个共享目录中由两个不同的平台的主机HOST1 和HOST2访问。

~ % cd /nfs/src
/nfs/src % tar zxf ~/amhello-1.0.tar.gz

在第一台主机上,您可以创建一个本地构建目录:

[HOST1] ~ % mkdir /tmp/amh && cd /tmp/amh
[HOST1] /tmp/amh % /nfs/src/amhello-1.0/configure
...
[HOST1] /tmp/amh % make && sudo make install
...

(这里我们假设安装者已经配置sudo,因此可以使用root权限执行)。

在第二台主机上,你可能同时执行完全相同的操作:

[HOST2] ~ % mkdir /tmp/amh && cd /tmp/amh
[HOST2] /tmp/amh % /nfs/src/amhello-1.0/configure
...
[HOST2] /tmp/amh % make && sudo make install
...

在这种情况下,/nfs/src/amhello-1.0目录完全可以为只读。事实上,VPATH 构建也是从只读介质(如 CD-ROM)构建软件包的一种手段。(在GNU工程发展到如此之大之前,FSF曾经销售带有未打包源代码的CD-ROM。)

2.2.7 分为两部分的安装

在我们的上一个示例中(请参阅并行构建树(又名 VPATH 构建)),源代码树由两个主机共享,但编译和安装是在每个主机上分别完成的。
GNU 构建系统还支持网络设置,其中哪些安装文件应在多个主机之间共享(The GNU Build System also supports networked setups where part of the installed files should be shared amongst multiple hosts.这句咋翻译的…)。它通过将体系结构相关文件从体系结构无关的文件中区分开来,并提供两个Makefile目标来分别安装他们的文件来实现此目的。
对依赖于体系结构的文件,对应目标是install-exec。对于体系结构无关的文件,对应目标是install-data。到目前为止我们使用的命令make install可视为make install-exec install-data的简写。
从 GNU 构建系统的角度来看,依赖于体系结构的文件和与体系结构无关的文件之间的区别完全基于指定其安装位置的目录变量。在我们之前提供的目录变量列表中(请参阅2.2.3 标准的目录变量),所有基于exec-prefix的变量都指定为与体系结构相关的目录,这些目录的文件将通过make install-exec安装。而其他的则指定为独立于体系结构的目录,并将通过make install-data来安装。有关更多详细信息,请参阅The Two Parts of Install。

让我们再来看下之前的双主机安装的例子,假设(1)我们要直接在/usr中安装软件包,并且(2)/usr/share目录由两台主机共享。

在第一台主机上,我们将运行

[HOST1] ~ % mkdir /tmp/amh && cd /tmp/amh
[HOST1] /tmp/amh % /nfs/src/amhello-1.0/configure --prefix /usr
...
[HOST1] /tmp/amh % make && sudo make install
...

但是,在第二台主机上,我们只需要安装特定于体系结构的文件。(因为与体系结构无关的文件只需一份)

[HOST2] ~ % mkdir /tmp/amh && cd /tmp/amh
[HOST2] /tmp/amh % /nfs/src/amhello-1.0/configure --prefix /usr
...
[HOST2] /tmp/amh % make && sudo make install-exec
...

ps:这里的意思应该是说,在第二台主机,与架构相关的部分通过make install-exec安装了,而与架构无关的部分(比如帮助手册等等)将共享第一台主机安装的。
在具有安装检查的软件包中,运行make installcheck以验证软件包是否正常工作(尽管明显是部分安装)是有意义的。

2.2.8 交叉编译

交叉编译是在一个平台上构建一个将在另一个平台上运行的二进制文件。说到交叉编译,区分执行编译的构建平台(build)和生成的可执行文件运行的主机平台(host)非常重要。以下configure选项用于指定他们:

字段 含义
--build=build 构建包的系统。
--host=host 将运行被构建的程序和库的系统。

当使用--host时,configure将搜索此平台的交叉编译套件。交叉编译工具通常将其目标体系结构作为其名称的前缀。例如,我的 MinGW32 交叉编译器包含i586-mingw32msvc-gcc 、i586-mingw32msvc-ld 、i586-mingw32msvc-as 等编译工具。

以下是我们如何在 i586-mingw32msvc架构的GNU/Linux PC 上进行构建amhello-1.0。

~/amhello-1.0 % ./configure --build i686-pc-linux-gnu --host i586-mingw32msvc
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for i586-mingw32msvc-strip... i586-mingw32msvc-strip
checking for i586-mingw32msvc-gcc... i586-mingw32msvc-gcc
checking for C compiler default output file name... a.exe
checking whether the C compiler works... yes
checking whether we are cross compiling... yes
checking for suffix of executables... .exe
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether i586-mingw32msvc-gcc accepts -g... yes
checking for i586-mingw32msvc-gcc option to accept ANSI C...
…
~/amhello-1.0 % make
…
~/amhello-1.0 % cd src; file hello.exe
hello.exe: MS Windows PE 32-bit Intel 80386 console executable not relocatable

--host-和 --build选项通常是我们进行交叉编译时需要指定全部内容。唯一的例外是,如果正在构建的包本身就是一个交叉编译器:我们需要第三个选项来指定其目标体系结构。比如在x86平台编译一个在arm平台上运行的编译器,这个(刚刚编译的)编译器编译的程序运行于powerpc。

字段 含义
--target=target 构建编译器工具时:编译的工具创建的程序运行的平台

例如,在安装GCC(GNU编译器集合)时,我们可以用–target=target来指定我们要将GCC构建为target的交叉编译器。同时使用–build和–target,我们可以交叉编译一个交叉编译器;这种三向交叉汇编被称为Canadian cross.

有关这些configure选项的详细信息,请参阅《autoconf手册》中的Specifying the System Type。

2.2.9 在安装时重命名程序

GNU 构建系统提供了在安装可执行文件和man手册之前自动重命名它们的方法。当你想安装的命令已经存在,你不想覆盖他时,这种方法会很方便。例如,您可能希望安装 GNU的tar为gtar,这样你就可以将其与供应商的tar命令区分开来。
这可以使用这三个configure选项之一来完成。

字段 含义
–program-prefix=prefix 在已安装的程序名称前面附加prefix。
–program-suffix=suffix 追加suffix到已安装的程序名称后面。
–program-transform-name=program 在已安装的程序名称上运行sed program。

例如,以下命令将hello安装为/usr/local/bin/test-hello :

~/amhello-1.0 % ./configure --program-prefix test-
…
~/amhello-1.0 % make
…
~/amhello-1.0 % sudo make install
…

2.2.10 使用 DESTDIR 构建二进制包

当系统管理员必须在许多主机上部署和升级软件包时,GNU构建系统的make install和make uninstall接口可能不能完全符合他们的需求。换句话说,GNU构建系统并不能取代软件包管理器。
这些包管理器通常需要知道包安装了哪些文件,因此仅仅一个make install是不够的。
可以使用DESTDIR变量执行分段安装。当执行configure时,这个包应当被配置为最终安装位置(例如--prefix=/usr),但是当运行make install时,你可以使用DESTDIR 参数,指定真正要安装目录的绝对路径。从这个目录中,很容易查看哪些文件安装在何处,最后通过某种方式将它们复制到最终位置。

下面的例子展示了,如何创建一份所有要安装的文件的快照。

~/amhello-1.0 % ./configure --prefix /usr
…
~/amhello-1.0 % make
…
~/amhello-1.0 % make DESTDIR=$HOME/inst install
…
~/amhello-1.0 % cd ~/inst
~/inst % find . -type f -print > ../files.lst
~/inst % tar zcvf ~/amhello-1.0-i686.tar.gz `cat ../files.lst`
./usr/bin/hello
./usr/share/doc/amhello/README

在此示例之后,amhello-1.0-i686.tar.gz 只要在许多主机上的根目录/解压缩就可以使用了。(使用cat ../files.lst而不是.作为tar的参数可以避免存档中每个子目录的条目:我们不希望恢复/ 、/usr等的修改时间。)(Using cat ../files.lst instead of ‘.’ as argument for tar avoids entries for each subdirectory in the archive: we would not like tar to restore the modification time of /, /usr/, etc.)
请注意,在为多个体系结构生成包时,使用make install-data和make install-exec(请参阅2.2.7 分为两部分的安装)在单个包中收集与体系结构无关的文件可能会很有用。
有关详细信息,请参阅 What Gets Installed。

2.2.11 准备发行版

我们已经提到过make dist。此目标收集所有源文件和构建系统的必要部分,以创建名为package-version.tar.gz
的压缩包。
另一个更有用的命令是make distcheck 。distcheck目标在构造package-version.tar.gz时与dist一样好,但它另外还执行了到目前为止提出的大多数用例的测试:

  • 它尝试对软件包进行完整编译(请参阅基本安装):解压缩新构造的压缩包,运行make 、make check 、 make install以及 make installcheck,甚至是make dist。
  • 它使用只读源代码树测试VPATH构建(请参阅并行构建树(又名VPATH构建)),
  • 它确保make clean 、make distclean 、make uninstall 没忽略任何应当删除的文件(标准makefile目标)
  • 检查DESTDIR安装是否正常工作(请参见使用 DESTDIR 构建二进制包)。

所有这些操作都是在临时目录中执行的,因此不需要 root 权限。这种子目录的确切位置和确切结构(提取的源代码的位置,临时构建和安装目录的命名方式以及它们嵌套的深度等)将被视为可以随时更改的实现细节;所以不要依赖它。

发布执行make distcheck失败的包意味着我们提供的编译目标中的某些将不起作用,这会使用户会感到失望。因此,最好仅在make distcheck成功后才发布包。当然,这并不意味着该软件包将完美无缺,但至少它可以帮你防止犯那些从未听说过distcheck的人所发布的软件包中所犯的一些令人尴尬的错误(例如由于拼写错误而使得DESTDIR无法正常工作,或者包文件被make clean删除,甚至VPATH构建不起作用)。

请参阅 Creating amhello-1.0.tar.gz,以使用make distcheck重新创建amhello-1.0.tar.gz 。有关 distcheck的详细信息,请参阅See Checking the Distribution

2.2.12 自动依赖关系跟踪

依赖关系跟踪是作为编译的副产物执行的。每次构建系统编译源文件时,它都会计算其依赖项列表(在C语言中,这些依赖项是正在编译的源代码中所包含的头文件)。每当运行make时,如果依赖项发生了更改,则将重新构建依赖项文件。
默认情况下,Automake会生成用于自动依赖关系跟踪的代码,除非开发人员选择覆盖它;有关详细信息,请参阅 Automatic dependency tracking。

当configure执行时,您可以看到它探测每个编译器的依赖关系机制(有好几种机制可以被使用):

~/amhello-1.0 % ./configure --prefix /usr
…
checking dependency style of gcc... gcc3
…

由于依赖项仅作为编译的副产物进行计算,因此在首次生成包时不存在依赖项信息。这没关系,因为无论如何所有文件都需要被构建:make不必决定需要重新编译哪些文件。实际上,依赖项跟踪对于一次性生成是完全无用的,并且configure有一个选项可以禁用此功能:

字段 含义
--disable-dependency-tracking 加快一次性构建速度

一些编译器不提供任何适用的方法来派生依赖项列表,而需要单独的运行(可能是另一个工具)来计算这些依赖项。这些方法带来的性能损失可能很多,因此需要在默认情况下禁用它们。。必须为configure传递 --enable-dependency-tracking选项才能激活它们。

字段 含义
--enable-dependency-tracking 不要拒绝慢速依赖关系提取程序。

参见Automake简史中的 Dependency Tracking Evolution,了解Automake多年来使用的不同依赖跟踪方案的一些讨论。

2.2.13 嵌套软件包

尽管我们不推荐刚使用Autotools的人使用嵌套包,但在这个小型推广教程之旅中,这是一个值得一提的不错功能。
自动解析的包(这意味着其构建系统已由 Autoconf 创建的包)可以嵌套到任意深度。

一个典型的设置是,包 A 将在子目录中分发它需要的库之一。这个库B是一个完整的软件包,有自己的GNU构建系统。A的脚本将运行B的脚本作为其执行的一部分;构建和安装 A 也将构建和安装 B.为 A 生成分发包时也将包括 B。

嵌套可以像这样包含多个包。GCC对嵌套的功能使用很多。这为安装者提供了单独的一个用于配置,构建和安装的软件包,与此同时还允许开发人员独立处理子包。

配置嵌套包时,提供给顶层configure的选项将以递归方式传递给嵌套的包的configure。当每个包不支持某个选项时,将会忽略这个选项,并认为这个选项是用于配置别的包的。

configure --help=recursive可用于显示所有包含的包的支持的选项

有关示例设置,请参阅 Nesting Packages。

2.3 automake能帮助你干什么

你可能有很多原因不想自己实现 GNU 构建系统(自己编写configure脚本和Makefile文件)。

  • 正如我们所看到的,GNU构建系统有很多功能(参见2.2 GNU 构建系统的例子)。有些用户可能会期望那些因为你不需要它们所以未添加的功能。
  • 以可移植方式实现这些功能是既困难又费劲的。想想为那些可能不熟练的系统编写可移植shell脚本和可移植的Makefile。请参阅autoconf手册中的Portable Shell Programming,以说服自己。
  • 你必须升级你的设置以遵循GNU编码标准的变更。

GNU Autotools将所有负担从你身上移走,并提供:

  • 通过简单的指令就能创建可移植,完整和自包含的GNU构建系统的工具。自包含意味着生成的构建系统不需要 GNU Autotools就能运行。
  • 集中的进行修复和改进更改(A central place where fixes and improvements are made):可移植性问题的错误修复将使每个包都被修复。

然而,也许也存在一些原因,使你可能不想使用autotools…例如,您可能已经在使用(或习惯于)另一个不兼容的构建系统。autotools只有在您接受 GNU 构建系统的概念时才有用。对于想完全控制自己编译系统的人来说,使用Autotools会感到沮丧。

2.4 helloworld的例子

在本节中,我们将从头开始重新创建amhello-1.0。第一小节说明如何调用 Autotools 来实例化 GNU 构建系统,而第二小节则解释了 Autotools 读取的configure.ac及Makefile.am的含义。

2.4.1 创建amhello-1.0.tar.gz

以下是我们如何从头开始重新创建amhello-1.0.tar.gz。该软件包非常简单,因此我们只需要写入5个文件。(如果您不想编写它们,则可以从随 Automake 一起分发的最终版本中复制它们。)

在空目录中创建以下文件。

  • src/main.c是hello程序的源文件。我们将其存储在src/子目录中,因为在之后,当软件包扩展时,还有为存放man手册的man/,存放数据文件的data/目录等。
~/amhello % cat src/main.c
#include <config.h>
#include <stdio.h>int
main (void)
{puts ("Hello World!");puts ("This is " PACKAGE_STRING ".");return 0;
}

README包含一些非常有限的文档,用于我们的小软件包。

~/amhello % cat README
This is a demonstration package for GNU Automake.
Type 'info Automake' to read the Automake manual.

Makefile.am和src/Makefile.am包含了这两个目录的Automake指令。

~/amhello % cat src/Makefile.am
bin_PROGRAMS = hello
hello_SOURCES = main.c
~/amhello % cat Makefile.am
SUBDIRS = src
dist_doc_DATA = README

最后,configure.ac包含用于创建configure脚本的 Autoconf 指令。

~/amhello % cat configure.ac
AC_INIT([amhello], [1.0], [bug-automake@gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefilesrc/Makefile
])
AC_OUTPUT

拥有这五个文件后,就可以运行Autotools来实例化构建系统了。使用autoreconf命令执行此操作,如下所示:

~/amhello % autoreconf --install
configure.ac: installing './install-sh'
configure.ac: installing './missing'
configure.ac: installing './compile'
src/Makefile.am: installing './depcomp'

此时,构建系统已完成。
执行完命令后文件的变化情况如下:

~/amhello %  ls
Makefile.am    aclocal.m4     config.h.in    depcomp        src
Makefile.in    autom4te.cache configure      install-sh
README         compile        configure.ac   missing

除了其输出中提到的三个脚本之外,您还可以看到autoreconf创建了其他四个文件:configure、config.h.in、Makefile.in和 src/Makefile.in 。后面三个文件是在执行configure时将会适配系统的模板文件,并会生成config.h,Makefile和src/Makefile(The latter three files are templates that will be adapted to the system by configure under the names config.h, Makefile, and src/Makefile. ).

~/amhello % ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands

您可以看到Makefile 、src/Makefile 和config.h 是在configure探测完系统后在最后创建的。现在可以运行我们想要的所有目标(请参阅 Standard Makefile Targets)。例如:

~/amhello % make
…
~/amhello % src/hello
Hello World!
This is amhello 1.0.
~/amhello % make distcheck
…
=============================================
amhello-1.0 archives ready for distribution:
amhello-1.0.tar.gz
=============================================

请注意,只有当 GNU 构建系统不存在时,才需要运行autoreconf。当您稍后更改Makefile.am或 configure.ac中的一些指令时,构建系统的相关部分将在您执行make时自动重新生成。
autoreconf是一个脚本,它以正确的顺序调用 autoconf、automake 和一堆其他命令。如果你是刚开始用这些工具,那么没必要一定弄清楚所有这些工具应以何种顺序调用以及他们的作用。但是,由于 Autoconf 和 Automake 都有单独的手册,因此需要了解的重要一点是,autoconf负责从configure.ac创建configure ,而automake负责从Makefile.am 和configure.ac创建Makefile.in。在寻求答案时,这至少应该引导您到正确的手册。
autoconf:configure.ac->configure,config.h.in
automake:Makefile.am,configure.ac->Makefile.in
configure:config.h.in->config.h;Makefile.in->Makefile

2.4.2 amhello的configure.ac设置说明

让我们从configure.ac的内容开始。

AC_INIT([amhello], [1.0], [bug-automake@gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefilesrc/Makefile
])
AC_OUTPUT

此文件由 autoconf(创建 configure) 和automake (创建各种 Makefile.in) 读取。它包含一系列M4宏,这些宏将作为shell代码扩展以最终形成configure脚本。我们不会详细介绍此文件的语法,因为 Autoconf 手册中有一整节介绍它(请参阅 Autoconf 手册 中的 Writing configure.ac)。

前缀为AC_前缀的宏是 Autoconf 宏,记录在 Autoconf 手册中(请参见《 Autoconf手册》中的 Autoconf Macro Index )。以AM_开头的宏是Automake宏,本手册后面将对此进行介绍(请参见 Macro Index)。

configure.ac的最前面两行初始化了 Autoconf 和 Automake 。 AC_INIT将包的名称、版本号和有关包的错误报告的联系人地址作为参数(例如,此地址在./configure --help的末尾输出)。在将此设置调整为您自己的软件包时,请不要盲目复制Automake的地址:使用软件包的邮件列表或您自己的邮件地址。

AM_INIT_AUTOMAKE的参数是传递给automake的一系列参数(请参见 Changing Automake’s Behavior)。-Wall和-Werror选项使automake打开所有告警并将其报告为错误。我们在这里说的是Automake的警告,例如Makefile.am中的可疑说明。这与编译器如何调用完全无关,即使它可能支持具有相似名称的选项。在开始处理软件包时,使用-Wall -Werror是一个安全的设置:您不想错过任何问题。之后你可能会决定放松一下。foreign选项告诉Automake,此软件包将不遵循GNU标准。GNU 软件包应始终分发其他文件,如ChangeLog、AUTHORS等。我们不想automake在我们的小示例中提示这些丢失的文件。

AC_PROG_CC行使configure脚本搜索 C 编译器并使用其名称定义CC变量。Automake 生成的src/Makefile.in文件使用CC变量来构建hello ,因此当configure从src/Makefile.in创建src/Makefile时,它将使用找到的值来定义CC。如果当Automake创建Makefile.in时,要使用的CC变量在configure.ac中没被定义,它将建议您添加对AC_PROG_CC的调用。

AC_CONFIG_HEADERS([config.h])调用将使configure脚本创建一个config.h文件,该文件收集configure. ac中其他宏定义的’ #define '。在我们的例子中,AC_INIT宏已经定义了其中的一些。下面是configure运行后config.h的摘要:

…
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "bug-automake@gnu.org"/* Define to the full name and version of this package. */
#define PACKAGE_STRING "amhello 1.0"
…

正如你可能注意到的,src/main.c包含config.h,所以它可以使用PACKAGE_STRING。在真实的项目中,config.h可能会变得非常大,在系统中探测每个特性都需要一个’ #define '。

AC_CONFIG_FILES宏声明了一个文件列表,这个列表里的文件就是configure从那些*.in模板创建出的文件的列表。Automake还扫描这个列表以找到必须处理的Makefile.am文件。(记住这一点很重要:当添加一个新目录到你的项目,你应该添加它的Makefile到这个列表,否则Automake将永远不会处理你新写在那个目录里的Makefile.am)

最后,AC_OUTPUT行是一个关闭命令,它实际生成脚本的一部分,即负责创建用AC_CONFIG_HEADERS和AC_CONFIG_FILES注册的文件的那部分。(Finally, the AC_OUTPUT line is a closing command that actually produces the part of the script in charge of creating the files registered with AC_CONFIG_HEADERS and AC_CONFIG_FILES.)

当开始一个新项目时,我们建议您从这样一个简单的 configure.ac开始,并逐渐添加它需要的其他测试。autoscan命令也可以建议包可能需要的一些测试(请参阅使 Using autoscan to Create configure.ac)。

2.4.3 amhello的Makefile.am设置说明

我们现在转到src/Makefile.am .此文件包含了用来构建和安装hello的Automake指令。

bin_PROGRAMS = hello
hello_SOURCES = main.c

一个Makefile.am具有与普通Makefile相同的语法。当automake处理Makefile.am时,它复制整个文件到Makefile.in(稍后此文件将会被configure转为Makefile),但是某些变量定义将生成一些构建规则和其他变量。通常Makefile.am只包含如上所述的变量定义列表,但它们还可以包含其他可以automake不会解析直接传递的变量和规则定义。

以_PROGRAMS结尾的变量是特殊的变量,它列出了生成的Makefile应该构建的程序。在Automake语言中,这个_PROGRAMS后缀被称为primary;Automake可以识别其他的primary,如_SCRIPTS, _DATA,_LIBRARIES等,它们对应于不同类型的文件。

bin_PROGRAMS的’ bin '部分告诉automake,生成的程序应该安装在bindr中。回想一下,GNU构建系统使用一组变量来表示目标目录,并允许用户自定义这些位置(参见 Standard Directory Variables)。任何这样的目录变量都可以放在主目录(省略dir后缀)前面,告诉automake将列出的文件安装在哪里。

程序需要从源文件构建,因此对于_PROGRAMS变量中列出的每个程序prog, automake将查找另一个名为prog_SOURCES的变量,这个变量将列出它的源文件。可能有多个源文件:它们都将被编译并链接在一起。

Automake还知道在创建tarball时需要分发的源文件(不同于构建的程序(unlike built programs))。因此hello_SOURCES声明的一个副作用是,main.c将成为make dist创建的tarball的一部分。

最后,这里有一些关于顶层Makefile.am的解释。

SUBDIRS = src
dist_doc_DATA = README

SUBDIRS是一个特殊变量,他列出了make在处理当前目录之前应递归处理的所有目录。因此,即使我们从顶层运行它,这行也使用make构建src/hello。此行还会导致make install在安装README之前进行安装src/hello(虽然说这个顺序并不是很重要)。

dist_doc_DATA = README行导致README被分发并安装在docdir中。列出_DATA primary的文件不会自动成为使用make dist构建的tarball的一部分,所以我们添加了dist_前缀,以便分发它们。然而,对于README来说就没有这个必要了:automake会自动分发它遇到的任何README文件(自动分发的其他文件列表由automake——help提供)。因此,第二行代码的唯一重要作用是在make安装期间安装README。

本例中没有涉及的一件事是从程序代码访问安装目录值(请参阅 Standard Directory Variables),也就是说,将它们转换为已定义的宏。关于这个,请参见在Autoconf手册中的Defining Directories。

note:下述内容是以王立 1999.12.17翻译的内容为基础进行修改适配的,因为新的automake文档已与原先不同,计划补充新增的内容,调整修改的内容,侵删。
待整理

3.通用性概念

4.一些实例软件包

本节包含了两个小例子。第一个例子假定你已经拥有了一个使用autoconf的,手动创建过Makefile的工程,并且你想用转而使用automake来编译他。关于这两个工具,可以去看前面的hello world的例子(2.4 A Small Hello World)。

4.1一个简单的例子,从起点到终点

让我们假定你刚刚写完zardoz,一个是你的头从一个漩涡漂流到另一个漩涡的程序(a program to make your head float from vortex to vortex. )。你已经使用了autoconf以提供一个可移植的框架,但你的`Makefile.in’还未完成,所以你需要automake。

第一步是更新你的`configure.in’以包含automake需要的命令。完成这一步的最简单方式是在AC_INIT之后添加AM_INIT_AUTOMAKE:

AC_INIT([zardoz], [1.0])
AM_INIT_AUTOMAKE
…

因为你的程序不含有任何复杂性的因素(例如,它不使用gettext,它不需要共享库),你已经完成了这一步工作。很容易吧!

现在你必须重新生成configure。但为此,你需要告诉autoconf 如何找到你使用的新宏。完成该任务的最简单的方式是使用aclocal程序为你生成你的aclocal.m4。但是等等…你已经有了一个aclocal.m4,这是因为你必须为你的程序写一些宏。aclocal允许你把你自己的宏放到 acinclude.m4中去,所以简单地改名并且运行:

mv aclocal.m4 acinclude.m4
aclocal
autoconf

现在是你为zardoz写的Makefile.am的时候了。 zardoz是一个用户程序,所以你需要把它安装到其它用户程序安装的地方去。 zardoz还有一些Texinfo文档。你的configure.in脚本使用 AC_REPLACE_FUNCS,因此你需要与@LIBOBJS@连接。所以这里你写:

bin_PROGRAMS = zardoz
zardoz_SOURCES = main.c head.c float.c vortex9.c gun.c
zardoz_LDADD = @LIBOBJS@info_TEXINFOS = zardoz.texi

现在你运行automake --add-missing以生成你的`Makefile.in’ 并且得到任何你可能需要的附加文件,现在你完成了你的任务!

4.2 构建true和false

这是另一个例子。他展示了如何从同一份源文件(true.c)产生两个程序(true和false)。困难的部分是,每个true.c的编译需要不同的cpp标志

bin_PROGRAMS = true false
false_SOURCES =
false_LDADD = false.otrue.o: true.c$(COMPILE) -DEXIT_CODE=0 -c true.cfalse.o: true.c$(COMPILE) -DEXIT_CODE=1 -o false.o -c true.c

5.创建Makefile.in

6.扫描configure.in

7.目录相关

8.创建程序和库

9.其他派生对象

10.其他gnu工具

11.创建文档

12.安装了些什么

13.清除了些什么

14.需要发布哪些文件

15.对测试套件(test suites)的支持

16.重构Makefiles

17.改变Automake的行为

18.其它规则

19.包含(include)

20.条件(Conditionals)

21.静默构建(Silencing make)

22.什么时候Automake不够用

23.发布`Makefile.in’

automake中文手册_incomplete相关推荐

  1. GNU Bison 2.1 中文手册

    20060121 GNU Bison 2.1中文手册翻译完成 Bison 2.1 是Bison最新版本.该版本的最大改进就是支持以C++语言做为输出,并且在分析器的本地化输出中有多项改进.Bison的 ...

  2. Smarty中文手册,Smarty教程,Smarty模板的入门教材

    Smarty中文手册,Smarty教程,Smarty模板的入门教材 首先,这份Smarty中文手册的翻译工作是由喜悦国际村村民自发组织的,不代表任何人的意见和观点.对他们的无私奉献精神,我们表示感谢, ...

  3. man nfsd(rpc.nfsd中文手册)

    本人译作集合:http://www.cnblogs.com/f-ck-need-u/p/7048359.html rpc.nfsd(8) System Manager's Manual rpc.nfs ...

  4. CSS2.0中文手册(CHM版)

    Div+Css是现在网站架设的一个趋势,应用Css对于网站有诸多的好处.本教程是沈小雨2002年制作的 Css2.0中文手册,对学习CSS和查询CSS属性非常有帮助. Css2.0中文手册针对的是已有 ...

  5. iPhone开发环境搭建全过程 iPhone手机开发内容,中文手册

    http://3g.edu.csdn.net/kecheng/iphone.html  iPhone手机开发内容 http://www.docin.com/p-34874880.html# iPhon ...

  6. Apache2.2中文手册

    Apache2.2中文手册 CHM格试 转载于:https://blog.51cto.com/zjcookies/114174

  7. PostgreSQL9.3中文手册的在线纠错

    PostgreSQL9.3中文手册已经在PG中国社区的官网上正式发布了,下面是网址: http://www.postgres.cn/docs/9.3 然而翻译中难免会有一些小错误.所以我们在在线手册的 ...

  8. 英巴卡迪诺新年战略:支持Linux提供中文手册

    提到英巴卡迪诺Embarcadero公司可能会有人感到陌生但是提到其旗下的应用程序开发工具Delphi和C++Builder相信很多开发者都会有与此相关的记忆.从这几年英巴卡迪诺的产品升级和市场推广来 ...

  9. Ansible中文手册

    中文手册链接地址:http://www.simlinux.com/archives/409.html http://www.simlinux.com/books/Ansible-notes.pdf 右 ...

最新文章

  1. eclipse java jdk_设置Eclipse和Java JDK
  2. Redux之compose
  3. Html5 Canvas斗地主游戏
  4. Date类的构造方法以及成员方法220
  5. 安装Samba服务器
  6. 语言学博士、Kaggle数据分析师,她说:读研不是必选项,这4项技能学校不教
  7. 十九、python沉淀之路--装饰器
  8. 怎么用c语言调用其他程序,求助:1个调用其他程序的C语言(或C++)程序
  9. 袖珍计算机英语手册,英语袖珍迷你系列__中考英语速记手册__刘国婷.pdf
  10. Excel自定义格式日期计算问题
  11. C语言 分支语句:if 语句和 switch语句
  12. 360众测靶场云文件服务器,360 政企安全官网_帮助应对高级威胁攻击
  13. 信息收集之 绕过CDN获取真实IP地址
  14. 【190222】VC++ 社区视频监控系统源代码
  15. 鲸探发布点评:8月19日发售《小窗白云与凿山骨》数字藏品
  16. 带武器的格斗游戏,武器带回血
  17. java 对接中国银联 云闪付
  18. ffmpeg去除水印
  19. Q新闻丨Java 9正式版恐再延期;顺丰菜鸟口水战涉及阿里云;编程语言排行榜Python第四;盲人程序员背百万字符,用耳朵编程...
  20. linux docker升级,Docker 升级到最新版本

热门文章

  1. C++:error C4996解决方法
  2. [幽默笑话]2006年高考作文爆笑集锦
  3. 苹果cmsV10x在线视频网站源码
  4. matlab的quantile函数,Quantile 函数详解
  5. 生信-RPKM与FPKM学习[转载]
  6. libcef-cefsimple简单解析-涉及对象及关键类分析-CefApp-CefClient-CefDisplayHandler(七)
  7. ASTM E595真空出气释气脱气试验最新标准
  8. web项目---severlet简介
  9. python pygame 动画_Python pygame制作动画跑马灯
  10. 利用AStyle对C++代码进行自动化风格规范管理