没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
make 工具及 makele 规则
14.1 概 述
设计make 程序起初是为了避免不必要的重复编译。使用make 不仅可以在一个工程的开发阶段避
免对同样命令的多次键入,而且对维护程序文件也十分有用,尤其对于依赖关系,make 可以非常有效地
维护任何有相互依赖性的多个文件集合。它可以用来维护C、C++或HTML 源代码,对于有依赖关系的
文件集都可以起到一定的维护能力。它提供了编写文件依赖性的一个规则,和对已经改变了的文件执行什
么命令来维护或编译。它提供了维护文件的一个强大的、非过程的和基于模板的方法,用户只需告诉
make 要做什么并提供一些规则,然后由make来做剩下的工作。这里介绍make 的常规用法和目的,即
使用make 和makele 来维护我们开发过程中的文件集合。
使用make 来维护.o 文件和可执行文件,有利于一致地编译程序。尤其在工程开发中,对源代码没
有变化的模块,无需再次编译它。在工程开发中也可以与SCCS、RCS 或CVS 等版本控制工具(有关版本
控制见下一章)结合使用,使得开发过程更符合软件工程中各个阶段的要求,也更容易维护。
14.2 make 和makele 的关系
如果用户编译过一些GNU 的程序,应该使用过make。因为GNU 的软件是开放源代码的,一般提
供较为通用的或不同平台的makele 文件,现在也有人使用其他软件来自动生成针对所用平台的
makele 文件。
当调用make 时,它在当前的目录下搜索文件名是“makeke”或“Makele”的文件,一些UNIX 版
本也搜索别的文件,一般是搜索s.makele、SCCS/s.makele或SCCS/s.Makele。如果不想使用上
述缺省文件,可以使用使用命令行中的“-f”选项来指定文件,本章后面的make 命令行选项将具体介绍。
14.3 makele 规则
makele 是一个make 的规则描述脚本。它描述能生成什么文件集并怎样生成,它允许有四种类型
行:目标行、命令行、宏定义行和make 伪指令行(如“incldude”)。makele 文件中注释以“#”开头。
当一行写不下时,可以用“\”字符转入下一行。下面分别介绍这四种类型。
14.3.1 目标行
目标行告诉make 建立什么。它由一个目标名表后面跟冒号“:”,再跟一个依赖性表组成。目标名表
可以包含多个目标的名字,一般情况下只列出一个目标名。目标名表不能为空。依赖性表,指出目标和哪
些其他文件或目标具有依赖关系。依赖性表可以为空。下面是目标行的一个例子:
example: deple deptarget
该目标行指出目标example 与deple 和deptarget 有依赖关系,如果deple 和deptarget 之一
修改,则应该重新生成目标。
examp1 examp2 examp3: deptarget1 deptarget2 deple
该目标行指出目标名表中的examp1、examp2、examp3 这三个各自独立的目标是用相同的依赖
列表和规则生成的。
clean:
空的依赖列表说明目标clean 没有其他依赖关系。
make 执行时,按依赖深度优先顺序扫描处理遇到的目标。即当前目标的依赖表中有其他目标名,
则立刻去扫描该目标,直到当前目标依赖表中的目标都扫描过后,才确定当前目标是否需要重新生成。如
果有比当前目标更新的依赖目标,或依赖的目标不存在,则必须生成相关目标。注意依赖表为空,则总是
生成目标。
如果目标依赖的文件或目标名比当前目标旧,则不生成目标。目标行后续的以Tab开始的行是指出
目标生成规则。该Tab 字符不能以空格代替。例如:
example.o: example.c example.h
cc -c example.c
该例子指出目标example.o 依赖于example.c 和example.h。如果example.c 或example.h 其
中之一改变了,就需要重新生成目标example.o,如果要重新生成目标,则要执行命令
cc -c example.c
如果example.c 和example.h 都没有改动,则不生成目标。可以用文件名模式匹配来自动地为目
标生成依赖表,可以使用shell 通配符“*”、问号“?”和中括号“[]”。例如makele 所在的目录下,所有以.
c 结尾的文件:
tjb:~# ls
main.c check.c treatment.c
则make 下面二个目标的效果是等同的:
prog: main.c check.c treatment.c
prog: *.c
一般地,包含依赖元素的列表用于构造一个目标。如依赖性表可用来组成一个目标文件。目标文件
能构成可执行文件:
Program:Part.o component.o module.o
或目标依赖的头文件和源文件:
module.o: module.cc module.hh part.hh
下面看一个简单的makele 的例子
all: hello hello1
hello: hello.o
cc -o hello -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello.o
hello1: hello1.o
cc -o hello1 -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello1.o
hello.o: hello.c
cc -c hello.c
hello1.o: hello1.c
cc -c hello1.c
clean:
rm *.o hello hello1
make 使用makele 文件时,从第一个目标开始扫描,从这个例子中我们看到,make 程序将先
看目标all 的依赖关系表,查看依赖表中的依赖目标是否比目标新,如果目标存在并且不是旧的,则不生
成新的目标。如果目标不存在则生成新的目标。这里因为没有all 文件,所以查看依赖表。首先扫描
hello,如果目标hello 也不存在,则查看hello 的依赖表。hello 依赖hello.o,这里假设hello.o 也不存
在或比目标新,那么再扫描hello.o 目标,而hello.o 目标依赖hello.c 文件,如果hello.c文件自上次
make 以来没有改动则hello.o 不需要改动,这时,返回去,由cc -o hello-L/usr/X11R6/lib -L/usr/lib
-lXm -lXt -lX11 hello.o 生成目标hello,然后返回all 目标再看依赖目标hello1。如果hello.c 修改过则
由命令cc -c hello.c 来生成目标hello.o。这里的例子,没有使用隐含规则。在执行make 时,make 总
是从第一个目标开始。所以目标clean 不会自动被执行。可以用命令行make clean 来生成目标,因为目
标的依赖表为空,所以make clean,总是要求生成目标。而生成目标的命令是rm *.o hello hello1 所
以生成目标就是删除了hello.o、hello1.o、hello、hello1四个文件。这里要注意的是,生成目标的命令
由一行第一个为Tab 字符的行指出生成的方法。例如,目标hello.o 的生成方法是cc –c hello.c。下面我
们来看看各种不同的目标。
库目标
库目标是目标的一个特殊类型,用特别的方法支持库目标。因为库中含有不同的模块,提供一系列
的函数,所以库目标要考虑到库中单独模块的地址。当一个目标或依赖表中目标含有括号“()”,则被认为
是一个库目标。例如:
libmy.a(myfun.o): myfun.c myfun.h
则表示myfun.o 在库libmy.a 中。库libmy.a 依赖于myfun.c 和myfun.h 文件。当库目标在依赖
表中的情况如下:
libmy.a: libmy(myfun.o) libmy(another.o)表示库libmy.a 依赖于myfun.o 和another.o 文件。
有些make 允许在括号中包括多个目标。有些只允许在括号中包含一个目标。
例如:
libmy.a: libfoo.a(myfun.o another.o) 等同于libmy.a: libmy(myfun.o)
libmy(another.o)
注意 括号中不要有空格,如果make 支持指定多个目标文件时,空格用来分隔目标文件。如果一个库目
标的不同依赖文件,有不同的编译选项,这时双冒号能够对一个目标定义多次依赖表。假设有一个模块
third.o,它需要在编译时选取其他的编译选项,而myfun.o 和another.o 需要另一些编译选项,就可以
使用两个冒号来定义目。例如:
libmy.a:: libmy.a(third.o)
libmy.a:: libmy.a(my.o) libmy.a(another.o)
使用后缀规则的目标
make 有自己规定的通用目标,也就是后缀规则。后缀规则是一次性告诉make如何建立某些类型
目标。例如有makele 文件如下:
all: hello hello1
hello: hello.o
cc -o hello -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello.o
hello1: hello1.o
cc -o hello1 -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello1.o
hello.o: hello.c
cc -c hello.c
hello1.o: hello1.c
cc -c hello1.c
clean:
rm *.o hello hello1
从中读者可以发现有许多重复内容。例如,生成hello 和hello1 的命令类似,生成hello.o 和
hello1.o 的命令类似。除了编译或链接的文件不一样,其他都一样。这时,我们就可以使用后缀规则。
下面的.c.o 规则告诉make 怎样把以.c 结尾的文件转换为以.o 结尾的文件:
.c.o:
cc -c $<
在这个.c.o 规则中用到了宏“$<”,它以当前的依赖文件名代入规则中。有关这些特殊的宏将在后面
介绍。把.c.o 规则用到前面的例子中可以简化为:
LDFLAGS=-L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11
.SUFFIXES:
.SUFFIXES: .c .o
.c.o:
剩余14页未读,继续阅读
资源评论
leon_wu
- 粉丝: 0
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功