本系列文章均翻译自Automake官方文档:Automake Manual,github同步项目:question
Automake是从Makefile.am(定义一系列make变量的文件)自动生成Makefile.in文件的工具。生成的Makefile.in符合GNU Makefile 标准。
因为不同的平台需要修改Makefile,所以编写configure
脚本自动修改Makefile,再执行./configure && make && make install
命令安装包,形成了GNU构建系统。
Autotools
是为包创建GNU构建系统的工具;Autoconf
主要关注configure
;Automake
主要关注Makefile
。
当安装一个程序时,安装步骤有以下几步:
note:
有一些可配置变量,可以通过./configure --help
查看完整版
如果想配置系统默认变量,可以修改/usr/local/share/config.site
文件中指定
Directory variable Default value
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}
通过./configure --help
查看完整版。
可以在运行时改变这些目录:./configure --prefix ~/usr
。
源码树:包含了configure文件的所有源文件
构建树:在源码树的基础上,包含上运行configure之后派生出来的文件。通常目录结构与源码树一致,子目录是被构建系统自动创建出来的
可以在解压完压缩包之后在任意位置新建一个build子文件夹并在该文件夹下执行后续步骤,所有的派生文件会存放在build目录下,这样的构建叫做parallel build
或者VPATH builds
。
虚拟路径构建可以创建多个子文件夹进行构建,这样就可以使用不同的参数构建同一份源码。
在指定的构建平台上编译可以在运行平台上执行的二进制文件
./configure --build指定构建平台,–host指定运行平台
notes:如果需要构建的包本身就是一个交叉编译器,需要使用–target参数指定架构
可以在执行configure的时候对安装的程序重命名,比如安装tar
变为gtar
以下三个参数可以满足该需求:
eg.
./configure --program-prefix tea
make DESTDIR=$HOME/inst install
此举会将程序安装在~/inst
文件夹下,文件夹下包含了程序的安装结构
安装的目录结构如下所示:
打包:
cd ~/inst
find . -type f -print > ../files.lst
tar zcvf ~/amhello-1.0-i686.tar.gz `cat ../files.lst`
如此一来,直接解压这个压缩包,就可以直接完成amhello的安装。
使用make distcheck
来保证包拥有所需要的构建步骤并且不会报错
VPATH Builds
DESTDIR
安装工作autoreconfig
是一个按照正确执行autoconf、automake和一堆其它命令的脚本,用于生成构建系统。
编写configure.ac、Makefile.am、main.c、README文件,执行
autoreconfig --install
实例化一个构建系统
autoconf负责从configure.ac生成configure文件
automake负责从Makefile.am和configure.ac生成Makefile.in文件
note:只有构建系统没有时才执行autoreconfig
,如果修改了configure.ac
或者Makefile.am
,执行make时会自动重新生成相关文件。configure.ac
的语法参考Autoconf手册。
在/usr/share/doc/automake-1.13.4
目录下,会有一个amhello的软件包,以它作为例子讲解:
amhello-1.0
├── aclocal.m4
├── config.h.in
├── configure
├── configure.ac
├── depcomp
├── install-sh
├── Makefile.am
├── Makefile.in
├── missing
├── README
└── src
├── main.c
├── Makefile.am
└── Makefile.in
AC_INIT([amhello], [1.0], [[email protected]])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
AC_
开头的是autocofig的宏;AM_
开头的是automake的宏。bin_PROGRAMS = hello
hello_SOURCES = main.c
与Makefile的语法一样。automake驱动该文件时会将整个内容复制到Makefile.in
文件,但是会通过构建规则和其他变量对特定的变量定义做出反应。通常该文件只包含上述的变量定义列表,但也可以包含其他的变量和规则,只是automake仅仅传递他们,不对其进行处理。
_PROGRAMS
结尾的特殊变量指定了Makefile应该构建的文件类型。Automake将这些变量称之为primary
,其他的primary例如 _SCRIPTS, _DATA, _LIBRARIES 等等,对应不同的文件类型。${exec_prefix}/bin
文件夹下make dist
时main.c会成为tar包的一部分_PROGRAMS
变量中列出了prog
,automake会寻找另一个名为prog_SOURCES
的变量列出其所有的源文件。所有的源文件会被一起编译和链接。SUBDIRS = src
dist_doc_DATA = README
_DATA primary
列出的文件列表不会自动地成为tar包的一部分,所以加上了dist前缀来达到这个目的。唯一重要的影响是此行在make install
的时候会安装README。note:文件中没有涉及到安装路径,请参考autocong手册中的Defining Directories。
Automake读取Makefile.am生成Makefile.in文件。某些在Makefile.am中定义的变量和规则指导Automake生成更加专用的代码。
大部分GNU make扩展不能被Automake所识别。
定义在Makefile.am或者configure.ac中的变量会覆盖automake的默认变量。
automake在检查变量定义的时候会递归检查所有引用的变量
注释以##
开头
虽然Automake旨在供GNU包维护中使用,但是并不想遵守其全部的规定。
有以下三个等级:
Automake变量遵守uniform naming scheme
,使何时程序被构建和如何被安装变得很容易。
一套不同的名字用来决定构建对象应该被安装到哪里。这些名字是primary的前缀,定义了哪个标准文件夹是安装目录。标准的文件夹名字参考 Directory Variables in The GNU Coding Standards
每个primary都有一个额外的以EXTRA_
作为前缀的变量名。它用于列出可能会或不会被构建的对象,取决于configure。
可以自定义目录,任何在Makefile.am中以dir
结尾的自定义变量都可以用作primary的合法前缀:
xmldir = $(datadir)/xml
xml_DATA = file.xml
不是在每个文件夹的每个对象的每个部分都会被安装。Automake会标记这些错误。还会检查目录名的拼写错误。
noinst_
前缀表示变量只构建不安装。
check_
表明变量不能被构建直到make check
命令运行。也不可安装。
所有的变量名期望 字母、数字、@、其它符号变为下划线,比如libmum++.a,派生变量会是libmum___a_SOURCES
超级前缀:
nobase_dist_include_HEADERS = \
jupiter/jupiter_interface.h
正常情况下,该头文件会被安装到/usr(/local)/include/jupiter_interface.h
,加了nobase
前缀之后,会变为/usr(/local)/include/jupiter/jupiter_interface.h
。
nobase_
可以使用下面的写法代替:
nobase_dist_pkgdata_HEADERS = jupiter/jupiter.ogg
jupiterdir = $(pkgdatadir)/jupiter
dist_jupiter_DATA = jupiter/jupiter.ogg
EXTRA_DIST变量应该被加到发布包的文件或文件夹。
例如
data_DATA = file1 … fileN fileN+1 … file2N
可以写成
data_DATA = file1 … fileN
data2dir = $(datadir)
data2_DATA = fileN+1 … file2N
一些保留变量为构建包的用户使用,让他们的工作更轻松。但是这些变量不能出现在要求正确编译的包中。
Automake引入了特殊的阴影便量为用户标记变量。添加前缀AM_
到用户变量名就是阴影变量。
bin_PROGRAMS = true false
false_SOURCES =
false_LDADD = false.o
true.o: true.c
$(COMPILE) -DEXIT_CODE=0 -c true.c
false.o: true.c
$(COMPILE) -DEXIT_CODE=1 -o false.o -c true.c
true_SOURCES没有写,Automake会默认有一个true.c文件和默认的规则来编译true.o、链接true。see Default _SOURCES
bin_PROGRAMS = false true
false_SOURCES = true.c
false_CPPFLAGS = -DEXIT_CODE=1
true_SOURCES = true.c
true_CPPFLAGS = -DEXIT_CODE=0
该种写法会生成 false-true.o and true-true.o