像我儿子一样永远保持好奇和梦想

[z][Q006][make]Makefile自动生成

上一篇 / 下一篇  2012-10-24 15:29:49 / 个人分类:practic_linux

  

Makefile自动生成  

2008-09-19 14:25:31|  分类: C编程技术|字号 订阅

_!X(d?A1a2U0
编写 make 规则: 
使用 gcc 的时候,用 -M 开关,它会为每一个你给它的C文件输出一个规则,把目标文件 做为目的,而这个C文件和所有应该被 #include 的 header 文 件将做为依靠文件。注意这个规则会加入所有 header 文件,包 括被角括号(`<', `>')和双引号(`"')所包围的文件。其实系统 header 档(比如 stdio.h, stdlib.h 等等一般不会被我们更改,如果用 -MM 来代替 -M 传递给 gcc,那些用角括号包围的 header 档将不会被包括。
$@ 扩展成当前规则的目的文件名, $< 扩展成依靠列表中的第 一个依靠文件,而 $^ 扩展成整个依靠的列表。

自动生成Makefile文件的操作:

Makefile自动生成 - ck - 不想孤独的猪ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台4[9i5mx}]0A


1、首先,新建一个测试项目的目录——hello:mkdir hello
然后,cd hello;编辑一个hello.c的代码文件:
#include <stdio.h>
int main()
{
     printf("hello automake!\n");
}
保存退出;

2、执行autoscan命令,在当前路径中生成了autoscan.log  configure.scan两个新文件。其中configure.scan文件的内容如下:
AC_PREREQ(2.57)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([test.c])
AC_CONFIG_HEADER([config.h])
AC_PROG_CC
AC_OUTPUT

3、重命名configure.scan  为configure.in,编辑它的内容,修改后的内容为:
AC_PREREQ(2.57)
AC_INIT(hello)
AC_CONFIG_SRCDIR([hello.c])
#AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE(hello, 1.0)
AC_PROG_CC
AC_OUTPUT([Makefile])

说明:Autoconf 是用来产生 'configure'文件的工具。'configure' 是一个 shell script,它可以自动设定符合各种不同平台上Unix 系统的特性,并且根据系统参数及环境产生合适的Makefile文件或C 的头文件(header file),让原始程式可以很方便地在不同的平台上进行编译。Autoconf会读取 configure.in 文件然后产生'configure' 这个 shell script。configure.in 文件内容是一系列GNU m4 的宏,这些宏经autoconf处理后会变成检查系统特性的shell scripts。 configure.in 内宏的顺序并没有特别的规定,但是每一个configure.in 文件必須在所有宏前加入 AC_INIT 宏,然后在所有宏的最后加上 AC_OUTPUT宏。可先用 autoscan 扫描原始文件以产生一个 configure.scan 文件,再对 configure.scan 做些修改成 configure.in 文件。
AC_INIT(FILE) 
该宏用来检查源代码所在路径,autoscan 会自动产生,一般无须修改它。
AM_INIT_AUTOMAKE(PACKAGE,VERSION) 
这个是使用 Automake 所必备的宏,PACKAGE 是所要产生软件套件的名称,VERSION 是版本编号。 
AC_PROG_CC 
检查系统可用的C编译器,若源代码是用C写的就需要这个宏。
AC_OUTPUT(FILE) 
设置 configure 所要产生的文件,若是Makefile ,configure 便会把它检查出来的结果带入 Makefile.in 文件后产生合适的 Makefile。 

4、执行aclocal命令,生成了aclocal.m4文件,一般无需修改这个文件。
5、新建Makefile.am文件,编辑内容如下:
            bin_PROGRAMS=test   
            test_SOURCES=test.c
说明:
Automake 会根据 configure.in 中的宏把Makefile.am 转成 Makefile.in 文件。 Makefile.am 文件定义所要产生的目标: 
AUTOMAKE_OPTIONS
设置 automake 的选项。Automake 主要是帮助开发 GNU 软件的人员来维护软件,所以在执行 automake 时,会检查目录下是否存在标准 GNU 软件中应具备的文件,例如 'NEWS'、'AUTHOR'、'ChangeLog' 等文件。设置 foreign 时,automake 会改用一般软件的标准来检查。 
bin_PROGRAMS 
定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空白符隔开
hello_SOURCES 
定义 'hello' 这个执行程序所需要的原始文件。如果 'hello'这个程序是由多个原始文件所产生,必須把它所用到的所有原始文件都列出来,以空白符隔开。假设 'hello' 还需要 'hello.c'、'main.c'、'hello.h' 三个文件的话,则定义 
hello_SOURCES= hello.c main.c hello.h 
如果定义多个执行文件,则对每个执行程序都要定义相对的filename_SOURCES

6、 执行autoconf命令,生成autom4te.cache和configure文件;
7、执行automake -a命令,生成depcomp  ,install-sh,mkinstalldirs,COPYING,INSTALL, missing文件;
说明:
编辑好 Makefile.am 文件,就可以用 automake --add-missing来产生 Makefile.in。加上 --add-missing 选项来告诉 automake顺便假如包装一个软件所必须的文件。Automake产生生出來的 Makefile.in 文件是完全符合 GNU Makefile 的惯例,只要执行 configure这个shell script. 便可以产生合适的 Makefile 文件了。 
在执行automake -a命令时可能会出现以下信息:
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
这些对结果影响不大,如果不想产生这些让人误解的信息,可以手动建立这些文件:
>NEWS   
>README   
>AUTHORS   
>ChangeLog   

8、执行./configure,生成了Makefile文件
9、执行make,生成目标文件。

实战Makefile.am

L&pk x.FN0

Makefile.am是一种比Makefile更高层次的规则。只需指定要生成什么目标,它由什么源文件生成,要安装到什么目录等构成。ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台;sP X |N

表一列出了可执行文件、静态库、头文件和数据文件,四种书写Makefile.am文件个一般格式。

:D/Y'@E3Mi%X"}0
表 1Makefile.am一般格式
表 1Makefile.am一般格式 

对于可执行文件和静态库类型,如果只想编译,不想安装到系统中,可以用noinst_PROGRAMS代替bin_PROGRAMS,noinst_LIBRARIES代替lib_LIBRARIES。

N:NS6v+FKx5yIA0

Makefile.am还提供了一些全局变量供所有的目标体使用:ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台h@&gI!M?ZRe/nl.e1M


表 2 Makefile.am中可用的全局变量
表 2 Makefile.am中可用的全局变量 

在Makefile.am中尽量使用相对路径,系统预定义了两个基本路径:

#jZhA m#YB0
表 3Makefile.am中可用的路径变量
表 3Makefile.am中可用的路径变量 

在上文中我们提到过安装路径,automake设置了默认的安装路径:ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台Pm"`eAz

1) 标准安装路径

?ky| ND6Q6d1C0

默认安装路径为:$(prefix) = /usr/local,可以通过./configure --prefix=<new_path>的方法来覆盖。

#GLC9d4|5`9i6s0dIao0

其它的预定义目录还包括:bindir = $(prefix)/bin, libdir = $(prefix)/lib, datadir = $(prefix)/share, sysconfdir = $(prefix)/etc等等。ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台e5ji s9b;pSO_3@N

2) 定义一个新的安装路径

2SD;Ms){ h0

比如test, 可定义testdir = $(prefix)/test, 然后test_DATA =test1 test2,则test1,test2会作为数据文件安装到$(prefix)/ /test目录下。

(r/qi5G?\2n0

我们首先需要在工程顶层目录下(即project/)创建一个Makefile.am来指明包含的子目录:ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台5E+I#H]'tRE$v+`2qt`e


SUBDIRS=src/lib src/ModuleA/apple/shell src/ModuleA/apple/core 
CURRENTPATH=$(shell /bin/pwd)
INCLUDES=-I$(CURRENTPATH)/src/include -I$(CURRENTPATH)/src/ModuleA/apple/include
export INCLUDES

由于每个源文件都会用到相同的头文件,所以我们在最顶层的Makefile.am中包含了编译源文件时所用到的头文件,并导出,见蓝色部分代码。ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台7Nq'Sh%G*L

我们将lib目录下的swap.c文件编译成libswap.a文件,被apple/shell/apple.c文件调用,那么lib目录下的Makefile.am如下所示:ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台mOZ$MTmK


noinst_LIBRARIES=libswap.a
libswap_a_SOURCES=swap.c
INCLUDES=-I$(top_srcdir)/src/includ

细心的读者可能就会问:怎么表1中给出的是bin_LIBRARIES,而这里是noinst_LIBRARIES?这是因为如果只想编译,而不想 安装到系统中,就用noinst_LIBRARIES代替bin_LIBRARIES,对于可执行文件就用noinst_PROGRAMS代替 bin_PROGRAMS。对于安装的情况,库将会安装到$(prefix)/lib目录下,可执行文件将会安装到${prefix}/bin。如果想安 装该库,则Makefile.am示例如下:ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台y&BvH9wq`R1W/Y


bin_LIBRARIES=libswap.a
libswap_a_SOURCES=swap.c
INCLUDES=-I$(top_srcdir)/src/include
swapincludedir=$(includedir)/swap
swapinclude_HEADERS=$(top_srcdir)/src/include/swap.h

最后两行的意思是将swap.h安装到${prefix}/include /swap目录下。ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台9P}5n:s't7LqTLZ5q

接下来,对于可执行文件类型的情况,我们将讨论如何写Makefile.am?对于编译apple/core目录下的文件,我们写成的Makefile.am如下所示:ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台+u,T.?h}M"P


noinst_PROGRAMS=test
test_SOURCES=test.c
test_LDADD=$(top_srcdir)/src/ModuleA/apple/shell/apple.o $(top_srcdir)/src/lib/libswap.a
test_LDFLAGS=-D_GNU_SOURCE
DEFS+=-D_GNU_SOURCE
#LIBS=-lpthread

由于我们的test.c文件在链接时,需要apple.o和 libswap.a文件,所以我们需要在test_LDADD中包含这两个文件。对于Linux下的信号量/读写锁文件进行编译,需要在编译选项中指明 -D_GNU_SOURCE。所以在test_LDFLAGS中指明。而test_LDFLAGS只是链接时的选项,编译时同样需要指明该选项,所以需要 DEFS来指明编译选项,由于DEFS已经有初始值,所以这里用+=的形式指明。从这里可以看出,Makefile.am中的语法与Makefile的语 法一致,也可以采用条件表达式。如果你的程序还包含其他的库,除了用AC_CHECK_LIB宏来指明外,还可以用LIBS来指明。ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台+pM(?J'V{

如果你只想编译某一个文件,那么Makefile.am如何写呢?这个文件也很简单,写法跟可执行文件的差不多,如下例所示:ET创芯网(EETOP)-电子设计威尼斯人网址、博客、超人气的电子工程师资料分享平台8nISssb4C L

noinst_PROGRAMS=apple
apple_SOURCES=apple.c
DEFS+=-D_GNU_SOURCE

ref:
blog/html/58/201358-17114.html
http://andychenkan.blog.163.com/blog/static/56300913200881922531784/

TAG: autoscan makefile Makefile

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar
博聚网