Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76271
  • 博文数量: 47
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-12 18:04
文章分类

全部博文(47)

文章存档

2010年(7)

2009年(40)

我的朋友

分类: LINUX

2009-03-13 18:37:22

创建automake项目 step by step

1. 创建好项目目录以及子目录

本文例子目录树结构:
  
  project
   |
   |-- Makefile.am [项目根目录 Makefile.am]
   |-- common[common子目录]
   |    |
   |     |---Makefile.am [项目子目录 Makefile.am]
   |     |
   |   |---test[test 子文件夹]
   |         |----Makefile.am [项目子目录测试子目录 Makefile.am]
   |
   |-- opt [opt子目录]
   |   |
   |   |---Makefile.am [项目子目录 Makefile.am]
   |   |
   |   |---test[test 子文件夹]
   |         |----Makefile.am [项目子目录测试子目录 Makefile.am]
   |
   |
   |-- exe [exe子目录]
      |
      |---Makefile.am [项目子目录 Makefile.am]
      |
      |---test[test 子文件夹]
            |----Makefile.am [项目子目录测试子目录 Makefile.am]
   


2. 进入项目根目录

执行流程图:

    a. autoscan-->"configure.scan"
    b. mv configure.scan [configure.in|configure.ac]
    c. vim [configure.in|configure.ac]
    d. vim Makefile.am [for each src dir]
    e. aclocal  -----|
    d. autoconf -----|-----> "configure"
    f. automake -a --------> "Makefile.in" [for each src dir]
    g. ./configure --arguments ----> Makefile [for each src dir]
    h. make
    i. make install
    f. make dist -----"xxxx.tar.gz"
   
2.1 编写configure.in
 
 整个configure.in[ac]文件的编写过程按以下步骤。

2.1.0 文件模板:

#步骤一: 项目初始化设置 project init set
AC_INIT(file)


#步骤五: 项目编译期检查 project compile checks
#checks for programs
#checks for libraries
#checks for header files
#checks for typedefs
#checks for structures
#checks for compiler characteristics
#checks for library functions
#checks for system services

#步骤二: 项目选项设置 project custom options set

#步骤三: 项目选项变量导出 options varies export to makefile

#步骤四: 项目文件输出设置 project outputs file set
AC_OUTPUT([file...])


2.1.1 步骤一: 项目初始化设置

2.1.1.1 初始化设置 必填项
 AC_INIT (package, version, [bug-report], [tarname])

2.1.1.2 项目文件验证, 选填项
 AC_CONFIG_SRCDIR (unique-file-in-source-dir)
 
2.1.1.3 automake支持 必填项
 AM_INIT_AUTOMAKE([OPTIONS])
 AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
 选一个宏进行定义

2.1.1.4 项目目录设置,选填项(强烈建议使用)
 AC_PREFIX_DEFAULT (prefix)
 设置项目默认安装路径,未定义情况下,目录是 /usr/local
 ex:
 AC_PREFIX_DEFAULT ([`pwd`])

2.1.1.5 NOTICE设置,选填项
 AC_PREREQ (version)
 AC_COPYRIGHT (copyright-notice)
 AC_REVISION (revision-info)
 
2.1.2 步骤二: 项目选项设置 project custom options set

2.1.2.1 项目安装外部包选项(很少使用)
 AC_ARG_WITH (package, help-string [, action-if-given [, action-if-not-given]])

2.1.2.2 项目安装自定义选项(肯定使用)
 AC_ARG_ENABLE (feature, help-string [, action-if-given [, action-if-not-given]])
 如果用户以选项`--enable-feature'或者`--disable-feature'调用 configure,就运行shell命令action-if-given。
 如果两个选项都没有给出,就运行shell命令 action-if-not-given。
 名称feature表示可选的用户级功能。
 它应该仅仅由字母、数字和破折号(dashes)组成。

 shell命令可以通过访问shell变量enableval来得到选项的参数,
 该变量的值实际上就是把shell变量 enable_feature的值中所有的`-'字符替换成`_'而得到的。
 如果你愿意,可以使用变量enable_feature。

ex:
 AC_ARG_ENABLE([ssl],
 [AC_HELP_STRING([--enable-ssl], [build for ssl support (default is yes)])],
 [if test "$enableval" = "yes"; then
  AC_DEFINE([_SSL_SUPPORT_], [1], [Define if --enable-ssl])
  MY_LDADD="-lACE_SSL"
 else
  MY_LDADD=""
 fi
 ],
 [AC_DEFINE([_SSL_SUPPORT_], [1], [Define if --enable-ssl])
 MY_LDADD="-lACE_SSL"
 ])
 
从例子可以看出:
 我们还需要几个简单的宏,帮我们将选项的一些值进行更进一步的处理
 
2.1.3 步骤三: 项目选项变量导出
  测试结果或者选项结果的处理宏
    
2.1.3.1 定义C预处理器符号
   在缺省状态下,AC_OUTPUT把由这些宏定义的符号放置到输出变量DEFS中,该变量为每个定义了的符号添加一个选项`-Dsymbol=value'。
   AC_DEFINE (variable [, value [, description]])
   AC_DEFINE_UNQUOTED (variable [, value [, description]])
 类似于AC_DEFINE,但还要对variable和value进行三种shell替换(每种替换只进行一次):
 变量扩展(`$'),命令替换(``'),以及反斜线传义符(`\')。
 值中的单引号和双引号没有特殊的意义。在variable或者value是一个shell变量的时候用本宏代替AC_DEFINE
  
2.1.3.2 设置输出变量
   记录测试结果的一种方式是设置输出变量,该变量是shell变量,它的值将被替换到configure输出的文件中。

  AC_SUBST (variable, [value])
  从一个shell变量创建一个输出变量。让AC_OUTPUT把变量variable替换到输出文件中(通常是一个或多个 `Makefile')。
  这意味着AC_OUTPUT将把输入文件中的实例替换成调用AC_OUTPUT时shell变量variable的值。
  variable的值不能包含新行。
  ex:
   AC_SUBST(LDADD, MY_LDADD)
   
  AC_SUBST_FILE (variable)
 另一种从shell变量创建输出变量的方式。
 让AC_OUTPUT把由shell变量variable给出的文件名的文件的内容(不进行替换)插入到输出文件中。
 这意味着AC_OUTPUT将在输出文件中(比如`Makefile.in')把输入文件中的实例
 替换为调用AC_OUTPUT时shell变量variable的值指明的文件的内容。
 如果没有文件可以插入,就把变量设置成`/dev/null'。
 
 ex:
 configure.ac文件:
  AC_SUBST_FILE([host_frag])
  host_frag=$srcdir/conf/sun4.mh
 Makefile.in文件:
  @host_frag@
 
2.1.4 步骤四: 项目文件输出设置 
  
AC_CONFIG_FILES
   配置输出文件
AC_CONFIG_HEADERS
   配置输出头文件
AC_CONFIG_COMMANDS
   配置输出命令
AC_CONFIG_LINKS
  配置输出链接
 
  以上四个宏的格式相同,如下:
  AC_CONFIG_FILES (file . . . , [cmds], [init-cmds])

项目输出文件定义:
ex: 
 AC_CONFIG_FILES([Makefile, src/Makefile])
 AC_OUTPUT
or
  AC_OUTPUT([Makefile, src/Makefile])  
 
   
2.2 编写Makefile.am
  
2.2.1 确定目录树结构
  
本文例子目录树结构:
  
  project
   |
   |-- Makefile.am [项目根目录 Makefile.am]
   |-- common[common子目录]
   |    |
   |     |---Makefile.am [项目子目录 Makefile.am]
   |     |
   |   |---test[test 子文件夹]
   |         |----Makefile.am [项目子目录测试子目录 Makefile.am]
   |
   |-- opt [opt子目录]
   |   |
   |   |---Makefile.am [项目子目录 Makefile.am]
   |   |
   |   |---test[test 子文件夹]
   |         |----Makefile.am [项目子目录测试子目录 Makefile.am]
   |
   |
   |-- exe [exe子目录]
      |
      |---Makefile.am [项目子目录 Makefile.am]
      |
      |---test[test 子文件夹]
            |----Makefile.am [项目子目录测试子目录 Makefile.am]
   
      
2.2.2 根目录Makefile.am编写
  
2.2.2.1 子目录递归
   项目文件下的Makefile.am主要定义需要递归执行的子目录,通过SUBDIRS进行定义
   SUBDIRS=common opt exe .
   编译按照SUBDIRS的顺序进行,make clean则按相反的顺序进行。
  
2.2.2.2 子目录的条件执行
   项目在编译的过程中,可能需要根据用户./configure 相关条件设置,设置有些目录不需要
   进行编译。  
  
例如:项目目录下opt目录作为一个可选项
      子目录下test目录同样是一个可选项

方法一:通过 AM_CONDITIONAL 宏定义变量
   
   configure.ac:
     AM_CONDITIONAL([COND_OPT],[test "$want_opt" = "yes"])
     AC_CONFIG_FILES([Makefile common/Makefile opt/Makefile exe/Makefile])
   
   项目目录Makefile.am:
     if COND_OPT
      MAYBE_OPT = opt
     endif
     SUBDIRS = common $(MAYBE_OPT) exe .
         
    注:
      定义SUBDIRS只是对 make all有效, 会根据用户的设置判断是否需要进行opt目录编译。
      如果使用 make dist 命令,则 所有子目录都会递归执行。
      
      Automake 会自动定义 DIST_SUBDIRS = common opt exe .
    
方法二:通过AC_SUBST宏定义输出变量
   
    configure.ac
   
     if test "$want_opt" = yes; then
      MAYBE_OPT=opt
    else
      MAYBE_OPT=
    fi
    AC_SUBST([MAYBE_OPT])    
    AC_CONFIG_FILES([Makefile common/Makefile opt/Makefile exe/Makefile])
   
   项目目录Makefile.am:
   SUBDIRS = common $(MAYBE_OPT) exe .
     
     
同理,对各子目录下test子目录,可以通过相似的办法设置,提示设置各子目录下的Makefile.am文件。   
   
2.2.2.3 根目录设置环境变量

有些变量是从Autoconf中继承而来的;它们是CC、 CFLAGS、CPPFLAGS、DEFS、 LDFLAGS和LIBS

还有一些附加的变量是Automake自行定义的:

INCLUDES
一个`-I'选项的列表。如果你需要包含特殊的目录,你可以在你的`Makefile.am'中设置它。 automake已经自动地提供了一些`-I'选项。特别地,它生成`-I$(srcdir)'和一个指向保存了 `config.h'的目录的`-I'选项(如果你已经使用了AC_CONFIG_HEADER或者AM_CONFIG_HEADER)。 除了`-I'以外,INCLUDES实际上还可以用于添加任何cpp选项。例如,有时用它把任意的`-D'选项传递给编译器。
COMPILE
实际用于编译C源文件的命令。文件名被添加到它的后面以形成完整的命令行。
LINK
实际用于连接C程序的命令。

可用的全局变量:
INCLUDES=
LDADD=
LDFLAGS=
EXTRA_DIST=

  
   
2.2.3 子目录Makefile.am编写

要求:本例子中,将common子目录文件编译成libcmm.a,
         将exe子目录文件编译成 project 执行文件

2.2.3.1 编译执行程序 (PROGRAMS)

步骤:
a. 定义程序名与程序源文件
  程序可以被安装在以下目录 bindir, sbindir, libexecdir, pkglibdir, noinst [这些均是目录变量名];
 
  根据自己的需要定义目录:
  如, 程序安装在 bin 目录下,则定义程序时 格式如下:
  bin_PROGRAMS=app1 app2 ...
 
b. 定义程序源文件
  根据具体定义的程序名,定义各程序的源文件,如下:
 
  app1_SOURCES= a.cpp b.cpp c.cpp ..
  app2_SOURCES= x.c y.c z.c
 
  如果Makefile.am中没有定义程序源文件, 系统按照默认 app_name.c 处理。

c. 定义程序需要的链接库
  使用全局变量 LDADD 添加链接库
  或者使用AM_LDFLAGS 变量设置链接库路径
  AM_CPPFLAGS变量设置 编译选项
 
  AM_LDFLAGS = -L.
  AM_CPPFLAGS = -DINSTALL_DIR=\"$(prefix)\" -I.
  AM_CXXFLAGS = -Wall
  LDADD = -lACE -lcmm
 
--------------------------------------------------- 
[exe 子目录Makefile.am]

AM_LDFLAGS =  -L../commom
AM_CPPFLAGS = -DINSTALL_DIR=\"$(prefix)\" -I../common
AM_CXXFLAGS = -Wall
#LDADD= -lACE from configure.ac
LDADD += -lcmm

bin_PROGRAMS = app
app_SOURCES=main.cpp
----------------------------------------------------

 
2.2.3.2 编译静态函数库

-----------------------------------------------------
[common 子目录Makefile.am]

SUBDIRS= . $(DIR_TEST)

AM_CPPFLAGS = -DINSTALL_DIR=\"$(prefix)\" -I.
AM_CXXFLAGS = -Wall

noinst_LIBRARIES = libcmm.a
libcmm_a_SOURCES=foo.cpp

------------------------------------------------------

------------------------------------------------------
[common 子目录 test 子目录 Makefile.am]

AM_LDFLAGS =  -L../
AM_CPPFLAGS = -DINSTALL_DIR=\"$(prefix)\" -I../
AM_CXXFLAGS = -Wall
#LDADD= -lACE from configure.ac
LDADD += -lcmm

bin_PROGRAMS = test
test_SOURCES=test_cmm.cpp
------------------------------------------------------

2.2.3.2 编译共享库

3. 自定义autoconf宏
 
[待续]

阅读(538) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~