简介
Automake介绍¶
Automake是从Makefile.am(定义一系列make变量的文件)自动生成Makefile.in文件的工具。生成的Makefile.in符合GNU Makefile 标准。
因为不同的平台需要修改Makefile,所以编写configure
脚本自动修改Makefile,再执行./configure && make && make install
命令安装包,形成了GNU构建系统。
Autotools介绍¶
Autotools
是为包创建GNU构建系统的工具;Autoconf
主要关注configure
;Automake
主要关注Makefile
。
当安装一个程序时,安装步骤有以下几步:
- tar -zxf xxx.tar.gz
- cd xxx
- ./configure #检查要求的环境,生成包括Makefile(s)在内的多个文件
- make #构建所有的文件结构,生成文件
- make check #源码检查
- su #切换到root用户
- make install #复制源码文件到目的目录
- make installcheck #安装后检查
note:
- make uninstall 需要在构建树下运行
- make clean 删除make生成的文件
- make distclean 额外删除 ./configure生成的文件
- make dist 从源码重新创建xxx.tar.gz
有一些可配置变量,可以通过./configure --help
查看完整版
如果想配置系统默认变量,可以修改/usr/local/share/config.site
文件中指定
2.2.3 标准目录变量¶
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
。
2.2.6 并行构建树(VPATH 构建)¶
对比源码树与构建树¶
源码树:包含了configure文件的所有源文件
构建树:在源码树的基础上,包含上运行configure之后派生出来的文件。通常目录结构与源码树一致,子目录是被构建系统自动创建出来的
虚拟路径构建¶
可以在解压完压缩包之后在任意位置新建一个build子文件夹并在该文件夹下执行后续步骤,所有的派生文件会存放在build目录下,这样的构建叫做parallel build
或者VPATH builds
。
虚拟路径构建可以创建多个子文件夹进行构建,这样就可以使用不同的参数构建同一份源码。
一些特性¶
2.2.8 交叉编译¶
在指定的构建平台上编译可以在运行平台上执行的二进制文件 ./configure --build指定构建平台,--host指定运行平台 notes:如果需要构建的包本身就是一个交叉编译器,需要使用--target参数指定架构
2.2.9 重命名程序¶
可以在执行configure的时候对安装的程序重命名,比如安装tar
变为gtar
以下三个参数可以满足该需求:
- --program-prefix #给程序名字添加前缀
- --program-suffix #给程序名字添加后缀
- --program-transform-name #重命名程序
eg.
./configure --program-prefix tea
2.2.10 指定目的文件夹构建二进制文件¶
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的安装。
2.2.11 准备发布¶
使用make distcheck
来保证包拥有所需要的构建步骤并且不会报错
- 尝试完整的打包、解包、运行make、make check、make install、make installcheck、make dist
- 测试只读源码树的
VPATH Builds
- 保证make clean、make distclean、make uninstall不会遗漏任何文件
- 检查
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手册。
2.4 小程序文件解读¶
在/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
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([
Makefile
src/Makefile
])
AC_OUTPUT
AC_
开头的是autocofig的宏;AM_
开头的是automake的宏。- AC_INIT 定义了包名、版本、联系地址
- AM_INIT_AUTOMAKE 括号中的是automake的选项。-Wall -Werror 意味着关闭警告并作为错误进行报告;foreign 不要遵守GNU的规则,GNU包总是还应该有其他的文件
- AC_PROG_CC 使configure脚本搜索C编译器然后用其名字定义变量CC,src/Makefile.in文件需要使用CC变量来构建hello
- AC_CONFIG_HEADERS 使configure脚本创建config.h文件收集在configure.ac文件中定义的宏
- AC_CONFIG_FILES 声明了configure文件应该从*.in模板创建的文件列表,否则不会使用Makefile.am文件
- AC_OUTPUT 是一个关闭命令,是真正的负责生成文件(在AC_CONFIG_HEADERS和AC_CONFIG_FILES中注册的)的脚本部分
src/Makefile.am¶
bin_PROGRAMS = hello
hello_SOURCES = main.c
与Makefile的语法一样。automake驱动该文件时会将整个内容复制到Makefile.in
文件,但是会通过构建规则和其他变量对特定的变量定义做出反应。通常该文件只包含上述的变量定义列表,但也可以包含其他的变量和规则,只是automake仅仅传递他们,不对其进行处理。
- bin表明了安装位置
- 以
_PROGRAMS
结尾的特殊变量指定了Makefile应该构建的文件类型。Automake将这些变量称之为primary
,其他的primary例如 _SCRIPTS, _DATA, _LIBRARIES 等等,对应不同的文件类型。 - bin 意味着程序应该被安装到
${exec_prefix}/bin
文件夹下 - hello_SOURCES 该声明的副作用是当执行
make dist
时main.c会成为tar包的一部分 - 因为程序需要从源文件构建,所以每个程序在一个
_PROGRAMS
变量中列出了prog
,automake会寻找另一个名为prog_SOURCES
的变量列出其所有的源文件。所有的源文件会被一起编译和链接。
Makefil.am¶
SUBDIRS = src
dist_doc_DATA = README
- SUBDIRS 列出所有的在驱动当前目录之前make需要递归进入的文件夹,make install也会先安装src/hello,再安装README
- dist_doc_DATA
_DATA primary
列出的文件列表不会自动地成为tar包的一部分,所以加上了dist前缀来达到这个目的。唯一重要的影响是此行在make install
的时候会安装README。
note:文件中没有涉及到安装路径,请参考autocong手册中的Defining Directories。
3. 基本理念¶
3.1 一般操作¶
Automake读取Makefile.am生成Makefile.in文件。某些在Makefile.am中定义的变量和规则指导Automake生成更加专用的代码。
大部分GNU make扩展不能被Automake所识别。
定义在Makefile.am或者configure.ac中的变量会覆盖automake的默认变量。
automake在检查变量定义的时候会递归检查所有引用的变量
注释以##
开头
3.2 严格程度¶
虽然Automake旨在供GNU包维护中使用,但是并不想遵守其全部的规定。
有以下三个等级:
- foreign - 只检查正确操作所必须的东西。
- gnu - 会尽可能多的满足GNU标准。默认选项
- gnits - 会检查还未成文的GNU标准,比GNU标准更细。通常不会使用该选项
3.3 命名格式¶
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
超级前缀:
- dist #指明哪些文件应该被发布
- nodist
- nobase #禁止去掉路径前缀的规则,举例:
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变量应该被加到发布包的文件或文件夹。
3.4 命令长度限制¶
例如
data_DATA = file1 … fileN fileN+1 … file2N
可以写成
data_DATA = file1 … fileN
data2dir = $(datadir)
data2_DATA = fileN+1 … file2N
3.6 用户保留变量¶
一些保留变量为构建包的用户使用,让他们的工作更轻松。但是这些变量不能出现在要求正确编译的包中。
Automake引入了特殊的阴影便量为用户标记变量。添加前缀AM_
到用户变量名就是阴影变量。
4. 一些示例包¶
- 使用不同的编译参数从一个文件构建两个项目。通过设定不同的变量名及其标志指向同一个文件俩达到效果
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