automake主要通过编辑Makefile.am来控制它的行为,下面就常用的三个Makefile.am配置做出说明。

1.1. autotools的工作原理

autotools最终是为了生成Makefile,为此,需要使用到autotools系列工具的如下几个命令:

l autoscan

l aclocal

l autoheader

l autoconf

l automake

另外,还需要有两类输入文件:configure.in和Makefile.am。其中,configure.in是用来生成configure脚本的,configure脚本的作用主要有两个:检测系统的环境,生成Makefile。而Makefile.am则是生成Makefile的参数,它们之间是一一对应的。一般来说,在一个工程中每个目录下都会有一个Makefile来管理当前目录下的文件。所以,基本上每个目录中都需要编写一个Makefile.am,来描述当前目录下生成的Makefile的行为。

有了生成工具和输入文件,下面来看一下生成Makefile的流程,如下图所示:

需要说明的是autoscan工具的使用,autoscan检测当前目录下的所有文件,生成一个configure.scan,这个文件可以作为configure.in文件的雏形,在它的基础上稍做修改就可以作为configure.in文件来使用。所以,autoscan工具只需要在工程创建时运行一次即可。

下面就来具体介绍两个输入文件的编写规则:

1.2. 编写Makefile.am

1.2.1. Makefile.am规则

Makefile.am写起来相对简单,有共有5类规则,如下表

表1.2.1 Makefile.am中的规则

文件类型

书写格式

可执行文件

bin_PROGRAMS = foo

foo_SOURCES = xxx.c xxxx.c

foo_LDADD =

foo_LDFLAGS =

foo_DEPENDENCIES =

静态库

lib_LIBRARIES = foo.a

foo_a_SOURCES = xxx.c xxxx.c

foo_a_LDADD =

foo_a_LIBADD =

foo_a_LDFLAGS =

动态库

lib_LTLIBRARIES = foo.la

foo_la_SOURCES = xxx.c xxxx.c

foo_la_LDADD =

foo_la_LIBADD =

foo_la_LDFLAGS =

头文件

include_HEADERS = foo.h

noinst_HEADERS = foo2.h

数据文件

data_DATA = data1 data2

其中,生成动态库的同时还会自动生成一个静态库,所以在一般情况下都不直接使用静态库规则。

Makefile.am中还有一些可以直接使用的全局变量,表示所有目标所共享的一些属性,见下表:

表1.2.2 Makefile.am中的变量

变量

含义

INCLUDES

编译时所需头文件

LDADD

链接时所需链接的库文件

LDFLAGS

链接时的选项

AM_CXXFLAGS

编译.cpp文件时的选项

AM_CFLAGS

编译.c文件时的选项

EXTRA_DIST

除源代码和一些默认的文件以外,其它需要打如发布包.tar.gz中的文件

SUBDIRS

在处理本目录之前要递归处理的子目录

top_srcdir

工程源码的最顶层目录

top_builddir

工程目标文件的最顶层目录

有了以上的规则和变量,我们可以完成最基本的Makefile.am编写,但在某些情况下,我们需要定义一些变量来控制工程中某些目标的生成:比如库的版本号是不断变化的,需要定义一个变量来指代。Makefile.am可以使用宏替换来实现这种功能,可以通过以下方式来引用一个宏:

@宏名@

这个宏的的定义是在configure.in中的,在1.3.节中会介绍它的定义方法。

现在Makefile.am中所需要了解的规则和语法已经介绍完了,下面介绍一下如何使用这些规则来具体生成一个库和可执行程序。

1.2.2. 库的生成

要生成一个库,需要在Makefile.am中加入一套动态库规则(见表1.2.1),如现在要用hello1.cpp和hello2.cpp两个源文件生成动态库libhello.so,库的版本为1.0.10,库需要额外连接一个叫做libworld.so的库,我们可以这样写:

lib_LTLIBRARIES = hello.la

hello_la_SOURCES = hello1.cpp hello2.cpp

hello_la_LIBADD = -lworld

hello_la_LDFLAGS = -version-info 1.0.10

可以看到,在LIBADD规则中链接库文件的方法与使用g++编译时的相同。但LDFLAGS规则中的属性就没有见过了。实际上,这个参数是传给libtool生成库时使用的,除了-version-info这个参数之外,LDFLAGS编译库时还会经常使用下面两个参数:

l -avoid-version 生成不带版本号的库

l -all-static 生成为静态库

1.2.3. 可执行文件的生成

要生成一个可执行文件,需要加入一套可执行文件的规则(见表1.2.1),与生成动态库的规则很类似。下面我们要使用源文件main.cpp生成可执行文件main,该可执行文件需要链接上面生成的库libhello.so,我们可以这样写:

bin_PROGRAMS = main

main_ SOURCES = main.cpp

main_ LDADD = -lhello

main_LDFLAGS = -I./include

1.3. 编写configure.in文件

Makefile.am相比,configure.in文件写起来更复杂,因为configure.in文件中可以使用的资源要远多与Makefile.am。但通常情况下,我们都可以借助autoscan工具帮助我们生成一个configure.in的模版,在此基础上再完善就可以了。所以,实际上我们只需要在configure.in中修改以下两个参数就可以了:

AC_INIT(package_name, package_version, owner_email)

AC_CONFIG_FILES([makefile1_path

makefile2_path])

AC_INIT()选项中指明了工程的名字,当前工程的版本号,工程所有者的邮箱。

AC_CONFIG_FILES()中指明了所有要生成的Makefile的相对路径,由于每个Makefile都需要一个Makefile.am作参数,所以该选项中Makefile的数量和路径应与当前工程中Makefile.am的状态一致。

在经过上面的修改之后,一个configure.in文件就基本可以使用了,但通常情况下,我们需要对它进行更多的配置。

1.3.1. 在configure.in中定义外部变量

在configure.in中定义变量与写shell脚本时定义变量的语法相同,如我们要定义一个值为nihao的变量hello,我们可以这样写:

hello=nihao

但使用这个变量的方法就有些不同了,比如我们要将hello这个变量赋给hi这个变量,我们可以这样写:

hi=”$hello”

如果这个变量需要被外部引用的话(如在1.2.1节中提到的Makefile.am引用configure.in中定义的变量),需要一个额外的选项来完成,如我们要将hello定义为外部变量,可以写成:

AC_SUBST(hello)

而Makefile.am中也就可以通过对它的引用来完成对某些可变因子的替换,在Makefile.am中的引用方法见1.2.1节。

1.3.2. 给configure配置自定义参数

对于一个已经生成好的configure,执行./configure --help命令可以看到该脚本所支持的所有参数,其中大部分是其自带的。同样,我们可以通过对configure.in的配置来给它添加新的参数。可以配置的参数种类有很多种,常用的有以下2种格式:

--enable-xxx 和 --disable-xxx

--with-xxx 和 --with-out-xxx

可以分别通过以下2个宏来定义这两个参数:

AC_ENABLE (feature, action-if-given, [action-if-not-given])

AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])

这两种格式基本上可以互换,下面就以AC_ARG_WITH()为例,说明如何给configure加上一个自定义参数。

假设我们要增加一个选项表示是否需要编译一个名为agent的模块,可以这样写:

BUILD_AGENT=no

AC_ARG_WITH([agent],

[AS_HELP_STRING([--with-agent],

[build agent(default is no)])],

[BUILD_AGENT=yes],

[BUILD_AGENT=no])

if test "x$BUILD_AGENT" = "xyes";then#判断是否加上了该参数

#做出相应动作

fi

这样,./configure就新添了两个选项--with-agent和--with-out-agent,通过这两个选项可以控制变量BUILD_AGENT的值,然后做出相应的动作。

使用autoconf与automake自动生成MakeFile文件的更多相关文章

  1. linux下使用automake工具自动生成makefile文件

    linux环境下,当项目工程很大的时候,编译的过程很复杂,所以需要使用make工具,自动进行编译安装,但是手写makefile文件比较复杂,所幸在GNU的计划中,设计出了一种叫做Autoconf/Au ...

  2. 使用automake等命令自动生成Makefile文件 (转载)

    使用automake等命令自动生成Makefile文件   Linux下编程时,为了方便编译,往往使用Makefile文件自动完成编译,但是Makefile文件本身的书写十分复杂,规则很多.好在Lin ...

  3. 一个简单的执行程序的GNU automake自动生成Makefile的方法及案例

    一个简单的执行程序的GNU automake自动生成Makefile的方法及案例 在GNU的世界里,存在Automake这样的工具进行自动生成Makefile文件,automake是由Perl语言编写 ...

  4. 自动生成Makefile文件

    主要的工具有autoscan, aclocal, autoheader, autoconfig,automake 1 .创建c源文件hello.c #include <stdio.h> i ...

  5. qmake使用方法(自动生成Makefile文件)

    qmake的使用简介 下面是qmake的简单介绍和使用要领,更为详细的信息请参阅手册 qmake的介绍 手写Makefile是比较困难并且容易出错的,尤其是需要给不同的平台和编译器组合写几个Makef ...

  6. 使用automake等命令自动生成Makefile文件

    参考:http://www.cnblogs.com/njucslzh/archive/2010/04/29/1723320.html

  7. 利用 autoconf 和 automake 生成 Makefile 文件

    一.相关概念的介绍 什么是 Makefile?怎么书写 Makefile?竟然有工具可以自动生成 Makefile?怎么生成啊?开始的时候,我有这么多疑问,所以,必须得先把基本的概念搞个清楚. 1.M ...

  8. 例解 autoconf 和 automake 生成 Makefile 文件

    本文介绍了在 linux 系统中,通过 Gnu autoconf 和 automake 生成 Makefile 的方法.主要探讨了生成 Makefile 的来龙去脉及其机理,接着详细介绍了配置 Con ...

  9. 使用autoconf和automake生成Makefile文件(转)

    Makefile好难写 曾经也总结了一篇关于Makefile的文章<make和makefile的简单学习>.但是,总结完以后,发现写Makefile真的是一件非常痛苦的事情,的确非常痛苦. ...

随机推荐

  1. 解决在html中引入font-awesome的css文件后, 图标显示不出来

    今天小颖在做项目时,需要在html文件中引入font-awesome.min.css,但是引入后: 以前小颖在用font-awesome库里的图标时,都是直接从node中下包,然后在main.js中引 ...

  2. 利用selenroid扩展uiautoamtor的webview解析能力

    uiautomator是一个非侵入式框架,但是webview解析能力很弱.为了改进webview的支持,可以考虑把webdriver或者selenroid整合进来. 具体接入可参考:http://se ...

  3. 微信小游戏的本地缓存和清除的使用 (text.js image.js file-util.js)

    参考: 微信小游戏,文件系统 UpdateManager-小游戏 一.Egret提供的本地缓存工具类( 备注:新版本进行了修改,并增加了sound.js等) 在微信小游戏项目中,Egret提供了fil ...

  4. 6.13 py网络编程

    tcp的十种状态 python使用原始套接字才可以做黑客攻击!!!!!伪造数据包!!!!!直接越过底层!socket这个东西是经过linux过滤过得! TTL  每经过一个路由器就减1 谁先调clos ...

  5. js监听指定元素的css动画属性

    MDN 监听css动画,开始,迭代次数,结束,中断 回调函数返回 animationEvent属性 <!DOCTYPE html> <html> <head> &l ...

  6. day5 五、数字类型、字符串,列表类型的基本操作和内置方法

    一.可变与不可变 可变:值改变,但是id不变,证明就是在改变原值,是可变类型.它的原理是在内存里有一个值,然后这个值发生了改变,意为id地址是同一个,没有变化 # l=['a','b'] # prin ...

  7. 无法在Web服务器上启动调试。

    Ⅰ x 操作超时 有关详细信息,请单击"帮助" x IIS--应用程序池--找到用到的程序池--回收   2 报这个错误的时候,我的IIS应用程序池只有一个>>> ...

  8. 更新快排中的partition

    这一次是将partition 过程中, 维护三个区域. <x   =x  >x  三区域. 还有个待定的区域. /* * 将数组划分为三个分区, 小于arr[R], 等于arr[R], 大 ...

  9. 一个按成绩排序SQL的写法问题

    测试数据: SQL> select * from sscore; NAME       SCORE ---------- ----- aa            99 bb            ...

  10. 查找->动态查找表->键树(无代码)

    文字描述 键树定义 键树又叫数字查找树,它是一棵度大于或等于2的树,树中的每个结点中不是包含一个或几个关键字,而是只含有组成关键字的符号.例如,若关键字是数值,则结点中只包含一个数位:若关键字是单词, ...