使用autotools

一、基本的:(<嵌入式Linux应用程序开发详解>
   
   
 autotools使用流程
   
   
正如前面所言,autotools是系列工具,读者首先要确认系统是否装了以下工具(可以用which命令进行查看)。
   
   
·  aclocal
   
   
·  autoscan
   
   
·  autoconf
   
   
·  autoheader
   
   
·  automake
   
   
使用autotools主要就是利用各个工具的脚本文件以生成最后的Makefile。其总体流程是这样的:
   
   
· 使用aclocal生成一个“aclocal.m
    
    
     
     4
     
     
    
    文件,该文件主要处理本地的宏定义
   
   
· 改写“configure.scan”文件,并将其重命名为“configure.in”,并使用autoconf文件生成configure文件。
   
   
接下来,笔者将通过一个简单的hello.c例子带领读者熟悉autotools生成makefile的过程,由于在这过程中有涉及到较多的脚本文件,为了更清楚地了解相互之间的关系,强烈建议读者实际动手操作以体会其整个过程。
   
   
1autoscan
   
   
它会在给定目录及其子目录树中检查源文件,若没有给出目录,就在当前目录及其子目录树中进行检查。它会搜索源文件以寻找一般的移植性问题并创建一个文件“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”。
   
   
2autoconf
   
   
configure.inautoconf的脚本配置文件,它的原型文件“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)
   
   
AM_INITOMAKE
   
   
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.m
   
   
    
    4
    
    
   
   文件,该文件主要处理本地的宏定义。如下所示:
[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
   
   
3autoheader
   
   
接着使用autoheader命令,它负责生成config.h.in文件。该工具通常会从“acconfig.h”文件中复制用户附加的符号定义,因此此处没有附加符号定义,所以不需要创建“acconfig.h”文件。如下所示:
[root@localhost automake]# autoheader
   
   
4automake
   
   
这一步是创建Makefile很重要的一步,automake要用的脚本配置文件是Makefile.am,用户需要自己创建相应的文件。之后,automake工具转换成Makefile.in。在该例中,笔者创建的文件为Makefile.am如下所示:
AUTOMAKE_OPTIONS=foreign
   
   
bin_PROGRAMS= hello
   
   
hello_SOURCES= hello.c
下面对该脚本文件的对应项进行解释。
   
   
· 其中的AUTOMAKE_OPTIONS为设置automake的选项。由于GNU(在第1章中已经有所介绍)对自己发布的软件有严格的规范,比如必须附带许可证声明文件COPYING等,否则automake执行时会报错。automake提供了三种软件等级:foreigngnugnits,让用户选择采用,默认等级为gnu。在本例使用foreign等级,它只检测必须的文件。
   
   
·  bin_PROGRAMS定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空格隔开。
   
   
·  hello_SOURCES定义“hello”这个执行程序所需要的原始文件。如果”hello”这个程序是由多个原始文件所产生的,则必须把它所用到的所有原始文件都列出来,并用空格隔开。例如:若目标体“hello”需要“hello.c”、“sunq.c”、“hello.h”三个依赖文件,则定义hello_SOURCES=hello.c sunq.c hello.h。要注意的是,如果要定义多个执行文件,则对每个执行程序都要定义相应的file_SOURCES
   
   
接下来可以使用automake对其生成“configure.in”文件,在这里使用选项“—adding-missing”可以让automake自动添加有一些必需的脚本文件。如下所示:
[root@localhost automake]# automake --add-missing
   
   
                  (或touch NEWS README AUTHORS ChangeLog
   
   
                      automake -a  )
   
   
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 
   
   
autotools生成的Makefile除具有普通的编译功能外,还具有以下主要功能(感兴趣的读者可以查看这个简单的hello.c程序的makefile):
   
   
1make
   
   
键入make默认执行”make all”命令,即目标体为all,其执行情况如下所示:
   
   
[root@localhost automake]# make
   
   
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
   
   
此时在本目录下就生成了可执行文件“hello”,运行“./hello”能出现正常结果,如下所示:
   
   
[root@localhost automake]# ./hello
   
   
Hello!Autoconf!
   
   
2make 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!Autoconf!
   
   
3make clean
   
   
此时,make会清除之前所编译的可执行文件及目标文件(object file, *.o),如下所示:
   
   
[root@localhost automake]# make clean
   
   
test -z "hello" || rm -f hello
   
   
rm -f *.o
   
   
4make 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确实是软件维护与发布的必备工具,也鉴于此,如今GUN的软件一般都是由automake来制作的。
   
   
二、使用静态库
   
   
test/lib/test1.c
#include <stdio.h>
int hello_world1()
{
    printf("hello world1/n");
    return 1;
}

test/lib/test2.c
#include <stdio.h>
void hello_world2()
{
    printf(" hello world2/n");
}
test/app.c
#include <stdio.h>
int main()
{
    hello_world1();
}
现在我们要将lib目录下的文件编译成静态库,并把他整合到最终的app程序中。
$autoscan
$ls
app.c  autoscan.log  configure.scan  lib
$mv configure.scan configure.in
autoscan
命令将用来生成初步的configure.in文件
现在我们更改configure.in文件
加入
AM_INIT_AUTOMAKE([-Wall -Werror])
(或AM_INIT_AUTOMAKE
初始化Automake,开启所有的警告,并将它们上报为错误
AC_PROG_RANLIB
声明静态库编译工具为ranlibGUN ranlib是另一个形式的ar
AC_CONFIG_FILES([
        Makefile
        lib/Makefile])
声明Makefilelib/Makefile为输出文件
test/Makefile.am
AUTOMAKE_OPTIONS=foreign
SUBDIRS = lib
bin_PROGRAMS=app
app_SOURCES=app.c
app_LDADD= lib/libtest.a
递归构建
lib
bin
目录下的为
app
app
的源代码是
app.c
app
的链接库是
lib/libtest.a
test/lib/Makefile.am
lib_LIBRARIES = libtest.a
libtest_a_SOURCES = test1.c test2.c
安装到$(libdir)目录下的文件为
libtest.a
编译libtest.a的源代码是
test1.c test2.c
$ls -R
.:
app.c  configure.in  lib  Makefile.am
./lib:
Makefile.am  test1.c  test2.c
$autoreconf --install
configure.in:6: installing `./missing'
configure.in:6: installing `./install-sh'
lib/Makefile.am: installing `./depcomp'
标志--install意思是拷贝遗失的辅助文件

每个人的输出可能有点不同,不出错就基本上没问题
$./configure --prefix ~/test
...
--prefix
指定了要安装的目录
$make && make install
也许有人发现了在目录下有个app可执行程序,但是他并非是我们所要的目标二进制文件,他是一个bash脚本,我们所要的已经在~/test/bin目录下了
好了,我们核对下是否正确
$cd ~/test
$ls -R
.:
bin  lib

./bin:
app

./lib:
libtest.a
$ldd bin/app
        linux-gate.so.1 =>  (0x0011e000)
        libc.so.6 => /lib/libc.so.6 (0x00ad2000)
        /lib/ld-linux.so.2 (0x00101000)
没有动态链接的libtest.a的迹象
$bin/app
hello world1
三、
动态库的编译
test/configure.in
AC_PROG_RANLIB改为AC_PROG_LIBTOOL
并加入AC_DISABLE_STATIC,禁止静态库的生成
test/Makefile.am
中的app_LDADD= lib/libtest.a改为app_LDADD= lib/libtest.la
对于动态库,libtool帮助产生的是一种比较通用形式即la文件
test/lib/Makefile.am
lib_LTLIBRARIES= libtest.la
libtest_la_SOURCES = test1.c test2.c
注意是lib_LTLIBARIES

指明了是libtool产生的库形式
继续编译静态库的形式
注意:为了不混淆请先清除~/test文件内容
$autoreconf --install
$./configure --prefix ~/test
$make && make install
剩下检验结果
$cd ~/test/
$ldd bin/app
        linux-gate.so.1 =>  (0x0011e000)
        libtest.so.0 => /home/secularbird/test/lib/libtest.so.0 (0x 0011f 000)
        libc.so.6 => /lib/libc.so.6 (0x00ad2000)
        /lib/ld-linux.so.2 (0x00101000)
我们看到app程序的运行需要连接到相应的libtest文件上
$bin/app
hello world1
这些是从网上收集的一些材料. 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值