织梦CMS - 轻松建站从此开始!

罗索

使用 automake

落鹤生 发布于 2010-04-07 19:24 点击:次 
使用 automake,只需要掌握一点点规则,定义一些变量,就能自动生成 Makefile。而这些 Makefile 有着统一的格式和结构,便于修改。下面就如何使用 automake 举出一个实际的例子。
TAG:

automake

    通常情况下,在写完自己代码后,使用 make 命令进行编译。make 命令其实什么也不做,知识读取一个叫 Makefile 的文件,从中获得 dependence and rule,然后调用 gcc 进行编译。但是 Makefile 比较复杂,变化技巧也比较多。对于一个大的工程项目来说,如果没有一个统一的风格,在工程延续的时候改动 Makefile 会很麻烦,也容易出错误。所以这时就有了使用 automake 的需求。使用 automake,只需要掌握一点点规则,定义一些变量,就能自动生成 Makefile。而这些 Makefile 有着统一的格式和结构,便于修改。下面就如何使用 automake 举出一个实际的例子。

2.1 使用 automake 的前提条件


    在使用 automake 前,请先确认在系统中安装了如下软件:

    GNU Automake

    GNU Autoconf

    GNU m4

    perl

    GNU Libtool(如果需要产生 shared library)如果没有的话,请在发行版中找相应的 rpm 包。

2.2 制作 configure 脚本

autoconf 是用来生成自动配置软件源代码脚本(configure)的工具。configure 脚本独立于 autoconf 运行,而且在运行的过程中,不需要用户的干预,通常不需要附带参数。它是用来检验软件必须的参数的。autoconf 从一个列举编译软件时所需要各种参数的模板文件中创建 configure。autoconf 需要 GNU m4 来生成该脚本。

由 autoconf 生成的脚本一般起名为 configure。当运行时,configure 创建了多个文件,并对这些文件中的配置参数赋予适当的值。由 configure 创建生成的文件有:

    1。一个或多个 Makefile,在软件源代码的每个目录中都生成一个 Makefile。

    2。还可选的生成 C 头文件——configurable,包含了各种 #define 声明。

    3。一个名为 config.status 的脚本,当运行时,重新生成上面的文件。

    4。一个名为 config.cache 的脚本,保存运行检测的结果。

    5。一个名为 config.log 的文件,保存有编译器生成的信息,用于调试 configure。

为了让 autoconf 生成 configure 脚本,需要以 configure.in 为参数调用 autoconf。如果要检测自己的各种参数,以作为对 autoconf 的补充,则需要写 aclocal.m4 和 acsite.m4 的文件。如果要使用 C 头文件,需要写 acconfig.h,并且将 autoconf 生成的 config.h.in 同软件一起发行。

your source files --> [autoscan*] --> [configure.scan] --> configure.in


configure.in --. .------> autoconf* -----> configure

                   +---+

[aclocal.m4] --+   `---.

[acsite.m4] ---'       |

                      +--> [autoheader*] -> [config.h.in]

[acconfig.h] ----.     |

                 +-----'

[config.h.top] --+

[config.h.bot] --'


Makefile.in -------------------------------> Makefile.in

Files used in configuring a software package:

                       .-------------> config.cache

configure* ------------+-------------> config.log

                       |

[config.h.in] -.       v            .-> [config.h] -.

               +--> config.status* -+               +--> make*

Makefile.in ---'                    `-> Makefile ---'


编辑 configure.in 文件:

configure.in 文件中包含了对 autoconf 宏的调用,这些宏是用来检测软件所必须的各项参数的。为了能够得到 configure.in 文件,需要使用 autoscan。configure.in 文件中,在进行各项检测前,必须在最开始调用 AC_INIT,在最后调用 AC_OUTPUT。另外有些宏由于检测的关系是和在文件中的位置相关的。最好每一个宏占用一行。


使用 autoscan 创建 configure.in 文件

可以将目录做为参数调用 autoscan,如果不使用参数的化,则认为是当前目录。autoscan 将检查指定目录中的源文件,并创建 configure.scan 文件。在将 configure.scan 改名为 configure.in 文件前,需要手工改动它以进行调整。


使用 autoconf 创建 configure 脚本

不带任何参数的运行 autoconf。autoconf 将使用 m4 宏处理器和 autoconf 宏,来处理处理 configure.in 中的宏。


configure.in 中的宏:

    AC_INIT(在源代码中唯一的一个文件):configure 将检查该文件是否存在,并检查包含它的目录是否存在。

    AC_OUTPUT(文件):指定创建的输出文件。在 configure.in 文件中调用一次。文件名间用空格分开。比如:AC_OUTPUT(Makefile:templates/top.mk lib/Makefile:templates/lib.mk)

在 configure.in 中,有一些被 autoconf 宏预先定义的变量,重要的有如下几个:

    bindir:安装可执行文件的目录。

    includedir:C 头文件目录。

    infodir:info 页安装目录。

    mandir:安装手册页的目录。

    sbindir:为管理员运行该该程序提供的安装路径。

    srcdir:为 Makefile 提供的源代码路径。

    top_srcdir:源代码的最上层目录。

    LIBS:给连接程序的 -l 选项

    LDFLAGS:给连接程序的 stripping(-s)和其他一些选项。

    DEFS:给 C 编译器的 -D 选项。

    CFLAGS:给 C 编译器的 debug 和优化选项。当调用了 AC_PROG_CC 才有效。

    CPPFLAGS:头文件搜索路径(-I)和给 C 预处理器和编译器的其他选项。

    CXXFLAGS:给 C++ 编译器的 debug 和优化选项。当调用了 AC_PROG_CXX 才有效。

如果在同一个目录下编译多个程序的话,使用 AC_CONFIG_SUBDIRS 宏,它的语法是:

    AC_CONFIG_SUBDIRS(DIR....):

其他重要的宏:

    AC_PROG_CC:选择 C 编译器。如果在环境中不设置 CC 的话,则检测 gcc。

    AC_PROG_CXX:选择 C++ 编译器。

参考文献:

    Autoconf.htm
2.3 使用 automake
一般操作

    Automake 工作时,读取一个叫'Makefile.am'的文件,并生成一个'Makefile.in'文件。Makefile.am中定义的宏和目标,会指导 automake生成指定的代码。例如,宏'bin_PROGRAMS'将导致编译和连接的目标被生成。

    Makefile.am中包含的目标和定义的宏被拷贝到生成的文件中去,这允许你添加任意代码到生成的Makefile.in文件中去。例如,使一个 Automake发布中包含一个非标准的dvs-dist目标,Automake的维护者用它来从它的源码控制系统制作一个发布。

    请注意,GNU生成的扩展名不被Automake所识别,在一个'Makefile.am'中使用这样一个扩展名会导致错误。

    Automake试图以一种聪明的方式将相邻的目标(或变量定义)注释重组。

    通常,Makefile.am中定义的目标会覆盖任何由automake自动生成的有相似名字的这样的目标。尽管这是种被支持的属性,但最好避免这么做,因为有些时候,生成的规则很严格。

    类似的,Makefile.am中定义的变量会覆盖任何由automake自动生成的变量定义。这一特性经常要比目标定义的覆盖能力更常用。请注意,很多 automake生成的变量只用于内部使用,在将来发布时他们的名字可能会变化。

    当测试一个变量定义时,Automake降递归的测试在定义中引用的变量。例如,如果Automake看到这段snippet程序中的 'foo_SOURCES':

    xs = a.c b.c

    foo_SOURCES = c.c $(xs)

    它将使用文件:'a.c','b.c'和'c.c' 作为foo_SOURCES的内容.

    Automake 也允许不被拷贝到输出的注释形式,所有以'##'开头的行将被Automake 完全忽略.


深度

    Automake 支持三种目录层次:'flat', 'shallow', 'deep'.

    flat: 所有的文件都在一个目录中. 相应的Makefile.am中缺少SUBDIRS宏. termutils 是一个例子.

    deep: 所有的资源都在子目录中,指定曾目录主要包含配置信息.GNU cpio 是一个很好的例子.GNU tar.相应的最顶层Makefile.am中将包含一个SUBDIR宏,但没有其他的宏来定义要创建的对象.

    shallow: 主资源存在于最顶层目录,而不同的部分(典型的,库函数)在子目录中.Automake 就是这样的一个包.


严格性

    当Automake 被GNU包维护者使用时,它的确努力去适应,但不要试图使用所有的GNU惯例.

    目前,Automake 支持三种严格性标准:

    foreign:Automake 将只检查绝对必须的东西.

    gnu:Automake 将尽可能多的检查以适应GNU标准, 这是默认项.

    gnits:Automake 将进行检查,以适应“尚未成文”的Gnits标准。 他们基于GNU标准,但更详尽。除非您是Gnits标准的制定者。建议您最好避免这个选项,指导该标准正式发布。


统一命名规范

    Automake变量一般遵循一套统一的命名规范以很容易的决定如何创建和安装程序(和其他派生对象)。给规范还支持configure时动态决定创建规则。

    在make时,一些变量被用于决定那些对象要被创建。写变量叫做primary variables。例如,PROGRAM变量包括一个要被编译和连接的程序列表。

    另一个变量集用于决定被创建变量被安装到哪里。这些变量以相应的主变量命名,但加一个前缀,表示那些标准目录应被用作安装路径。这些标准目录的名称规定在 GNU标准中。Automake用pkglibdir, pkgincludedir 和 pkgdatadir来展开这一列表。他们和没有pkg前缀的版本一样,只不过有‘@PACHAGE@’扩展,PKGLIBDIR被定义为 $(DATADIR)/@PACKAGE@.

    对每一个主变量,有一个EXTRA_前缀的变量。这个变量用于列出所有对象,至于哪些变量被创建,哪些变量不被创建则取决于configure。之所以需要这个变量,是因为Automake必须静态的指导要创建对象的完整列表以便生成一个‘Makefile。in’文件。

    例如,cpio 在configure时决定创建那些程序。一些程序被安装在bindir,一些被安装在sbindir:

    EXTRA_PROGRAMS = mt rmt

    bin_PROGRAMS = cpoi pax

    sbin_PRGRAMS = @PROGRAMS@

    定义没有前缀的主变量是错误的(如:PROGRAMS)。值得注意的是,“dir”在作为构成变量名时会被忽略。一次,我们写成bin_PROGRAMS 而不是bindir_PROGRAMS.

    不是每一种对象都得以安装在每个目录下。Automake 将标记那些他认为是错误的尝试,他也能够诊断一些明显的目录名拼写错误。

    有时标准目录--被Automake使用的--不过用。特别的,有时为了清晰,将对象安装在一些预定义的子目录,是很有用的。Automake允许你增加安装目录。如果以一个变量名(如,zar)加上dir的另一个变量(如,zardir)被定义了,那么他也是合法的。

    例如,如果HTML没支持Automake的一下部分,你就可以用他来安装HTML源文件:

    htmldir = $(prefix)/html

    html_DATA = automake.html

    “noinst”前缀专门指定有问题的对象不被安装。

    “check”前缀表示有问题的对象知道make check命令被执行猜被创建。

    可用的主变量是 'PROGRAMS','LIBRARIES','LISP','SCRIPTS','DATA','HEADERS','MANS'和 'TEXINFOS' 导出变量是如何命名的

    有时一个Makefile变量名有一些用户支持的文本导出。例如程序名被重写进Makefile宏名称。Automake读取这些文本,所以他不必遵循命名规则。当生成后引用时名称中的字符除了字母,数字,下划线夺回被转换为下划线。例如,如果你的程序里有sniff-glue,则导出变量名将会是 sniff_glue_SOURCES,而不是sniff-glue_SOURCES.


一些例子


一个完整简单的例子

    假设你写了一个名为zardoz的程序。

    第一步,更新你的configure.in文件以包含automake所需的命令。最简单的办法就是在AC_INIT后加一个 AM_INIT_AUTOMAKE调用:

    AM_INIT_AUTOMAKE(zardoz, 1.0)

    如果你的程序没有任何复杂的因素。这是最简单的办法。

    现在,你必须重建‘configure’文件。这样做,你必须告诉autoconf如何找到你所用的新宏。最简单的方式是使用aclocal程序来生成你的‘aclocal.m4’.aclocal让你将你的宏加进‘acincluide.m4’,所以你只需重命名并运行他


    mv aclocal.m4 acinclude.m4

    aclocal

    autoconf


    现在是为你的zardoz写Makefile.am的时候了。zardoz是一个用户程序,所以逆向将他安装在其他用户程序安装的目录。zardoz还有一些Texinfo文档。你的configure.in脚本使用AC_REPLACE_FUNCS,所以你需要链接‘@LIBOBJS@’

    bin_PROGRAMS = zardoz

    zardoz_SOURCES = main.c head.c float.c vortex9.c gun.c

    zardoz_LDADD = @LIBOBJS@


    info_TEXINFOS = zardoz.texi


    现在你可以运行Automake以生成你的Makefile.in文件。

一个经典的程序

    hello 以其简单和多面幸而闻名。着一段将显示在Hello包Automake如何被使用。

    下面是

    dnl用 autoconf 处理它以产生一个 configure 脚本.

    AC_INIT(src/hello.c)

    AM_INIT_AUTOMAKE(hello, 1.3.11)

    AM_CONFIG_HEADER(config.h)


    dnl Set of available languages

    ALL_LINGUAS="de fr es ko nl no pl pt sl sv"

    dnl Checks for programs.

    AC_PROG_CC

    AC_ISC_POSIX

    dnl Checks for libraries.

    dnl Checks for header files.

    AC_STDC_HEADERS

    AC_HAVE_HEADERS(string.h fcntl.h sys/file.h sys/param.h)

    dnl Checks for library functions.

    AC_FUNC_ALLOCA

    dnl Check for st_blksize in struct stat

    AC_ST_BLKSIZE

    dnl internationalization macros

    AM_GNU_GETTEXT

    AC_OUTPUT([Makefile doc/Makefile intl/Makefile po/Makefile.in \ src/Makefile tests/Makefile tests/hello], [chmod +x tests/hello])

    'AM_'宏由Automake(或Gettext 库)提供;其余的是Autoconf标准宏。

    top-level ‘Makefile.am’:

    EXTRA_DIST = BUGS ChangeLog.O

    SUBDIRS = doc intl po src tests

    --如你所见,这里所有的工作时在子目录中真正完成的.

    --'po' 和 'intl'目录是用 gettextize自动生成的,这里不做进一步讨论.

    在'doc/Makefile.am'文件中我们看到:

    info_TEXINFOS = hello.texi

    hello_TEXINFOS = gpl.texi

    --这已足以创建,安装和发布手册.


    这里是'tests/Makefile.am'文件:

    TESTS = hello

    EXTRA_DIST = hello.in testdata

    --脚本'hello'被configure创建,并且是唯一的测试.make check将运行它.

    最后是,'src/Makefile.am',所有的真正的工作是在这里完成的:

    bin_PROGRAMS = hello

    hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h

    hello_LDADD = @INTLLIBS@ @ALLOCA@

    localedir = $(datadir)/locale

    INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\"


创建一个'Makefile.in'文件

    要为一个包创建所有的'Makefile.in',在顶层目录运行automake不带参数的程序.automake将自动查找每个适当的 'Makefile.am'文件,并声称相应的'Makefile.in'文件.请注意,automake会简要的察看一下包的构成;它假定一个包在顶层只有一个'configure.in'文件.如果你的包有多个'configure.in'文件,那么你必须在每一个含有'configure.in'文件的目录运行一次'automake'程序.

    你可以随意送给automake一个参数;'.am'会加到变量名的后面,并且作为输入文件的文件名.这一特性通常被用来自动重建一个'过时的 ''Makefile.in'文件.注意,automake必须在最顶级的目录运行,及时仅仅为了重新生成某个子目录中的'Makefile.in'文件.

automake接受以下可选参数:

    -a

    --add-missing

    在某些特殊情况下,Automake需要某些公共文件存在.例如,如果'configure.in'运行 AC_CANONICAL_HOST时,就需要'config.guess'.Automake需要几个这样的文件,这一选项会让automake自动的将一些缺失文件加进包中(如果可能的话).一般的,如果Automake告诉你某个文件不存在,你可以试一试这个选项.

    --amdir = dir

    在dir所制定的目录而不是安装目录下寻找Automake的数据文件,经常用于调试.

    --build-dir = dir

    告诉Automake创建目录在哪里.这一选项只用于将'dependencies'加进一个由make dist生成的'Makefile.in'文件中.

    --cygnus

    将使得所生成的'Makefile.in'文件遵循Cygnus规则,而不是GNU或Gnits规则.

    --foreign

    设置全局严格性为'gnits'.

    --gnu

    设置全局严格性为'gnu'.

    --help

    帮助

    -i

    --include-deps

    将所有自动创建时的依赖信息包括在'Makefile.in'中.通常在制作发行时用到.

    --generate-deps

    创建一个'.dep_segment'文件,它合并了所有的自动生成时的依赖信息,通常用于制作发行.这在维护'SMakefile'或其他平台上的 'Makefile'(如Makefile.Dos)时非常有用.它只能与--include-deps, --srcdir-name和 --build-dir 联合使用.注意这一选项不作其他任何处理.

    --no-force

    一般的,automake创建在'configure.in'中提及的所有'Makefile.in'文件.这一选项将导致,automake只更新那些对于与自身相关的东西过了时的'Makefile.in'文件.

    -o dir

    --output-dir = dir

    将生成的'Makefile.in'放在指定的dir目录中.通常,'Makefile.in'放在与之相对应的'Makefile.am'所在目录中的.在制作发布时使用.

    --srcdir-name = dir

    告诉Automake与当前创建动作相关的源文件目录的名字.个选项仅被用于将自动创建时的依赖信息包括在'Makefile.in'中.

    -v

    --verbose

    时Automake打印出正在读取或创建的文件的信息.

    --version

    打印Automake的版本号.


扫描'configure.in'文件

    Automake扫描包的'configure.in'文件来决定某些关于包的信息.'configure.in'中必须定义一些变量并且需要一些 autoconf 宏.Automake也会利用'configure.in'文件的信息来定制它的输出.

    Automake还支持一些autoconf宏以使维护更为简单.


配置需求

    满足Automake基本要求的最简单方法是使用'AM_INIT_AUTOMAKE'宏.但如果你愿意,你可以手工来做.


自动生成 aclocale.m4

    Automake包括很多Autoconf宏,其中有些在某些情况下游Automake使用,这些宏必须被定义在你的'aclocal.m4'中.否则,autoconf将看不到他们.

    acloal程序将根据'configure.in'自动生成'aclocal.m4'.这提供了一个方便的途径来得到Automake提供的宏.


Automake所支持的Autoconf宏

    AM_CONFIG_HEADER

    AM_CYGWIN32

    AM_FUNC_STRTOD

    AM_FUNC_ERROR_AT_LINE

    AM_FUNC_MKTIME

    AM_FUNC_OBSTACK

    AM_C_PROTOTYPES

    AM_HEADER_TOCGWINSZ_NEEDS_SYS_IOCTL

    AM_INIT_AUTOMAKE

    AM_PATH_LISPDIR

    AM_PROG_CC_STDC

    AM_PROG_INTALL

    AM_PROG_LEX

    AM_SANITY_CHECK

    AM_SYS_POSIX_TERMIOS

    AM_TYPE_PTRDIFF_T

    AM_WITH_DMALLOC

    AM_WITH_REGEX


编写你自己的aclocal宏

    Aclocal并没有特定的宏机制,因此你可以用你自己的宏来扩展它.这以特性经常被用以制作做那些想让自己的Autoconf宏被其他应用程序使用的库.例如,gettext库支持一个AM_GNU_GETTEXT宏,它可以被任何使用gettext库的包所使用.当该库被安装后,它会安装这个宏,这样,aclocal就能够找到他了.

    宏的名称应以'.m4'结尾,这样的文件将被安装在'$(datadir)/aclocal'中.


最顶层'Makefile.am'

    在non-flat包中,顶层'Makefile.am'必须告诉Automake哪些子目录将被创建.这是通过SUBDIRS变量定义的.

    SUBDIRS宏包含一个子目录列表,以规定各种创建的过程.'Makefile'中很多目标(如,all)将不止运行所在目录中,还要运行于所有指定的子目录中.注意,在SUBDIRS中列出的目录并不需要包含'Makefile.am'文件而只需要'Makefile'文件.这将允许包含位于不使用 Automake的包(如,gettext)中的库.另外,SUBDIRS之中的目录必须是当前目录的直接子目录.比如,你不能在SUBDIRS中指定 'src/subdir'.

    在deep型的包中,顶层'Makefile.am'文件通常非常短.例如,下面是HELLO发布中的'Makefile.am':


    EXTRA_DIST = BUGS ChangeLog.O README-alpha

    SUBDIRS = doc intl po src tests


    如果你只想创建一个包的子集,你可以覆盖SUBDIRS(就如同GNU inetutils的情形)在你的'Makefile.am'中包括:

    SUBDIRS = @SUBDIRS@

    让后在你的'configure.in'中你可以指定:


    SUBDIRS = "src doc lib po"

    AC_SUBST(SUBDIRS)


    这样做的结果是automake被欺骗了,它会在指定目录创建包,但并不真正绑定那个列表直到运行configure.


    SUBDIRS可以包含配置的替代(如,'@DIRS@');Automake 自己并不真正检测这一变量的内容.

    如果 SUBDIRS 被定义了,那么你的'configure.in' 就必须包含AC_PROG_MAKE_SET.

    SUBDIRS 的使用并不局限于顶层'Makefile.am'.Automake 可被用来构造任意深度的包.


参考文献

    Automake.htm

(秩名)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201004/9026.html]
本文出处:网络博客 作者:秩名
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容