automake.docx
《automake.docx》由会员分享,可在线阅读,更多相关《automake.docx(39页珍藏版)》请在冰豆网上搜索。
automake
AutoMake
版本问题
AutoMake例子
步骤总述
新版的automake变化
autotools系列工具作用
怎么能让automake生成的makefile里面包含有我指定的库
制作configure脚本
使用automake
autoconf手册
利用libtool自动生成动态库的Makefile的生成方法
autoconf和automake生成Makefile文件
引子
模拟需求
工具简介
生成Makefile的来龙去脉
Configure.in的八股文
实战Makefile.am
几个重要的宏
三种一般需求
版本问题
不同的automake,autoconf,autoscan之间存在着一定的不兼容性。
这里推荐autoscan2.59和automake1.9配合使用。
如果你是debian或者ubuntu,那么可你可以简单按照下面的方式安装
apt-getinstallautoconf
apt-getremoveautomake1.4
apt-getinstallautomake1.9
AutoMake例子
现在googleMakefile和automake就能找到一些文章。
以一个Hello程序描述为一个project生成Makefile的过程。
这个例子其实在Infoautomake里能看到。
大家把它翻成中文的,不错。
但实际上按照这个例子来做的话,步骤都对,就是太简单,一些常用的设置需要写进去,但是没有提到,还是要自己info,google,try.
步骤总述
autoscan生成configure.scan.
在configure.scan基础上手动编辑,主要要添加的:
AM_INIT_AUTOMAKE(myprojectname,version)
AC_OUTPUT(最后要生成的Makefile,包括子目录中的,中间用空格隔开),
例如AC_OUTPUT(Makefilesubdir/Makefilesubdir1/Makefile)
AC_PROG_RANLIB(意义见第四条末尾)
aclocal
autoconf生成configure脚本。
就是在每个最后需要生成Makefile的目录中,写一个Makefile.am.
最上层的要写明
AUTOMAKE_OPTIONS=foreign
如果这个目录没有要编译的文件,只包含了子目录,则只写个
SUBDIRS=dir1
就ok了。
例如我的工程,最上层只是包含了源码目录,于是就写了
AUTOMAKE_OPTIONS=foreign
SUBDIRS=src
如果有文件要编译,则要指明target先。
比如我的src目录底下既有文件,又有目录,而src的这层目录中的文件最后是要编译成一个可执行文件,则src目录下的Makefile.am这么写。
bin_PROGRAMS=myprogram
SUBDIRS=sub1
myprogram_SOURCES=\
a.cpp\
b.cpp\
#要编译的源文件。
这儿的_SOURCES是关键字
EXTRA_DIST=\
a.h\
b.h
#不用编成.o,但生成targetmyprogram也需要给编译器处理的头文件放这里
myprogram_LDADD=libsub1.a这个_LDADD是关键字,
#最后生成myprogram这个执行文件,还要linksrc/sub1这个目录中的内容编成的一个lib:
libsub1.a,
myprogram_LDFLAGS=-lpthread-lglib-2.0-L/usr/bin$(all_libraries)
#myprogram还要link系统中的动态so,以此类推,需要连自编译的so,也写到这个关键字_LDFLAGS后面就好了。
AM_CXXFLAGS=-D_LINUX
#传递给g++编译器的一些编译宏定义,选项,
INCLUDES=-IPassport-Isub1/-I/usr/include/glib-2.0\
-I/usr/lib/glib-2.0/include$(all_includes)
#传递给编译器的头文件路径。
下面是sub1种生成lib的Makefile.am
noinst_LIBRARIES=libprotocol.a
#不是生成可执行文件,而是静态库,target用noinst_LIBRARIES
libprotocol_a_SOURCES=\
alib.cpp
EXTRA_DIST=mylib.h\
alib.h
INCLUDES=-I../$(all_includes)
AM_CXXFLAGS=-D_LINUX-DONLY_EPOLL-D_SERVER
ok,最后补上AC_PROG_RANLIB涵义,如果要自己生成lib,然后link到最终的可执行文件中,则要加上这个宏,否则不用。
[讨论]每个目录至少都要有一个target,或者是可执行文件或者是lib,似乎对目录的划分带来点局限。
比如我的目录结构如果是这样
./Src
./Src/sub1
./Src/sub2
而我想这样,sub1,sub2都没有target,目录划分只是为了区别代码的不同模块,然后把两个目录中编译出的中间文件一起link,得到最后需要的myprogram。
似乎在Src/Makefile.am中要这么写
myprogram_SOURCES=sub1/a.cpp\
sub2/b.cpp
可以实现,但我没试,:
P
当然和设成先编译出libsub1.alibsub2.a最后Link得到myprogram没有本质区别了。
automake--add-missing
Ok,Makefile.in应该放到各个目录下了。
最后,运行configure脚本,生成各个目录下的Makefile.......
再最后,make.......
新版的automake变化
软件版本间的不兼容总是会带来不少麻烦。
首先我对比了网上的一些文章和gnu的autoconf文档,发现差别很大,新版本和老版本有很多不同,当然大部分特性新版本还是兼容老版本的,令人郁闷的是automake的文档中对configure.in的描述还是针对autoconf老版本的。
软件版本:
autoscan2.59
automake1.9.5
参考文档:
automake1.7.8dochttp:
//www.gnu.org/software/automake/manual/html_node/
autoconf2.59dochttp:
//www.gnu.org/software/autoconf/manual/
建立程序:
cd~/src
mkdirhello
编辑文件hello.c
运行autoscan,产生错误:
autom4te:
configure.ac:
nosuchfileordirectory
不予理会,生成了文件configure.scan
cpconfigure.scanconfigure.ac
修改configure.ac的内容如下:
#-*-Autoconf-*-
#Processthisfilewithautoconftoproduceaconfigurescript.
AC_PREREQ(2.59)
AC_INIT(hello,1.0,beyondwdq@)
AC_CONFIG_SRCDIR([configure.ac])
AM_INIT_AUTOMAKE(hello,1.0)
AC_CONFIG_HEADER([config.h])
#Checksforprograms.
AC_PROG_CC
#Checksforlibraries.
#Checksforheaderfiles.
#Checksfortypedefs,structures,andcompilercharacteristics.
#Checksforlibraryfunctions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
这里说明一下的是,老版本的autotools使用configure.in作为输入,后来新版本改为configure.ac,但configure.in也可以。
运行aclocal,生成文件aclocal.m4
运行autoheader,声称文件config.h.in
编辑文件Makefile.am内容如下:
bin_PROGRAMS=hello
hello_SOURCES=hello.c
运行automake--add-missing,提示少了文件READMENEWSAUTHORSChangeLog
touchREADMENEWSAUTHORSChangeLog建立这些文件
再次运行automake--add-missing[注意]若在Makefile.am中加上AUTOMAKE_OPTIONS=foreign则不会提示缺少文件。
运行autoconf,生成了configure脚本
执行./configure,生成Makefile
运行make,编译通过。
autotools系列工具作用
1.autoscan(autoconf):
扫描源代码以搜寻普通的可移植性问题,比如检查编译器,库,头文件等,生成文件configure.scan,它是configure.ac的一个雏形。
2.aclocal(automake):
根据已经安装的宏,用户定义宏和acinclude.m4文件中的宏将configure.ac文件所需要的宏集中定义到文件aclocal.m4中。
aclocal是一个perl脚本程序,它的定义是:
“aclocal-createaclocal.m4byscanningconfigure.ac”
userinputfilesoptionalinputprocessoutputfiles
=================================================
acinclude.m4-----.
V
.-------,
configure.in------------------------>|aclocal|
{usermacrofiles}->||------>aclocal.m4
`-------'
3.autoheader(autoconf):
根据configure.ac中的某些宏,比如cpp宏定义,运行m4,声称config.h.in
userinputfilesoptionalinputprocessoutputfiles
=================================================
aclocal.m4-------.
(acconfig.h)----.|
VV
.----------,
configure.in----------------------->|autoheader|---->config.h.in
`----------'
4.automake:
automake将Makefile.am中定义的结构建立Makefile.in,然后configure脚本将生成的Makefile.in文件转换为Makefile。
如果在configure.ac中定义了一些特殊的宏,比如AC_PROG_LIBTOOL,它会调用libtoolize,否则它会自己产生config.guess和config.sub
userinputfilesoptionalinputprocessesoutputfiles
===================================================
.--------,
||--->COPYING
||--->INSTALL
||------>install-sh
||------>missing
|automake|------>mkinstalldirs
configure.in----------------------->||
Makefile.am----------------------->||------>Makefile.in
||------>stamp-h.in
.---+|--->config.guess
|||--->config.sub
|`------+-'
||---->config.guess
|libtoolize|---->config.sub
||-------->ltmain.sh
||-------->ltconfig
`----------'
5.autoconf:
将configure.ac中的宏展开,生成configure脚本。
这个过程可能要用到aclocal.m4中定义的宏。
userinputfilesoptionalinputprocessesoutputfiles
===================================================
aclocal.m4------.
V
.--------,
configure.in----------------------->|autoconf|------>configure
`--------'
References:
http:
//sourceware.org/autobook/autobook/autobook_276.html
怎么能让automake生成的makefile里面包含有我指定的库
INCLUDES=-I/include
LIBS=-lm-lcrypt
制作configure脚本
autoconf是用来生成自动配置软件源代码脚本(configure)的工具。
configure脚本独立于autoconf运行,而且在运行的过程中,不需要用户的干预,通常不需要附带参数。
它是用来检验软件必须的参数的。
autoconf从一个列举编译软件时所需要各种参数的模板文件中创建configure。
autoconf需要GNUm4来生成该脚本。
由autoconf生成的脚本一般起名为configure。
当运行时,configure创建了多个文件,并对这些文件中的配置参数赋予适当的值。
由configure创建生成的文件有:
一个或多个Makefile,在软件源代码的每个目录中都生成一个Makefile。
还可选的生成C头文件——configurable,包含了各种#define声明。
一个名为config.status的脚本,当运行时,重新生成上面的文件。
一个名为config.cache的脚本,保存运行检测的结果。
一个名为config.log的文件,保存有编译器生成的信息,用于调试configure。
为了让autoconf生成configure脚本,需要以configure.in为参数调用autoconf。
如果要检测自己的各种参数,以作为对autoconf的补充,则需要写aclocal.m4和acsite.m4的文件。
如果要使用C头文件,需要写acconfig.h,并且将autoconf生成的config.h.in同软件一起发行。
yoursourcefiles-->[autoscan*]-->[configure.scan]-->configure.in
configure.in--..------>autoconf*----->configure
+---+
[aclocal.m4]--+`---.
[acsite.m4]---'|
+-->[autoheader*]->[config.h.in]
[acconfig.h]----.|
+-----'
[config.h.top]--+
[config.h.bot]--'
Makefile.in------------------------------->Makefile.in
Filesusedinconfiguringasoftwarepackage:
.------------->config.cache
configure*------------+------------->config.log
|
[config.h.in]-.v.->[config.h]-.
+-->config.status*-++-->make*
Makefile.in---'`->Makefile---'
编辑configure.in文件:
configure.in文件中包含了对autoconf宏的调用,这些宏是用来检测软件所必须的各项参数的。
为了能够得到configure.in文件,需要使用autoscan。
configure.in文件中,在进行各项检测前,必须在最开始调用AC_INIT,在最后调用AC_OUTPUT。
另外有些宏由于检测的关系是和在文件中的位置相关的。
最好每一个宏占用一行。
使用autoscan创建configure.in文件
可以将目录做为参数调用autoscan,如果不使用参数的化,则认为是当前目录。
autoscan将检查指定目录中的源文件,并创建configure.scan文件。
在将configure.scan改名为configure.in文件前,需要手工改动它以进行调整。
使用autoconf创建configure脚本
不带任何参数的运行autoconf。
autoconf将使用m4宏处理器和autoconf宏,来处理处理configure.in中的宏。
configure.in中的宏:
AC_INIT(在源代码中唯一的一个文件):
configure将检查该文件是否存在,并检查包含它的目录是否存在。
AC_OUTPUT(文件):
指定创建的输出文件。
在configure.in文件中调用一次。
文件名间用空格分开。
比如:
AC_OUTPUT(Makefile:
templates/top.mklib/Makefile:
templates/lib.mk)
在configure.in中,有一些被autoconf宏预先定义的变量,重要的有如下几个:
bindir:
安装可执行文件的目录。
includedir:
C头文件目录。
infodir:
info页安装目录。
mandir:
安装手册页的目录。
sbindir:
为管理员运行该该程序提供的安装路径。
srcdir:
为Makefile提供的源代码路径。
top_srcdir:
源代码的最上层目录。
LIBS:
给连接程序的-l选项
LDFLAGS:
给连接程序的stripping(-s)和其他一些选项。
DEFS:
给C编译器的-D选项。
CFLAGS:
给C编译器的debug和优化选项。
当调用了AC_PROG_CC才有效。
CPPFLAGS:
头文件搜索路径(-I)和给C预处理器和编译器的其他选项。
CXXFLAGS:
给C++编译器的debug和优化选项。
当调用了AC_PROG_CXX才有效。
如果在同一个目录下编译多个程序的话,使用AC_CONFIG_SUBDIRS宏,它的语法是:
AC_CONFIG_SUBDIRS(DIR....):
其他重要的宏:
AC_PROG_CC:
选择C编译器。
如果在环境中不设置CC的话,则检测gcc。
AC_PROG_CXX:
选择C++编译器。
使用automake
一般操作
Automake工作时,读取一个叫'Makefile.am'的文件,并生成一个'Makefile.in'文件。
Makefile.am中定义的宏和目标,会指导automake生成指定的代码。
例如,宏'bin_PROGRAMS'将导致编译和连接的目标被生成。
Makefile.am中包含的目标和定义的宏被拷贝到生成的文件中去,这允许你添加任意代码到生成的Makefile.in文件中去。
例如,使一个Automake发布中包含一个非标准的dvs-dist目标,Automake的维护者用它来从它的源码控制系统制作一个发布。
请注意,GNU生成的扩展名不被Automake所识别,在一个'Makefile.am'中使用这样一个扩展名会导致错误。
Automake试图以一种聪明的方式将相邻的目标(或变量定义)注释重组。
通常,Makefile.am中定义的目标会覆盖任何由automake自动生成的有相似名字的这样的目标。
尽管这是种被支持的属性,但最好避免这么做,因为有些时候,生成的规则很严格。
类似的,Makefile.am中定义的变量会覆盖任何由automake自动生成的变量定义。
这一特性经常要比目标定义的覆盖能力更常用。
请注意,很多automake生成的变量只用于内部使用,在将来发布时他们的名字可能会变化。
当测试一个变量定义时,Automake降递归的测试在定义中引用的变量。
例如,如果Automake看到这段snippet程序中的'foo_SOURCES':
xs=a.cb.c
foo_SOURCES=c.c$(xs)
它将使用文件:
'a.c','b.c'和'c.c'作为foo_SOURCES的内容.
Automake也允许不被拷贝到输出的注释形式,所有以'##'开头的行将被Automake完全忽略.
深度
Automake支持三种目录层次:
'flat','shallow','deep'.
flat:
所有的文件都在一个目录中.相应的Makefile.am中缺少SUBDIRS宏.termutils是一个例子.
deep:
所有的资源都在子目录中,指定曾目录主要包含配置信息.GNUcpio是一个很好的例子.GNUtar.相应的最顶层Makefile.am中将包含一个SUBDIR宏,但没有其他的宏来定义要创建的对象.
shallow:
主资源存在于最顶层目录,而不同的部