没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
GNU Make 使用手册(中译版)
翻译:于凤昌
译者注:本人在阅读Linux源代码过程中发现如果要全面了解Linux的结构、理解Linux的编
程总体设计及思想必须首先全部读通Linux源代码中各级的Makefile文件。目前,在网上虽
然有一些著作,但都不能全面的解释Linux源代码中各级的Makefile文件,因此本人认真阅
读了GNU Make 使用手册(3.79)版原文,在此基础上翻译了该手册,以满足对Linux源代码
有兴趣或者希望采用GCC编写程序但对缺乏GNU Make全面了解之人士的需要。本人是业余爱
好不是专业翻译人士,如果有问题请通过电子信箱与我联系共同商讨,本人的E-mail为:
yfc70@public2.lyptt.ha.cn 。注意在文章中出现的斜体加粗字表示章节。
GNU make Version 3.79
April 2000
Richard M. Stallman and Roland McGrath
1 Make 概述
Make 可自动决定一个大程序中哪些文件需要重新编译,并发布重新编译它们的命令。
本版本 GNU Make 使用手册由 Richard M. Stallman and Roland McGrath 编著,是从 Paul D.
Smith 撰写的 V3.76 版本发展过来的。
GNU Make 符合
IEEE Standard 1003.2-1992
(POSIX.2) 6.2 章节的规定。
因为 C 语言程序更具有代表性,所以我们的例子基于 C 语言程序,但 Make 并不是仅仅
能够处理 C 语言程序,它可以处理那些编译器能够在 Shell 命令下运行的的各种语言的程序。
事实上,GNU Make 不仅仅限于程序,它可以适用于任何如果一些文件变化导致另外一些文
件必须更新的任务。
如果要使用 Make,必须先写一个称为 Makefile 的文件,该文件描述程序中各个文件之
间的相互关系,并且提供每一个文件的更新命令。在一个程序中,可执行程序文件的更新依
靠 OBJ 文件,而 OBJ 文件是由源文件编译得来的。
一旦合适的 Makefile 文件存在,每次更改一些源文件,在 shell 命令下简单的键入:
make
就能执行所有的必要的重新编译任务。Make 程序根据 Makefile 文件中的数据和每个文件更
改的时间戳决定哪些文件需要更新。对于这些需要更新的文件,Make 基于 Makefile 文件发
布命令进行更新,进行更新的方式由提供的命令行参数控制。具体操作请看
运行 Make
章节。
1.1 怎样阅读本手册
如果您现在对 Make 一无所知或者您仅需要了解对 make 的普通性介绍,请查阅前几章
内容,略过后面的章节。前几章节是普通介绍性内容,后面的章节是具体的专业、技术内容。
如果您对其它 Make 程序十分熟悉,请参阅
GNU Make 的特点
和
不兼容性和失去的特点
部分,
GNU Make 的特点
这一章列出了 GNU Make 对 make 程序的扩展,
不兼容和失去的特点
一章解释了其它 Make 程序有的特征而 GNU Make 缺乏的原因。
对于快速浏览者,请参阅
选项概要、快速参考
和
内建的特殊目标名
部分。
1.2 问题和 BUG
如果您有关于 GNU Make 的问题或者您认为您发现了一个 BUG,请向开发者报告;我们
不能许诺我们能干什么,但我们会尽力修正它。在报告 BUG 之前,请确定您是否真正发现了
BUG,仔细研究文档后确认它是否真的按您的指令运行。如果文档不能清楚的告诉您怎么做,
也要报告它,这是文档的一个 BUG。
在您报告或者自己亲自修正 BUG 之前,请把它分离出来,即在使问题暴露的前提下尽可
能的缩小 Makefile 文件。然后把这个 Makefile 文件和 Make 给出的精确结果发给我们。同
时请说明您希望得到什么,这可以帮助我们确定问题是否出在文档上。
一旦您找到一个精确的问题,请给我们发 E-mail,我们的 E-mail 地址是:
bug-make@gnu.org
在邮件中请包含您使用的 GNU Make 的版本号。您可以利用命令‘make--version’得到
版本号。同时希望您提供您的机器型号和操作系统类型,如有可能的话,希望同时提供
config.h 文件(该文件有配置过程产生)。
2 Makefile 文件介绍
Make 程序需要一个所谓的 Makefile 文件来告诉它干什么。在大多数情况下,Makefile
文件告诉 Make 怎样编译和连接成一个程序。
本章我们将讨论一个简单的 Makefile 文件,该文件描述怎样将 8 个 C 源程序文件和 3
个头文件编译和连接成为一个文本编辑器。Makefile 文件可以同时告诉 Make 怎样运行所需
要的杂乱无章的命令(例如,清除操作时删除特定的文件)。如果要看更详细、复杂的
Makefile 文件例子,请参阅
复杂的 Makefile 文件例子
一章。
当 Make 重新编译这个编辑器时,所有改动的 C 语言源文件必须重新编译。如果一个头
文件改变,每一个包含该头文件的 C 语言源文件必须重新编译,这样才能保证生成的编辑器
是所有源文件更新后的编辑器。每一个 C 语言源文件编译后产生一个对应的 OBJ 文件,如果
一个源文件重新编译,所有的 OBJ 文件无论是刚刚编译得到的或原来编译得到的必须从新连
接,形成一个新的可执行文件。
2.1 规则的格式
一个简单的 Makefile 文件包含一系列的“规则”,其样式如下:
目标(target)…: 依赖(prerequiries)…
<tab>命令(command)
…
…
目标(target)通常是要产生的文件的名称,目标的例子是可执行文件或 OBJ 文件。目标
也可是一个执行的动作名称,诸如‘clean’(详细内容请参阅
假想目标
一节)。
依赖是用来输入从而产生目标的文件,一个目标经常有几个依赖。
命令是 Make 执行的动作,一个规则可以含有几个命令,每个命令占一行。
注意:每个
命令行前面必须是一个 Tab 字符,即命令行第一个字符是 Tab。这是不小心容易出错的地方。
通常,如果一个依赖发生变化,则需要规则调用命令对相应依赖和服务进行处理从而更
新或创建目标。但是,指定命令更新目标的规则并不都需要依赖,例如,包含和目标‘clern’
相联系的删除命令的规则就没有依赖。
规则一般是用于解释怎样和何时重建特定文件的,这些特定文件是这个详尽规则的目
标。Make 需首先调用命令对依赖进行处理,进而才能创建或更新目标。当然,一个规则也
可以是用于解释怎样和何时执行一个动作,详见
编写规则
一章。
一个 Makefile 文件可以包含规则以外的其它文本,但一个简单的 Makefile 文件仅仅需
要包含规则。虽然真正的规则比这里展示的例子复杂,但格式却是完全一样。
2.2 一个简单的 Makefile 文件
一个简单的 Makefile 文件,该文件描述了一个称为文本编辑器(edit)的可执行文件
生成方法,该文件依靠 8 个 OBJ 文件(.o 文件),它们又依靠 8 个 C 源程序文件和 3 个头文
件。
在这个例子中,所有的 C 语言源文件都包含‘defs.h’ 头文件,但仅仅定义编辑命令
的源文件包含‘command.h’头文件,仅仅改变编辑器缓冲区的低层文件包含‘buffer.h’
头文件。
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
我们把每一个长行使用反斜杠-新行法分裂为两行或多行,实际上它们相当于一行,这
样做的意图仅仅是为了阅读方便。
使用 Makefile 文件创建可执行的称为‘edit’的文件,键入:make
使用 Makefile 文件从目录中删除可执行文件和目标,键入:make clean
在这个 Makefile 文件例子中,目标包括可执行文件‘edit’和 OBJ 文件‘main.o’及
‘kdb.o’。依赖是 C 语言源文件和 C 语言头文件如‘main.c’和‘def.h’等。事实上,每
一个 OBJ 文件即是目标也是依赖。所以命令行包括‘cc -c main.c’和‘cc -c kbd.c’。
当目标是一个文件时,如果它的任一个依赖发生变化,目标必须重新编译和连接。任何
命令行的第一个字符必须是‘Tab’字符,这样可以把 Makefile 文件中的命令行与其它行分
别开来。(一定要牢记:Make 并不知道命令是如何工作的,它仅仅能向您提供保证目标的合
适更新的命令。Make 的全部工作是当目标需要更新时,按照您制定的具体规则执行命令。)
目标‘clean’不是一个文件,仅仅是一个动作的名称。正常情况下,在规则中‘clean’
这个动作并不执行,目标‘clean’也不需要任何依赖。一般情况下,除非特意告诉 make
执行‘clean’命令,否则‘clean’命令永远不会执行。注意这样的规则不需要任何依赖,
它们存在的目的仅仅是执行一些特殊的命令。象这些不需要依赖仅仅表达动作的目标称为假
想目标。详细内容参见
假想目标
;参阅
命令错误
可以了解 rm 或其它命令是怎样导致 make
忽略错误的。
2.3 make 处理 makefile 文件的过程
缺省情况下,make 开始于第一个目标(假想目标的名称前带‘.’)。这个目标称为缺省
最终目标(即 make 最终更新的目标,具体内容请看
指定最终目标的参数
一节)。
在上节的简单例子中,缺省最终目标是更新可执行文件‘edit’,所以我们将该规则设
为第一规则。这样,一旦您给出命令:
make
make 就会读当前目录下的 makefile 文件,并开始处理第一条规则。在本例中,第一条规则
是连接生成‘edit’,但在 make 全部完成本规则工作之前,必须先处理‘edit’所依靠的
OBJ 文件。这些 OBJ 文件按照各自的规则被处理更新,每个 OBJ 文件的更新规则是编译其源
文件。重新编译根据其依靠的源文件或头文件是否比现存的 OBJ 文件更‘新’,或者 OBJ 文
件是否存在来判断。
其它规则的处理根据它们的目标是否和缺省最终目标的依赖相关联来判断。如果
一些规则和缺省最终目标无任何关联则这些规则不会被执行,除非告诉 Make 强制执行(如
输入执行 make clean 命令)。
在 OBJ 文件重新编译之前,Make 首先检查它的依赖 C 语言源文件和 C 语言头文件
是否需要更新。如果这些 C 语言源文件和 C 语言头文件不是任何规则的目标,make 将不会
对它们做任何事情。Make 也可以自动产生 C 语言源程序,这需要特定的规则,如可以根据
Bison 或 Yacc 产生 C 语言源程序。
在 OBJ 文件重新编译(如果需要的话)之后,make 决定是否重新连接生成 edit
可执行文件。如果 edit 可执行文件不存在或任何一个 OBJ 文件比存在的 edit 可执行文件
‘新’,则 make 重新连接生成 edit 可执行文件。
这样,如果我们修改了‘insert.c’文件,然后运行 make,make 将会编译‘insert.c’
文件更新‘insert.o’文件,然后重新连接生成 edit 可执行文件。如果我们修改了
‘command.h’文件,然后运行 make,make 将会重新编译‘kbd.o’和‘command.o’文件,
然后重新连接生成 edit 可执行文件。
2.4 使用变量简化 makefile 文件
在我们的例子中,我们在‘edit’的生成规则中把所有的 OBJ 文件列举了两次,这里再
重复一遍:
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
这样的两次列举有出错的可能,例如在系统中加入一个新的 OBJ 文件,我们很有可能在一个
需要列举的地方加入了,而在另外一个地方却忘记了。我们使用变量可以简化 makefile 文
件并且排除这种出错的可能。变量是定义一个字符串一次,而能在多处替代该字符串使用(具
体内容请阅读
使用变量
一节)。
在 makefile 文件中使用名为 objects, OBJECTS, objs, OBJS, obj, 或 OBJ 的变量代
表所有 OBJ 文件已是约定成俗。在这个 makefile 文件我们定义了名为 objects 的变量,其
定义格式如下:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
然后,在每一个需要列举 OBJ 文件的地方,我们使用写为`$(objects)'形式的变量代替(具
体内容请阅读
使用变量
一节)。下面是使用变量后的完整的 makefile 文件:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)
2.5 让 make 推断命令
编译单独的 C 语言源程序并不需要写出命令,因为 make 可以把它推断出来:make 有一
个使用‘CC –c’命令的把 C 语言源程序编译更新为相同文件名的 OBJ 文件的隐含规则。例
如 make 可以自动使用‘cc -c main.c -o main.o’命令把‘main.c’编译 ‘main.o’。因
此,我们可以省略 OBJ 文件的更新规则。详细内容请看
使用隐含规则
一节。
如果 C 语言源程序能够这样自动编译,则它同样能够自动加入到依赖中。所以我们可在
依赖中省略 C 语言源程序,进而可以省略命令。下面是使用隐含规则和变量 objects 的完整
makefile 文件的例子:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
剩余96页未读,继续阅读
资源评论
- zxpBenson2018-07-30最近在读apue,感觉make需要熟悉一下,这个pdf在百度上要买vip才能下,有点呵呵,还是csdn好啊
- 伪java工程师2012-10-26很全面,可以好好研究学习了
- raidenawkward2012-10-08感谢分享了 97页,内容很全
mzlogin
- 粉丝: 231
- 资源: 15
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Screenshot_20240427_031602.jpg
- 网页PDF_2024年04月26日 23-46-14_QQ浏览器网页保存_QQ浏览器转格式(6).docx
- 直接插入排序,冒泡排序,直接选择排序.zip
- 在排序2的基础上,再次对快排进行优化,其次增加快排非递归,归并排序,归并排序非递归版.zip
- 实现了7种排序算法.三种复杂度排序.三种nlogn复杂度排序(堆排序,归并排序,快速排序)一种线性复杂度的排序.zip
- 冒泡排序 直接选择排序 直接插入排序 随机快速排序 归并排序 堆排序.zip
- 课设-内部排序算法比较 包括冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、归并排序和堆排序.zip
- Python排序算法.zip
- C语言实现直接插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序、归并排序、计数排序,并带图详解.zip
- 常用工具集参考用于图像等数据处理
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功