您的位置:首页 > 其它

GNU Autotools的使用方法

2012-05-24 17:33 399 查看
http://blog.csdn.net/scucj/article/details/6079052

手工写Makefile是一件很有趣的事情,对于比较大型的项目,如果有工具可以代劳,自然是一件好事。在Linux系统开发环境中,GNU Autotools 无疑就充当了这个重要角色。(在Windows系统的开发环境中,IDE工具,诸如Visual Studio,来管理项目也很方便。)

      本文以一个简单项目为例子,来讲述GNU Autotools的一列工具及其命令的用法。

autotools是系列工具, 它主要由autoconf、automake、perl语言环境和m4等组成;所包含的命令有五个:

    (1)aclocal

    (2)autoscan

    (3)autoconf

    (4)autoheader

    (5)automake

一、准备源代码

(1)目录project包含一个main.c的文件和两个子目录lib与include;lib目录中包含一个test.c,include目录中包含一个test.h。在系统中,显示如下:

[c-sharp]
view plaincopyprint?

[root@localhost project]# ls 
include  lib  main.c 
[root@localhost project]# 
[root@localhost project]# ls include/ 
test.h 
[root@localhost project]# ls lib/ 
test.c 
[root@localhost project]# 

[cpp]
view plaincopyprint?

/* project/main.c */ 

#include <stdio.h> 
#include "include/test.h" 

int main() 
{ 
    printf("main entrance./n"); 

    test_method(); 
    return 0; 
} 

/* project/main.c */
#include <stdio.h>
#include "include/test.h"
int main()
{
printf("main entrance./n");
test_method();
return 0;
}


[c-sharp]
view plaincopyprint?

/* project/lib/test.c */ 

#include <stdio.h> 
#include "../include/test.h" 

void test_method() 

    printf("test method./n"); 



[cpp]
view plaincopyprint?

/* project/include/test.h*/ 

void test_method(); 

/* project/include/test.h*/
void test_method();


二、autotools 使用步骤

     2.1 使用autoscan命令,它将扫描工作目录,生成 configure.scan 文件。    

[c-sharp]
view plaincopyprint?

[root@localhost project]# autoscan 
autom4te: configure.ac: no such file or directory 
autoscan: /usr/bin/autom4te failed with exit status: 1 

[root@localhost project]# ls 
autoscan.log  configure.scan  include  lib  main.c 

[root@localhost project]# 

[c-sharp]
view plaincopyprint?

[root@localhost project]mv configure.scan configure.ac 

[root@localhost project]# ls 
autoscan.log  configure.ac include  lib  main.c 
[root@localhost project]# 
[root@localhost project]# cat configure.ac 
#                                               -*- Autoconf -*- 

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

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

AC_CONFIG_SRCDIR([main.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_OUTPUT 
[root@localhost project]# 

[root@localhost project]mv configure.scan configure.ac
[root@localhost project]# ls
autoscan.log  configure.ac include  lib  main.c
[root@localhost project]#
[root@localhost project]# cat configure.ac
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([main.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_OUTPUT
[root@localhost project]#


     2.3 对 configure.ac 文件做适当的修改,修改显示如下[1]:

[c-sharp]
view plaincopyprint?

[root@localhost project]# cat configure.ac 
#                                               -*- Autoconf -*- 

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

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

AC_INIT(hello,1.0,abc@126.com) 
AM_INIT_AUTOMAKE(hello,1.0) 
AC_CONFIG_SRCDIR([main.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 

[c-sharp]
view plaincopyprint?

[root@localhost project]# aclocal 
[root@localhost project]# ls 
aclocal.m4  autom4te.cache  autoscan.log  configure.in  include  lib  main.c 

[root@localhost project]# 

[root@localhost project]# aclocal
[root@localhost project]# ls
aclocal.m4  autom4te.cache  autoscan.log  configure.in  include  lib  main.c
[root@localhost project]#


2.5 使用 autoconf 命令生成 configure 文件。这个命令将 configure.ac 文件中的宏展开,生成 configure 脚本。这个过程可能要用到aclocal.m4中定义的宏。

[c-sharp]
view plaincopyprint?

[root@localhost project]# autoconf 
[root@localhost project]# ls 
aclocal.m4  autom4te.cache  autoscan.log  configure  configure.in  include  lib  main.c 

[cpp]
view plaincopyprint?

[root@localhost project]# autoheader 
[root@localhost project]# ls 
aclocal.m4  autom4te.cache  autoscan.log  config.h.in  configure  configure.in  include  lib  main.c 

[root@localhost project]# 

[root@localhost project]# autoheader
[root@localhost project]# ls
aclocal.m4  autom4te.cache  autoscan.log  config.h.in  configure  configure.in  include  lib  main.c
[root@localhost project]#


2.7 手工创建Makefile.am文件。Automake工具会根据 configure.in 中的参量把 Makefile.am 转换成 Makefile.in 文件。

[cpp]
view plaincopyprint?

[root@localhost project]# cat Makefile.am 
UTOMAKE_OPTIONS = foreign 
bin_PROGRAMS = hello 
hello_SOURCES = main.c include/test.h lib/test.c 

[cpp]
view plaincopyprint?

[root@localhost project]# 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' 
Makefile.am: installing `./depcomp' 
[root@localhost project]# 

[root@localhost project]# 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'
Makefile.am: installing `./depcomp'
[root@localhost project]#


2.8.1 再次使用 automake ——add-missing 运行一次,可以辅助生成几个必要的文件。

 

[cpp]
view plaincopyprint?

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

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 

[root@localhost project]# ls 
aclocal.m4  autom4te.cache  autoscan.log  config.h.in  config.h.in~  configure  configure.ac  COPYING  depcomp  include  INSTALL  install-sh  lib  main.c  Makefile.am  missing 

[root@localhost project]# 

[c-sharp]
view plaincopyprint?

[root@localhost project]# touch NEWS 
[root@localhost project]# touch README 
[root@localhost project]# touch AUTHORS 
[root@localhost project]# touch ChangeLog 
[root@localhost project]# 
[root@localhost project]# automake --add-missing 
[root@localhost project]# ls 
aclocal.m4  autom4te.cache  ChangeLog    config.h.in~  config.status  configure.ac  depcomp  INSTALL     lib     Makefile.am  missing  README 

AUTHORS     autoscan.log    config.h.in  config.log    configure      COPYING       include  install-sh  main.c  Makefile.in  NEWS 

[root@localhost project]# 

[root@localhost project]# touch NEWS
[root@localhost project]# touch README
[root@localhost project]# touch AUTHORS
[root@localhost project]# touch ChangeLog
[root@localhost project]#
[root@localhost project]# automake --add-missing
[root@localhost project]# ls
aclocal.m4  autom4te.cache  ChangeLog    config.h.in~  config.status  configure.ac  depcomp  INSTALL     lib     Makefile.am  missing  README
AUTHORS     autoscan.log    config.h.in  config.log    configure      COPYING       include  install-sh  main.c  Makefile.in  NEWS
[root@localhost project]#


2.9 使用 configure 命令, 把 Makefile.in 变成最终的 Makefile 文件。

[c-sharp]
view plaincopyprint?

[root@localhost project]# ./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: creating config.h 
config.status: config.h is unchanged 

config.status: executing depfiles commands 
[root@localhost project]# ls 
aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello    INSTALL     lib     main.o    Makefile.am  missing  README    test.o 

AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  include  install-sh  main.c  Makefile  Makefile.in  NEWS     stamp-h1 

[root@localhost project]# 

[c-sharp]
view plaincopyprint?

[root@localhost project]# make 
make  all-am 
make[1]: Entering directory `/home/chenjie/project' 

gcc  -g -O2   -o hello  main.o test.o 
make[1]: Leaving directory `/home/chenjie/project' 

[root@localhost project]# 
[root@localhost project]# ls 
aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello    INSTALL     lib     main.o    Makefile.am  missing  README    test.o 

AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  include  install-sh  main.c  Makefile  Makefile.in  NEWS     stamp-h1 

[root@localhost project]# 

[root@localhost project]# make
make  all-am
make[1]: Entering directory `/home/chenjie/project'
gcc  -g -O2   -o hello  main.o test.o
make[1]: Leaving directory `/home/chenjie/project'
[root@localhost project]#
[root@localhost project]# ls
aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello    INSTALL     lib     main.o    Makefile.am  missing  README    test.o
AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  include  install-sh  main.c  Makefile  Makefile.in  NEWS     stamp-h1
[root@localhost project]#


3.2 make clean 命令清除编译时的obj文件,它与 make 命令是对应关系,一个是编译,一个清除编译的文件

3.3 运行”./hello”就能看到运行结果:

[c-sharp]
view plaincopyprint?

[root@localhost project]# ./hello 
main entrance. 
test method. 
[root@localhost project]# 

[c-sharp]
view plaincopyprint?

[root@localhost project]# make install 
make[1]: Entering directory `/home/chenjie/project' 
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 `/home/chenjie/project' 
[root@localhost project]# 
[root@localhost project]# hello 
main entrance. 
test method. 
[root@localhost project]# 

[root@localhost project]# make install
make[1]: Entering directory `/home/chenjie/project'
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 `/home/chenjie/project'
[root@localhost project]#
[root@localhost project]# hello
main entrance.
test method.
[root@localhost project]#


3.5 make uninstall 命令把目标文件从系统中卸载。

3.6  make dist 命令将程序和相关的文档打包为一个压缩文档以供发布,在本例子中,生成的打包文件名为:hello-1.0.tar.gz。

[c-sharp]
view plaincopyprint?

[root@localhost project]# make dist 
{ test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {}
';' && rm -fr hello-1.0; }; } 
mkdir hello-1.0 
find hello-1.0 -type d ! -perm -755 -exec chmod a+rwx,go+rx {} /; -o / 

          ! -type d ! -perm -444 -links 1 -exec chmod a+r {} /; -o / 

          ! -type d ! -perm -400 -exec chmod a+r {} /; -o / 
          ! -type d ! -perm -444 -exec /bin/sh /home/chenjie/project/install-sh -c -m a+r {} {} /; / 

        || chmod -R a+r hello-1.0 
tardir=hello-1.0 && /bin/sh /home/chenjie/project/missing --run tar chof -
"$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz 

{ test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {}
';' && rm -fr hello-1.0; }; } 
[root@localhost project]# ls 
aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello             include  install-sh  main.c  Makefile     Makefile.in  NEWS   
stamp-h1 
AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  hello-1.0.tar.gz  INSTALL  lib         main.o  Makefile.am  missing      README  test.o 

[root@localhost project]# 

[c-sharp]
view plaincopyprint?

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

[root@localhost chenjie]# ls 
hello-1.0  hello-1.0.tar.gz 
[root@localhost chenjie]# cd hello-1.0 
[root@localhost hello-1.0]# ls 
aclocal.m4  AUTHORS  ChangeLog  config.h.in  configure  configure.ac  COPYING  depcomp  include  INSTALL  install-sh  lib  main.c  Makefile.am  Makefile.in  missing  NEWS 
README 
[root@localhost hello-1.0]# 
[root@localhost hello-1.0]# 
[root@localhost hello-1.0]# ./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: creating config.h 
config.status: executing depfiles commands 
[root@localhost hello-1.0]# 
[root@localhost hello-1.0]# make 
make  all-am 
make[1]: Entering directory `/home/chenjie/hello-1.0' 
if gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -MT main.o -MD -MP -MF
".deps/main.Tpo" -c -o main.o main.c; / 

        then mv -f ".deps/main.Tpo"
".deps/main.Po"; else rm -f
".deps/main.Tpo"; exit 1; fi 
if gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -MT test.o -MD -MP -MF
".deps/test.Tpo" -c -o test.o `test -f
'lib/test.c' || echo './'`lib/test.c; / 

        then mv -f ".deps/test.Tpo"
".deps/test.Po"; else rm -f
".deps/test.Tpo"; exit 1; fi 
gcc  -g -O2   -o hello  main.o test.o 
make[1]: Leaving directory `/home/chenjie/hello-1.0' 
[root@localhost hello-1.0]# 
[root@localhost hello-1.0]# make install 
make[1]: Entering directory `/home/chenjie/hello-1.0' 

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 `/home/chenjie/hello-1.0' 

[root@localhost hello-1.0]# 
[root@localhost hello-1.0]# hello 
main entrance. 
test method. 

[root@localhost chenjie]# ls
hello-1.0.tar.gz
[root@localhost chenjie]# tar -zxvf hello-1.0.tar.gz
[root@localhost chenjie]# ls
hello-1.0  hello-1.0.tar.gz
[root@localhost chenjie]# cd hello-1.0
[root@localhost hello-1.0]# ls
aclocal.m4  AUTHORS  ChangeLog  config.h.in  configure  configure.ac  COPYING  depcomp  include  INSTALL  install-sh  lib  main.c  Makefile.am  Makefile.in  missing  NEWS  README
[root@localhost hello-1.0]#
[root@localhost hello-1.0]#
[root@localhost hello-1.0]# ./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: creating config.h
config.status: executing depfiles commands
[root@localhost hello-1.0]#
[root@localhost hello-1.0]# make
make  all-am
make[1]: Entering directory `/home/chenjie/hello-1.0'
if gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -MT main.o -MD -MP -MF ".deps/main.Tpo" -c -o main.o main.c; /
then mv -f ".deps/main.Tpo" ".deps/main.Po"; else rm -f ".deps/main.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -MT test.o -MD -MP -MF ".deps/test.Tpo" -c -o test.o `test -f 'lib/test.c' || echo './'`lib/test.c; /
then mv -f ".deps/test.Tpo" ".deps/test.Po"; else rm -f ".deps/test.Tpo"; exit 1; fi
gcc  -g -O2   -o hello  main.o test.o
make[1]: Leaving directory `/home/chenjie/hello-1.0'
[root@localhost hello-1.0]#
[root@localhost hello-1.0]# make install
make[1]: Entering directory `/home/chenjie/hello-1.0'
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 `/home/chenjie/hello-1.0'
[root@localhost hello-1.0]#
[root@localhost hello-1.0]# hello
main entrance.
test method.


五、命令使用的整个流程图

    图我就不画了,转载两个图[2][3],对比着看,或许更明白一些。





六、总结

    本文描述了如果使用GNU Autotools的来管理源代码,发布源代码包,以及获得源代码包后如何编译、安装。由于这个例子过于简单,GNU Autotools的用法还未完全描述清楚,主要体现在以下几点:

    (1)在创建 Makefile.am 文件中,描述的很简单。在实际的项目中,文件关系很复杂,而且还有引用其他动态库、第三方动态库等关系。

    (2)虽然 makefile 是自动生成的,但是了解它的规则是非常重要的。makefile 涉及到的规则本文并未加以描述。

    有空的时候再写一篇blog来描述上述两个问题。

[1] http://book.chinaitlab.com/linux/777286.html

[2] http://blog.ossxp.com/2010/04/954/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息