Welcome

autoconf使用

参考鸟哥的博客http://www.laruence.com/

背景知识/学习原因

现在linux是很火的操作系统,在很多服务器上都使用了linux的操作系统,作为一名linux菜鸟,也是希望以后能够有机会能够在开发一些关于linux的软件,能够给linux的社区做点共享,而且最近也是在看一些关于linux软件的源码,所以趁着这个机会,把linux软件的编译流程也走一下,之前的软件基本上都是通过网上找一些安装的教程,然后按照教程走一遍,然而并没有深入的理解configure,make,这些工作的大概的思想,有幸能够在网上搜到了php大神鸟哥的博客讲到了关于这方面的内容,看完了之后感觉学习到了很多,所以把这些自己的感受到都记录下来,当做学习的一个积累,也顺便培养下自己的写博客的习惯。

Makefile介绍

Makefile是用于自动编译和链接的 ,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是 所有的文件都需要重新编译,Makefile中纪录有文件的信息,在 make时会决定在链接的时候需要重新编译哪些文件.
Makefile的宗旨就是 :让编译器知道要编译一个文件需要依赖其他的 哪些文件.当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的 模块.
Makefile的 基本结构不是 很复杂,但当一个程序开发人员开始写Makefile时,经常会怀疑自己写的 是 否符合惯例,而且自己写的 Makefile经常和自己的 开发环境相关联,当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改.这样就造成了手工书写Makefile的 诸多问题,automake恰好能很好地帮助我们解决这些问题.使用automake,程序开发人员只需要写一些简单的 含有预定义宏的 文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in,再使用configure依据Makefile.in来生成一个符合惯例的 Makefile.下面我们将详细介绍Makefile的 automake生成方法.

使用的环境

本文所提到的程序是基于Linux发行版本:Ubuntu12.04,它包含了我们要用到的autoconf,automake.

从helloworld入手

建目录

1
2
$ mdkir c-autoconf
$ cd c-autoconf

编写hello.c

1
2
3
4
5
6
#incluede <stdio.>
int main(int argc, int argv[])
{
printf("hello world");
return 0;
}

autoscan上场

通过autoscan来根据目录下的文件来生成configure.scan文件

1
2
$ ls
$ autoscan.log configure.scan hello.c

把configure.scan修改名字变成configure.in,修改configure.in文件,

1
2
3
4
5
6
7
8
9
10
11
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_INIT(hello.c)
AM_INIT_AUTOMAKE(hello, 1.0)
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT(Makefile)

aclocal 上场

1
2
3
$ aclocal
$ ls
$ autom4te.cache autoscan.log configure.in hello.c

autoconf 上场

1
2
3
$ autoconf
$ ls
$ autom4te.cache autoscan.log configure configure.in hello.c

关于aclocal和autoconf

aclocal通过configure.in来生成autom4te.cache,然后autoconf通过生成的autom4te.cache来生成configure文件

大家可以看到configure.in内容是 一些宏定义,这些宏经autoconf处理后会变成检查系统特性.环境变量.软件必须的 参数的 shell脚本.

autoconf 是 用来生成自动配置软件源代码脚本(configure)的 工具.configure脚本能独立于autoconf运行,且在 运行的 过程中,不需要用户的 干预.

要生成configure文件,你必须告诉autoconf如何找到你所用的宏.方式是使用aclocal程序来生成你的aclocal.m4.

aclocal根据configure.in文件的 内容,自动生成aclocal.m4文件.aclocal是 一个perl 脚本程序,它的定义是 :”aclocal – create aclocal.m4 by scanning configure.ac”.

autoconf从configure.in这个列举编译软件时所需要各种参数的 模板文件中创建configure.

autoconf需要GNU m4宏处理器来处理aclocal.m4,生成configure脚本.m4是 一个宏处理器.将输入拷贝到输出,同时将宏展开.宏可以是 内嵌的 ,也可以是 用户定义的 .除了可以展开宏,m4还有一些内建的 函数,用来引用文件,执行命令,整数运算,文本操作,循环等.m4既可以作为编译器的 前端,也可以单独作为一个宏处理器.

新建一个Makefile.am文件

1
2
$ touch Makefile.am
$ vim Makefile.am
1
2
3
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=hello
helloworld_SOURCES=hello.c

automake会根据你写的 Makefile.am来自动生成Makefile.in.
Makefile.am中定义的 宏和目标,会指导automake生成指定的代码.例如,宏bin_PROGRAMS将导致编译和连接的目标被生成.

automake 上场

1
2
3
4
5
$ automake --add-missing
configure.in: installing `./install-sh'
configure.in: installing `./mkinstalldirs'
configure.in: installing `./missing'
Makefile.am: installing `./depcomp'

开始编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
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: executing depfiles commands

现在同时可以看到我们已经是生成了Makefile了

1
2
$ ls -al Makefile
-rw-rw-r-- 1 vagrant vagrant 19590 Aug 9 14:03 Makefile

come on,开始使用makefile来编译代码

1
2
3
4
$ make
gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"hello\" -DVERSION=\"1.0\" -I. -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o hello.c
mv -f .deps/hello.Tpo .deps/hello.Po
gcc -g -O2 -o hello hello.o

开始运行

1
2
$ ./hello
hello world

深入浅出

  1. autoscan
  autoscan是 用来扫描源代码目录生成configure.scan文件的 .autoscan
可以用目录名做为参数,但如果你不使用参数的 话,那么autoscan将认为使用的是当前目录.
autoscan将扫描你所指定目录中的 源文件,并创建configure.scan文件.
  2. configure.scan
  configure.scan包含了系统配置的 基本选项,里面都是 一些宏定义.我们需要将它改名为
configure.in
  3. aclocal
  aclocal是 一个perl 脚本程序.aclocal根据configure.in文件的 内容
,自动生成aclocal.m4文件.aclocal的 定义是 :"aclocal - create
aclocal.m4 by scanning configure.ac".
  4. autoconf
  autoconf是 用来产生configure文件的 .configure是 一个脚本,它能设置
源程序来适应各种不同的操作系统平台,并且根据不同的 系统来产生合适的 Makefile,从而可以使
你的源代码能在不同的操作系统平台上被编译出来.
  configure.in文件的 内容是 一些宏,这些宏经过autoconf 处理后会变成检查系统
特性.环境变量.软件必须的 参数的 shell脚本.configure.in文件中的 宏的 顺序并没
有规定,但是 你必须在 所有宏的 最前面和最后面分别加上AC_INIT宏和AC_OUTPUT宏.
  在 configure.ini中:
  #号表示注释,这个宏后面的 内容将被忽略.
  AC_INIT(FILE)
  这个宏用来检查源代码所在 的 路径.
AM_INIT_AUTOMAKE(PACKAGE, VERSION)
   这个宏是 必须的 ,它描述了我们将要生成的 软件包的 名字及其版本号:PACKAGE是软件包
的名字,VERSION是 版本号.当你使用make dist命令时,它会给你生成一个类似
helloworld-1.0.tar.gz的 软件发行包,其中就有对应的 软件包的 名字和版本号.
AC_PROG_CC
  这个宏将检查系统所用的 C编译器.
AC_OUTPUT(FILE)
  这个宏是 我们要输出的 Makefile的 名字.
  我们在 使用automake时,实际上还需要用到其他的 一些宏,但我们可以用aclocal 来帮
我们自动产生.执行aclocal后我们会得到aclocal.m4文件.
  产生了configure.in和aclocal.m4 两个宏文件后,我们就可以使用autocon
f来产生configure文件了.
  5. Makefile.am
  Makefile.am是 用来生成Makefile.in的 ,需要你手工书写.Makefile.
am中定义了一些内容:
AUTOMAKE_OPTIONS
  这个是 automake的 选项.在 执行automake时,它会检查目录下是 否存在 标准
GNU软件包中应具备的各种文件,例如AUTHORS.ChangeLog.NEWS等文件.
我们将其设置成foreign时,automake会改用一般软件包的 标准来检查.
bin_PROGRAMS
  这个是 指定我们所要产生的 可执行文件的 文件名.如果你要产生多个可执行文件,
那么在各个名字间用空格隔开.
helloworld_SOURCES
  这个是 指定产生"helloworld"时所需要的 源代码.如果它用到了多个源文件,
那么请使用空格符号将它们隔开.比如需要helloworld.h,helloworld.c那么请写成:
helloworld_SOURCES= helloworld.h helloworld.c.
  如果你在 bin_PROGRAMS定义了多个可执行文件,则对应每个可执行文件都要定义相对的
filename_SOURCES.
  6. automake
  我们使用automake --add-missing来产生Makefile.in.
  选项--add-missing的 定义是 "add missing standard files
 to package",它会让automake加入一个标准的 软件包所必须的 一些文件.
   我们用automake产生出来的 Makefile.in文件是 符合GNU Makefile惯例
 的 ,接下来我们只要执行configure这个shell 脚本就可以产生合适的 Makefile 文
 件了.
   7. Makefile
   在 符合GNU Makefiel惯例的 Makefile中,包含了一些基本的 预先定义的 操作:

 make
   根据Makefile编译源代码,连接,生成目标文件,可执行文件.
 make clean
   清除上次的 make命令所产生的 object文件(后缀为".o"的 文件)及可执行文件.
 make install
   将编译成功的 可执行文件安装到系统目录中,一般为/usr/local/bin目录.
 make dist
   产生发布软件包文件(即distribution package).这个命令将会将可执行文件及相关
 文件打包成一个tar.gz压缩的 文件用来作为发布软件的 软件包.
   它会在 当前目录下生成一个名字类似"PACKAGE-VERSION.tar.gz"的 文件.PA
 CKAGE和VERSION,是 我们在 configure.in中定义的 AM_INIT_AUTOM
 AKE(PACKAGE, VERSION).
 make distcheck
   生成发布软件包并对其进行测试检查,以确定发布包的正确性.