2011-03-25 20:48

AutoTools 简单入门 [转]

学习GNU/LINUX 开发的编程人员,上手之后不久就会在编译开源软件的时候碰到configure脚本,过段时间还会知道configure脚本是autoconf生成的; 但是真正想用起来autoconf,却是要弄明白config.h,configure.in,Makfile.am等一大堆的文件,这可能要花些功夫。 让我们从一个例子开始,争取为大家省点力气。

我们用个小程序作例子,计算一个整数的开方,建个工作目录:sqrt。程序很简单:
 #include<stdio.h>
 #include<math.h>
 int main()
 {
  int i=0;
  scanf("%d",&i);
  printf("sqrt(%d)=%f\n",i,sqrt(i));
 }
 接下来我们要编译这个程序:
 $cc -X -lm -o sqrt sqrt.c
 因为我们使用了数学库,所以要给链接器传递一个参数-lm。
 程序就完成了。
 我们想专业一点,给这个程序增加Make文件,不用再输入那么长的命令,同时还想让这个程序成为可移植的程序。这个时候,我们就需要用到autotools了。
 autotools包含了几个部分,最常用到的是autoconf和automake。
 我们先加入autoconf。
 autoconf需要一个configure.ac文件,幸运的是,我们不需要自己写这个文件,我们可以使用autoscan来生成这个文件。执行autoscan。
 $autoscan
autom4te: configure.ac: no such file or directory
autoscan: /usr/bin/autom4te failed with exit status: 1
错误信息先不用管,目录下多了几个文件: autoscan.log  configure.scan。我们要关心的是configure.scan,这是一个原始版本的configure.ac。打开这个文件,把下面这一行修改一下:
 AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
 改成
 AC_INIT([sqrt], [0.1.0], [you@mail.address])
参数的意思一目了然,不罗嗦了。接下来将文件另存为:configure.ac。执行:
 $autoconf
 我们看到,目录下又多了一些内容,我们关心的是configure这个脚本文件,执行一下试试吧!
 不过现在这个configure还没什么用,要发挥configure的真正目的——识别编译环境,配置编译选项的话,还要进行一些操作。

首先编辑configure.ac文件,在我们之前改动的AC_INIT...一行下面,加入如下一行内容:
AM_INIT_AUTOMAKE 
再执行一次autoconf试试?很不幸,我们遇到了错误:
configure.ac:6: error: possibly undefined macro: AM_INIT_AUTOMAKE...
因为找不到AM_INIT_AUTOMAKE宏,不要担心,因为我们少做了一步,先要把这些宏生成一下,当然是自动的。
$aclocal
$autoconf
现在的autoconf没有报错。这个时候再看看目录下面,发现多了一个aclocal.m4文件,这就是aclocal声称的宏命令文件,autoconf会使用它来生成新的configure脚本。
 是不是现在就能够自动搞定Makefile了?我们现在再执行一下configure,看看输出:
 configure: error: cannot find install-sh or install.sh in . ./.. ./../..
 和我们想的有点不同,我们还要用到automake命令做一些其它的事情,我们先执行一下:
 $automake
 configure.ac: required file `./install-sh' not found
 configure.ac: required file `./missing' not found
 automake: no `Makefile.am' found for any configure output
 我们注意到最后一行,知道了还需要一个`Makefile.am`文件,这个文件我们要写一下,编辑一个文件,增加:
 bin_PROGRAMS = sqrt
 sqrt_SOURCES = sqrt.c
 sqrt_LDADD = $(LIBOJBS)
 执行automake试试?
 configure.ac: required file `./install-sh' not found
configure.ac: required file `./missing' not found
automake: no `Makefile.am' found for any configure output
automake: Did you forget AC_CONFIG_FILES([Makefile]) in configure.ac?
 哦,不行,还要install-sh,missing文件,错误信息中,还提到AC_CONFIG_FILES([Makefile]),是的,我们还要修改一下configure.ac,在最后一行AC_OUTPUT前面增加一行:
 AC_CONFIG_FILES([Makefile])
 现在再执行一次automake吧,但是我们要加一个参数:
 $automake --add-missing
 configure.ac: installing `./install-sh'
 configure.ac: installing `./missing'
 Makefile.am: installing `./INSTALL'
 Makefile.am: required file `./NEWS' not found
 Makefile.am: required file `./README' not found
 Makefile.am: required file `./AUTHORS' not found
 Makefile.am: required file `./ChangeLog' not found
 Makefile.am: installing `./COPYING'
 configure.ac:8: required file `config.h.in' not found

前面缺的四个文件简单,我们按照自己的情况编辑保存即可,config.h.in从哪里来呢? 现在让我们把config.h.in搞出来,这个要用到autoheader,我们执行命令:
 $autoheader
 config.h.in文件就生成好了。准备好了其它几个文本文件,我们再执行一次,这次不用加参数了,不过我们还要再执行一次autoconf,因为我们修改了configure.ac之后还没有执行过autoconf。
 $autoconf
 $automake
 我们再执行一次./configure:
 $./configure
 ...
 config.status: creating Makefile
 config.status: creating config.h
 ...
 让我们执行一下make吧。
 $make
 ...
 /home/nevernew/sqrt/sqrt.c:7: undefined reference to `sqrt'
 ...
 是因为我们没有把数学库加入链接,修改Makefile.am,将对应行修改为:
 sqrt_LDADD = $(LIBOBJS) -lm
 更新一下文件:
 $autoconf
 $automake
 $./configure
 $make
 $./sqrt

http://liuskysun.blog.163.com/blog/static/99812978201122454256231/

====================================================================================

Makefile固然可以帮助make完成它的使命,但要承认的是,编写Makefile确实不是一件轻松的事,尤其对于一个较大的项目而言更是如此。那么,有没有一种轻松的手段生成Makefile而同时又能让我们享受make的优越性呢?本节要讲autotools系列工具正是为此而设的,它只需用户输入简单的目标文件、依赖文件、文件目录等就可以轻松地生成Makefile了,这无疑是广大用户的所希望的。另外,这些工具还可以完成系统配置信息的收集,从而可以方便地处理各种移植性的问题。也正是基于此,现在Linux上的软件开发一般都用autotools来制作Makefile。
   
autotools使用流程
   
   正如前面所言,autotools是系列工具,读者首先要确认系统是否装了以下工具(可以用which命令进行查看)。

·  aclocal

·  autoscan

·  autoconf

·  autoheader

·  automake

使用autotools主要就是利用各个工具的脚本文件以生成最后的Makefile。其总体流程是这样的:

·  使用aclocal生成一个“aclocal.m4”文件,该文件主要处理本地的宏定义;

·  改写“configure.scan”文件,并将其重命名为“configure.in”,并使用autoconf文件生成configure文件。

接下来,将通过一个简单的hello.c例子来熟悉autotools生成makefile的过程.

1.autoscan

它会在给定目录及其子目录树中检查源文件,若没有给出目录,就在当前目录及其子目录树中进行检查。它会搜索源文件以寻找一般的移植性问题并创建一个文件“configure.scan”,该文件就是接下来autoconf要用到的“configure.in”原型。如下所示:

[root@localhost automake]# autoscan

autom4te: configure.ac: no such file or directory

autoscan: /usr/bin/autom4te failed with exit status: 1

[root@localhost automake]# ls

autoscan.log  configure.scan  hello.c

如上所示,autoscan首先会尝试去读入“configure.ac”(同configure.in的配置文件)文件,此时还没有创建该配置文件,于是它会自动生成一个“configure.in”的原型文件“configure.scan”。

2.autoconf

configure.in是autoconf的脚本配置文件,它的原型文件“configure.scan”如下所示:

#                                               -*- Autoconf -*-

# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)

#The next one is modified by sunq

#AC_INIT(FULL-PACKAGE-NAME,VERSION,BUG-REPORT-ADDRESS)

AC_INIT(hello,1.0)

# The next one is added by sunq

AM_INIT_AUTOMAKE(hello,1.0)

AC_CONFIG_SRCDIR([hello.c])

AC_CONFIG_HEADER([config.h])

# 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_CONFIG_FILES([Makefile])

AC_OUTPUT

下面对这个脚本文件进行解释:

·  以“#”号开始的行为注释。

·  AC_PREREQ宏声明本文件要求的autoconf版本,如本例使用的版本2.59。

·  AC_INIT宏用来定义软件的名称和版本等信息,在本例中省略了BUG-REPORT-ADDRESS,一般为作者的e-mail。

·  AM_INIT_AUTOMAKE是笔者另加的,它是automake所必备的宏,也同前面一样,PACKAGE是所要产生软件套件的名称,VERSION是版本编号。

·  AC_CONFIG_SRCDIR宏用来侦测所指定的源码文件是否存在,来确定源码目录的有

效性。在此处为当前目录下的hello.c。

·  AC_CONFIG_HEADER宏用于生成config.h文件,以便autoheader使用。

·  AC_CONFIG_FILES宏用于生成相应的Makefile文件。

·  中间的注释间可以添加分别用户测试程序、测试函数库、测试头文件等宏定义。

接下来首先运行aclocal,生成一个“aclocal.m4”文件,该文件主要处理本地的宏定义。如下所示:

[root@localhost automake]# aclocal

再接着运行autoconf,生成“configure”可执行文件。如下所示:

[root@localhost automake]# autoconf

[root@localhost automake]# ls

aclocal.m4  autom4te.cache  autoscan.log  configure  configure.in  hello.c

3.autoheader

接着使用autoheader命令,它负责生成config.h.in文件。该工具通常会从“acconfig.h”文件中复制用户附加的符号定义,因此此处没有附加符号定义,所以不需要创建“acconfig.h”文件。如下所示:

[root@localhost automake]# autoheader

4.automake

这一步是创建Makefile很重要的一步,automake要用的脚本配置文件是Makefile.am,用户需要自己创建这个文件。之后,automake工具将其转换成Makefile.in。
    在该例中,创建的文件为Makefile.am如下所示:

AUTOMAKE_OPTIONS=foreign

bin_PROGRAMS= hello

hello_SOURCES= hello.c hello.h

下面对该脚本文件的对应项进行解释。

·  其中的AUTOMAKE_OPTIONS为设置automake的选项。由于GNU(在第1章中已经有所介绍)对自己发布的软件有严格的规范,比如必须附带许可证声明文件COPYING等,否则automake执行时会报错。automake提供了三种软件等级:foreign、gnu和gnits,让用户选择采用,默认等级为gnu。在本例使用foreign等级,它只检测必须的文件。

·  bin_PROGRAMS定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空格隔开。

·  hello_SOURCES定义“hello”这个执行程序所需要的原始文件。如果”hello”这个程序是由多个原始文件所产生的,则必须把它所用到的所有原始文件都列出来,并用空格隔开。例如:若目标体“hello”需要“hello.c”、“sunq.c”、“hello.h”三个依赖文件,则定义hello_SOURCES=hello.c sunq.c hello.h。
    接下来可以使用automake对其生成“configure.in”文件,在这里使用选项“—adding-missing”可以让automake自动添加有一些必需的脚本文件。如下所示:

[root@localhost automake]# automake --add-missing

configure.in: installing './install-sh'

configure.in: installing './missing'

Makefile.am: installing 'depcomp'

[root@localhost automake]# ls

aclocal.m4      autoscan.log  configure.in  hello.c     Makefile.am  missing

autom4te.cache  configure     depcomp    install-sh  Makefile.in  config.h.in

可以看到,在automake之后就可以生成configure.in文件。

5.运行configure

在这一步中,通过运行自动配置设置文件configure,把Makefile.in变成了最终的Makefile。如下所示:

[root@localhost automake]# ./configure

checking for a BSD-compatible install... /usr/bin/install -c

checking whether build enVironment is sane... yes

checking for gawk... gawk

checking whether make sets $(MAKE)... yes

checking for Gcc... Gcc

checking for C compiler default output file name... a.out

checking whether the C compiler works... yes

checking whether we are cross compiling... no

checking for suffix of executables...

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 ANSI C... 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

可以看到,在运行configure时收集了系统的信息,用户可以在configure命令中对其进行方便地配置.
在./configure的自定义参数有两种,一种是开关式(--enable-XXX或--disable-XXX),另一种是开放式,即后面要填入一串字符(--with-XXX=yyyy)参数。读者可以自行尝试其使用方法。另外,读者可以查看同一目录下的”config.log”文件,以方便调试之用。

到此为止,makefile就可以自动生成了。回忆整个步骤,用户不再需要定制不同的规则,而只需要输入简单的文件及目录名即可,这样就大大方便了用户的使用。

autotools生成的Makefile除具有普通的编译功能外,还具有以下主要功能:
1.make

键入make默认执行”make all”命令,即目标体为all,其执行情况如下所示:

[root@localhost automake]# make

if Gcc -D PACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"hello\" -DVERSION=\"1.0\"  -I. -I.     -g -O2 -MT hello.o -MD -MP -MF ".deps/hello.Tpo" -c -o hello.o hello.c; \

then mv -f ".deps/hello.Tpo" ".deps/hello.Po"; else rm -f ".deps/hello.Tpo"; exit 1; fi

Gcc  -g -O2   -o hello  hello.o

此时在本目录下就生成了可执行文件“hello”,运行“./hello”能出现正常结果,如下所示:

[root@localhost automake]# ./hello

Hello everyone!

2.make install

此时,会把该程序安装到系统目录中去,如下所示:

[root@localhost automake]# make install

if Gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"hello\" -DVERSION=\"1.0\"  -I. -I.     -g -O2 -MT hello.o -MD -MP -MF ".deps/hello.Tpo" -c -o hello.o hello.c; \

then mv -f ".deps/hello.Tpo" ".deps/hello.Po"; else rm -f ".deps/hello.Tpo"; exit 1; fi

Gcc  -g -O2   -o hello  hello.o

make[1]: Entering directory '/root/workplace/automake'

test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"

  /usr/bin/install -c 'hello' '/usr/local/bin/hello'

make[1]: Nothing to be done for 'install-data-am'.

make[1]: LeaVing directory '/root/workplace/automake'

此时,若直接运行hello,也能出现正确结果,如下所示:

[root@localhost automake]# hello

Hello everyone!

3.make clean

此时,make会清除之前所编译的可执行文件及目标文件(object file, *.o),如下所示:

[root@localhost automake]# make clean

test -z "hello" || rm -f hello

rm -f *.o

4.make dist

此时,make将程序和相关的文档打包为一个压缩文档以供发布,如下所示:

[root@localhost automake]# make dist

[root@localhost automake]# ls hello-1.0-tar.gz

hello-1.0-tar.gz

可见该命令生成了一个hello-1.0-tar.gz的压缩文件。

AutoTools 疑难解决方法相关推荐

  1. win7系统每次开机都需要疑难解答的原因与解决方法

    最近有些win7旗舰版的用户发现自己的电脑每次开机都无法正常连接网络,需要自己手动点击一下疑难解答才可以恢复正常连接,非常麻烦,那么Win7旗舰版系统每次开机都需要疑难解答怎么办呢?下面小编就给大家带 ...

  2. Win10插入耳机后无声音,声音问题疑难解答提示“外设似乎没有插上” 三种解决方法

    方法一 一.打开声音问题疑难解答进行检测 若检测结果如下: 二.确认声音为 windows 默认而不是无声 个性化–主题–高级声音设置–windows默认 三.确认声卡已安装且为最新版本(重点) 1. ...

  3. cf两边黑屏怎么解决win10_Win10电脑开机黑屏只有鼠标指针无法进入桌面的解决方法...

    近期遇到Win10电脑开机之后,黑屏只有鼠标,等待很久也显示不出来桌面,多次电脑重新启动也无法解决这个问题.除了重新做系统,那么遇到这个问题我们要如何解决?下面装机之家分享一下Win10电脑开机黑屏只 ...

  4. win10 调用计算机,Win10系统打开此电脑提示正在处理它解决方法

    相信绝大数的用户,在使用系统的过程中难免会遇到各种疑难杂症,就在近期有一网友遇到一个奇怪的Win10系统故障,双击打开"此电脑"或者打开某个系统分区(C盘或D盘)或者打开某个文件夹 ...

  5. 一不小心把win10的秘钥卸载了解决方法

    我遇到的第一个问题是Win10家庭版激活失败提示错误代码0xC004C003 然后我百度后看到一个解决方法是卸载秘钥然后再输入秘钥的,于是我执行了slmgr.vbs /upk,发现win10秘钥被卸载 ...

  6. Win8/Win8.1常见错误代码的解决方法汇总

    相信已经有不少网友早已升级到Windows 8.1,同时,伴随Windows XP操作系统服务终止,也会有部分老用户直接升级到最新系统.为了帮助大家更好的使用,今天笔者就把一些常见系统错误汇总并予以解 ...

  7. win10系统打开更新服务器失败怎么回事,Win10系统一直无法安装更新怎么办 Win10更新一直安装失败的3种解决方法...

    经常会有小伙伴反馈,Win10无法安装更新怎么办?其实,Windows 10更新方法有很大,总有一种方式可以解决问题.以下是Win10更新失败的三种解决方式,帮你轻松解决更新失败问题. Win10更新 ...

  8. 打印机尚未链接到此计算机,win10系统无法连接打印机显示未指定设备的解决方法...

    有不少win10系统用户在使用打印机的时候,发现无法连接打印机,显示未指定设备,造成无法正常使用打印机,遇到这样的问题该如何处理呢,下文就给大家整理一下win10系统无法连接打印机显示未指定设备的解决 ...

  9. 云原生落地难的五个痛点与解决方法

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 在云原生的技术发展和实践快速演进的时代,企业面对五花八门 ...

最新文章

  1. 李茶:虎牙直播推荐系统架构详解
  2. android之descendantFocusability用法简析
  3. mysql 判断表或字段存不存在
  4. Flask Vue.js全栈开发
  5. Android之Providing Resources(提供资源)
  6. mongodb 字符串 截取_Mongodb split字符串后分组统计
  7. 213. 打家劫舍 II golang 动态规划
  8. 《Effective Java》 第一讲:创建和销毁对象
  9. TeamViewer——Ubuntu系统上的安装和卸载
  10. 分享,iOS国家手机区号代码.plist
  11. 搜索及代码在GitHub上查重小技巧
  12. Java Session对象的钝化和活化
  13. 墨者 SQL手工注入漏洞测试(MySQL数据库)
  14. 活久见!程序员开发进度太慢被公司告上法庭,索赔 90 万!
  15. 《利用python进行数据分析》第二版 第13章-Python建模库介 学习笔记
  16. Android根据语言适配货币符,ios – 使用NSLocale根据国家/地区代码或国家/地区名称获取货币符号...
  17. 【深度学习】VGG16--slim
  18. 什么叫做走心的文案?怎么写走心的文案?
  19. linux kernel mtd 分区
  20. C#实现向手机发送验证码短信

热门文章

  1. 蒙特卡洛抽样电动汽车充电负荷
  2. 紫外-可见分光光度计使用注意事项
  3. 【Python爬虫系列】为什么我喜欢python?来看看这些让人爱不释手的原因吧,购物网站大盘点,看过这些python做的项目,我立马入坑了…(神奇 | 爱了,爱了)
  4. 零基础数据挖掘入门系列(二) - 数据的探索性(EDA)分析
  5. 论文邮箱不是导师的_终极答案:你的论文为何在导师那里“石沉大海”?
  6. Android读取手机ROM总大小方法
  7. 2017杭电ACM集训队单人排位赛 - 2 -1002 地狱飞龙 (辛普森公式求积分)(模板)
  8. com.ibm.mq.MQException: MQJE001: 完成代码为“2”,原因为“2495”。 no mqjbnd64 in java.library.path
  9. 浏览器支持字体大小情况 以及 Chrome设置小于12px的字体的处理方案
  10. 论文阅读——Unsupervised Neural Machine Translation with Indirect Supervision