没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
深入学习 Make 命令和 Makefile
make 是 Linux 下的一款程序自动维护工具,配合 makefile 的使用,就能够
根据程序中模块的修改情况,自动判断应该对那些模块重新编译,从而保证软件
是由最新的模块构成。本文分为上下两部分,我们将紧紧围绕 make 在软件开发
中的应用展开详细的介绍。
一、都是源文件太多惹得祸
当我们在开发的程序中涉及众多源文件时,常常会引起一些问题。首先,如果程
序只有两三个源文件,那么修改代码后直接重新编译全部源文件就行了,但是如
果程序的源文件较多,这种简单的处理方式就有问题了。
设想一下,如果我们只修改了一个源文件,却要重新编译所有源文件,那么这显
然是在浪费时间。其次,要是只重新编译那些受影响的文件的话,我们又该如何
确定这些文件呢?比如我们使用了多个头文件,那么它们会被包含在各个源文件
中,修改了某些头文件后,那些源文件受影响,哪些与此无关呢?如果采取拉网
式大检查的话,可就费劲了。
由此可以看出,源文件多了可真是件让人头疼的事。幸运的是,实用程序 make
可以帮我们解决这两个问题——当程序的源文件改变后,它能保证所有受影响的
文件都将重新编译,而不受影响的文件则不予编译,这真是太好了。
二、Make 程序的命令行选项和参数
我们知道,make 程序能够根据程序中各模块的修改情况,自动判断应对哪些模
块重新编译,保证软件是由最新的模块构建的。至于检查哪些模块,以及如何构
建软件由 makefile 文件来决定。
虽然 make 可以在 makefile 中进行配置,除此之外我们还可以利用 make 程序的
命令行选项对它进行即时配置。Make 命令参数的典型序列如下所示:
make [-f makefile 文件名][选项][宏定义][目标]
这里用[]括起来的表示是可选的。命令行选项由破折号“–”指明,后面跟选项,
如
make –e
如果需要多个选项,可以只使用一个破折号,如
make –kr
也可以每个选项使用一个破折号,如
make –k –r
甚至混合使用也行,如
make –e –kr
Make 命令本身的命令行选项较多,这里只介绍在开发程序时最为常用的三个,
它们是:
–k:
如果使用该选项,即使 make 程序遇到错误也会继续向下运行;如果没有该选项,
在遇到第一个错误时 make 程序马上就会停止,那么后面的错误情况就不得而知
了。我们可以利用这个选项来查出所有有编译问题的源文件。
–n:
该选项使 make 程序进入非执行模式,也就是说将原来应该执行的命令输出,而
不是执行。
–f :
指定作为 makefile 的文件的名称。 如果不用该选项,那么 make 程序首先在当
前目录查找名为 makefile 的文件,如果没有找到,它就会转而查找名为 Makefile
的文件。如果您在 Linux 下使用 GNU Make 的话,它会首先查找 GNUmakefile,
之后再搜索 makefile 和 Makefile。按照惯例,许多 Linux 程序员使用 Makefile,
因为这样能使 Makefile 出现在目录中所有以小写字母命名的文件的前面。所以,
最好不要使用 GNUmakefile 这一名称,因为它只适用于 make 程序的 GNU 版本。
当我们想构建指定目标的时候,比如要生成某个可执行文件,那么就可以在 make
命令行中给出该目标的名称;如果命令行中没有给出目标的话,make 命令会设
法构建 makefile 中的第一个目标。我们可以利用这一特点,将 all 作为 makefile
中的第一个目标,然后将让目标作为 all 所依赖的目标,这样,当 命令行中没有
给出目标时,也能确保它会被构建。
三、Makefile 概述
上面提到,make 命令对于构建具有多个源文件的程序有很大的帮助。事实上,
只有 make 命令还是不够的,前面说过还必用须 makefile 告诉它要做什么以及怎
么做才行,对于程序开发而言,就是告诉 make 命令应用程序的组织情况。
我们现在对 makefile 的位置和数量简单说一下。一般情况下,makefile 会跟项
目的源文件放在同一个目录中。另外,系统中可以有多个 makefile,一般说来
一个项目使用一个 makefile 就可以了;如果项目很大的话,我们就可以考虑将
它分成较小的部分,然后用不同的 makefile 来管理项目的不同部分。
make 命令和 Makefile 配合使用,能给我们的项目管理带来极大的便利,除了用
于管理源代码的编译之外,还用于建立手册页,同时还能将应用程序安装到指定
的目录。
因为 Makefile 用于描述系统中模块之间的相互依赖关系,以及产生目标文件所
要执行的命令,所以,一个 makefile 由依赖关系和规则两部分内容组成。下面
分别加以解释。
依赖关系由一个目标和一组该目标所依赖的源文件组成。这里所说的目标就是将
要创建或更新的文件,最常见的是可执行文件。规则用来说明怎样使用所依赖得
文件来建立目标文件。
当 make 命令运行时,会 读 取 makefile 来确定要建立的目标文件或其他文件,然
后对源文件的日期和时间进行比较,从而决定使用那些规则来创建目标文件。一
般 情况下,在 建 立 起最终的目标文件之前,肯定免不了要建立一些中间性质的目
标文件。这时,Make 命令也是使用 makefile 来确定这些目标文件的创建顺序,
以及用于它们的规则序列。
四、makefile 中的依赖关系
make 程序自动生成和维护通常是可执行模块或应用程序的目标,目标的状态取
决于它所依赖的那些模块的状态。Make 的思想是为每一块模块都设置一个时间
标记,然后根据时间标记和依赖关系来决定哪一些文件需要更新。一 旦 依赖模块
的状态改变了,make 就会根据时间标记的新旧执行预先定义的一组命令来生成
新的目标。
依赖关系规定了最终得到的应用程序跟生成它的各个源文件之间的关系。如下面
的图 1 描述了可执行文件 main 对所有的源程序文件及其编译产生的目标文件之
间的依赖关系,见下图:
图 1 模块间的依赖关系
就图 1 而言,我们可以说可执行程序 main 依赖于 main.o、f1.o 和 ff1.o。与此
同时,main.o 依赖于 main.c 和 def1.h;f1.o 依赖于 f1.c、def1.h 和 def2.h;
而 ff1.o 则依赖于 ff1.c、def2.h 和 def3. h。在 makefile 中,我们可以用目
标名称,加冒号,后跟空格键或 tab 键,再加上由空格键或 tab 键分隔的一组用
于生产目标模块的文件来描述模块之间的依赖关系。对 于 上 例 来 说 ,可以作以下
描述:
main: main.o f1.o f2.o
main.o: main.c def1.h
f1.o: f1.c def1.h def2.h
f2.o: f2.c def2.h def3.h
不难发现,上 面 的 各 个源文件跟各模块之间的关系具有一个明显的层次结构,如
果 def2.h 发生了变化,那么就需要更新 f1.o 和 f2.o,而 f1.o 和 f2.o 发生了
变化的话,那么 main 也需要随之重新构建。
默认时,make 程序只更新 makefile 中的第一个目标,如果希望更新多个目标文
件的话,可以使用一个特殊的目标 all,假如我们想在一个 makefile 中更新 main
和 hello 这两个程序文件的话,可以加入下列语句达到这个目的:
all: main hello
五、makefile 中的规则
除了指明目标和模块之间的依赖关系之外,makefile 还要规定相应的规则来描
述如何生成目标,或者说使用哪些命令来根据依赖模块产生目标。就上例而言,
当 make程序发现需要重新构建 f1.o的时候,该使用哪些命令来完成呢?很遗憾,
到目前为止,虽然 make 知道哪些文件需要更新,但是却不知道如何进行更新,
因为我们还没有告诉它相应的命令。
当然,我们可以使用命令 gcc -c f1.c 来完成,不过如果我们需要规定一个
include 目录,或者为将来的调试准备符号信息的话,该怎么办呢?所有这些,
都需要在 makefile 中用相应规则显式地指出。
实际上,makefile 是以相关行为基本单位的,相关行用来描述目标、模块及规
则(即命令行)三者之间的关系。一个相关行格式通常为:冒号左边是目标(模
块)名;冒号右边是目标所依赖的模块名;紧跟着的规则(即命令行)是由依赖
模块产生目标所使用的命令。相关行的格式为:
目标:[依赖模块][;命令]
习惯上写成多行形式,如下所示:
剩余17页未读,继续阅读
资源评论
- bluesnail19862014-01-24很不错的书,字迹清晰,内容也够,入门足够了
blackswat
- 粉丝: 4
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功