autoconf和automake

来自:http://tigersoldier.is-programmer.com/show/1904.html


1 autoconf和automake的由来

autoconf和automake是啥?这要从类Unix系统的程序编译说起。

1.1 Make

一般一个真正的工程肯定不只一个文件,而多个文件的编译是件很麻烦的事情(最简单的就是用gcc或者g 后面接着多个文件),再加上要推出跨平台的(一般只是跨不同的类Unix平台),还有啥包依赖啊什么的,很麻烦嗯。于是就有了一个工具叫make,它接收一个名为Makefile的文件作为参数,自动地进行编译,还可以在Makefile里设置接受不同的选项,然后人们就可以make install、make all什么的了。

1.2 configure脚本

然而不同系统的编译要用不同的编译参数,但是开源软件不可能带多个Makefile,而且又难写,囧么办?于是有了configure脚本,它自动检测系统,并接受一个Makefile.in文件,根据它来生成Makefile。


1.3 autoconf和automake

然而confiure脚本和Makefile.in还是很难写,至少我不会写,而且看得也眼花。于是GNU推出了autoconfautomake,用于生成configure脚本和Makefile.in文件。其中autoconf是用来生成configure的automake是用来生成Makefile.in的


2 使用方法

貌似说了很多废话。东西是拿来用的,不是拿来吹的,所以就拿来用吧。

2.1 autoconf的使用

首先看看autoconf怎么用。autoconf接受一个configure.ac的文件,根据里面的内容来生成configure脚本。怎么还有文件?嗯,总是要有输入的嘛,反正简单得多就是了(大型软件的configure.ac可能也挺复杂,不过总比自己写configure要来得轻松得多)。

2.1.1 configure.ac文件

现在一步一步来看看最简单的configure.ac里有些什么,首先是两句初始化命令:

AC_INIT(src/main.cpp)

AM_INIT_AUTOMAKE(main, 0.1)

这两句是所有configure.ac里都必须有的,AC_INIT的参数是你main函数所在的文件(包括路径),AM_INIT_AUTOMAKE指定了程序的名称和版本号。名称可以随意起,只要符合标识符规则就行。注意第二行的开头是AM而不是AC。

接下来定义程序语言,C语言用AC_PROG_CC,C 用AC_PROG_CXX,其他语言请自行搜索。

然后可以加一些其他选项了,我见过的是AC_PROG_INSTALL、PKG_CHECK_MODULES和AC_SUBST,目前对它们还没什么了解,先放一边.

如果要用到库(也就是有个目录的代码本身不是文件,是给其他目录include用的),就还要加上这么一句:

AC_PROG_RANLIB

最后指定要输出的Makefile文件,注意是每个有代码(或者有Makefile.am)的地方都要输出,不同的文件之间用空格隔开。大概类似这个样子:

AC_OUTPUT(Makefile src/Makefile)

这就是一个最简单的configure.ac文件了

2.2 automake的使用

2.2.1 Makefile.am文件

再看看Makefile.am。

在你的代码所存放的地方要定义bin_PROGRAMS,如

bin_PROGRAMS = main

这个定义的就是编译好的可执行程序名。

然后就要定义程序文件,类似这个格式:

main_SOURCES = main.cpp a.h a.cpp

_SOURCES 前面的要与bin_PROGRAMS所定义的相一致,如果写的是bin_PROGRAMS = asdf,那么相应地要改为asdf_SOURCES。之后要包含该Makefile.am文件所在目录中所有的程序文件(当然,没用到的可以不包含),用空格隔开。不在这个目录下的(哪怕是在这个目录的子目录下)都不要包含进去.那么子目录下的文件怎么办?我们可以用SUBDIRS指定子目录,如:

SUBDIRS = sub abc

相邻的子目录用空格分开。SUBDIRS里指定的每个子目录中都必须要有Makefile.am(相应地在configure.ac里也要加入到AC_OUTPUT中)。要注意一点是bin_PROGRAMS定义的是一个可执行文件,也就是说之后的XXX_PROGRAMS中定义的文件必须有一个是有main函数的。要是我们的子目录中的代码不是一个独立的程序,只是拿来给其他目录的程序include的怎么办?要用noinst_LIBRARIES来将它定义为库,如

noinst_LIBRARIES = lib.a

之后和定义了bin_PROGRAMS一样定义XXX_SOURCES,例如根据上面noinst_LIBRARIES所定义的,我们可以这样来定义:
lib_a_SOURCES = a.cpp a.h

注意“.”要改成“_”,也誻lib.a在作为XXX_SOURCES的头部时变成了lib_a
最后哪里引用了这些代码,要加入相应地语句。比方说,这个目录名字为sub,在它的上层目录要引用到这些代码,那么要在它的上层目录中的Makefile.am中加入这么一句:

LDADD = sub/lib.a

来指定调用了这个目录的代码(其实我们是把sub目录下的代码编译成了一个库,库文件为lib.a,LDADD就是指定要调用哪个库)。最后,别忘了使用库时,要给configure.ac中加入AC_PROG_RANLIB. 由于Makefile.am有多个,刚才的介绍可能有点乱,下面来总结一下Makefile.am是怎么放的:

  1. 根目录(configure.ac所在的目录)必须有一个Makefile.am
  2. 所有有需要编译的代码文件的目录下必须有一个Makefile.am
  3. 如果一个目录中有Makefile.am,那么必须在它的父目录中的Makefile.am里用SUBDIRS指定它


于是这两个文件大致介绍完了,当然,只是介绍了要编译一个简单程序的最基本、最通用的部分,没介绍的东西(也就是我现在还不懂的东西)多着呢。

2.3 autoheader

在介绍如何使用这两个文件之前,首先要说说另一个工具:autoheader 它用来生成一个config.h文件 ,里面包含一些和平台相关的程序代码,供程序使用。也就是说,你可以在程序里include这个header.h,然后使用其中的某些定义好的常量什么的。由于我没用过,所以对它的介绍也就到此为止了。

2.4 使用

现在到了使用这些文件的时候了。
首先我们要运行的是autoheader(当然,如果不想要config.h的话,就跳过这一步吧)。
之后要运行的是aclocal,它的作用是生成autoconf所需要的一些宏的定义(也就是生成我们在configure.ac中所使用的扩展宏)。
然后运行autoconf。
之后理论上应该是automake,不过automake它还要求你必须有一些额外的文件,它们是:install-sh、missing、depcomp、INSTALL、NEWS、README、AUTHORS、ChangeLog、COPYING,它们是一个符合GNU规范的代码文件结构所必须的文件。automake可以通过附加--add-missing参数自动生成其中的一些文件(install-sh、missing、depcomp、INSTALL、COPYING),剩下的要自己创建。我们可以用touch命令来创建一个空文件,然后再运行automake。
之后就可以运行configure脚本来创建Makefile,再运行make来编译了。
总结一下,调用的命令应该是:
autoheader
aclocal
autoconf
automake
./configure
make
如果没有automake所需要的那些其他文件的话,应该是这样:
autoheader
aclocal
autoconf
touch NEWS README AUTHORS ChangeLog
automake --add-missing
./configure
make

可以没有autoheader(如果不需要它生成的config.h)的话
编译生成的可执行文件不一定是在程序的根目录的。若一个Makefile.am定义了bin_PROGRAMS,那么它所定义的bin_PROGRAMS相对应的可执行文件会与它在同一个目录下。

3 举例

下面来看看一个简单的例子。程序总共有3个文件,分别是main.cpp、a.h和a.cpp,其中main.cpp在src目录下,a.h和a.cpp是main.cpp所需要引用的代码,位于src目录的sub子目录下。我们想为main.cpp生成名为hello的可执行文件。
首先在程序根目录下编写configure.ac文件:
AC_INIT(src/main.cpp)
AM_INIT_AUTOMAKE(hello, 0.1)
AC_PROG_CXX
AC_PROG_RANLIB
AC_OUTPUT(Makefile src/Makefile src/sub/Makefile)

然后是程序根目录下的Makefile.am文件:
SUBDIRS = src

之后是src目录下的Makefile.am
bin_PROGRAMS = main
main_SOURCES = main.cpp
SUBDIRS = sub
LDADD = sub/lib.a

最后是src/sub目录下的Makefile.am
noinst_LIBRARIES = lib.a
lib_a_SOURCES = a.cpp a.h

编译成功后,就可以在src目录下看到hello文件了


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值