3-Makefile书写规则

合集下载

c语言makefile编写规则(一)

c语言makefile编写规则(一)

c语言makefile编写规则(一)C语言Makefile编写规则1. Makefile介绍Makefile是一种文件,其中包含了一组规则(rules)用于编译和构建项目。

它的作用是告诉系统如何编译代码,生成可执行文件。

2. Makefile规则基本结构Makefile规则由以下几部分组成:目标(Target)目标是一个文件,可以是源代码文件、中间文件或最终生成的可执行文件。

依赖(Dependencies)依赖指的是生成目标所需要的文件或其他目标。

当某个依赖文件发生变化时,目标就需要重新生成。

命令(Commands)命令是指执行编译、链接等操作的具体命令。

当目标需要重新生成时,Makefile会执行相应的命令。

规则示例以下是一个简单的示例,展示了一个C语言源文件的编译过程:target: dependenciescommand其中, - target表示目标文件; - dependencies表示生成目标所需要的文件或其他目标; - command表示具体的编译命令。

例如,假设有一个名为`的C语言源文件,我们想要生成一个名为hello`的可执行文件。

那么对应的Makefile规则可以定义如下:hello:gcc -o hello3. Makefile变量Makefile中还可以定义变量,以提高代码的可读性和重用性。

变量可以存储命令、文件名、路径等信息。

变量定义变量的定义采用变量名 = 值的方式进行,例如:CC = gcc其中,CC是变量名,gcc是变量的值。

变量引用使用变量时,需要在变量名前加$符号进行引用。

例如,使用上述定义的CC变量可以这样写:$(CC) -o hello4. Makefile示例以下是一个完整的Makefile示例,展示了多个目标之间的依赖关系和命令定义:CC = gccall: hellohello:$(CC) -o hello:$(CC) -cclean:rm -f hello在上述示例中,共定义了3个目标:all、hello和。

makefile编写规则

makefile编写规则

makefile编写规则⼀、makefile 规则:⼀般开头都是 Tab ,不能空格, include 前⾯不能是 Tab; 1、如果没编译过,将所有的(.c)⽂件编译并且链接; 2、如果有其中的(.c)⽂件改变,编译并链接改变的⽂件; 3、如果(.h)⽂件被修改,编译引⽤相应的(.c)⽂件, 链接; 4、在随意修改时间的情况下,会导致编译过程中⽣成的(.o 中间⽂件)与可执⾏⽂件时间不⼀致,此时会编译相应的⽂件,并链接,最终编译成可执⾏⽂件;⼆、第⼀版 makefile: 例如有2个 .h ⽂件(utils.h, player.h, actor.h)和 3个 .c ⽂件( main.c, player.c, actor.c)需要编译链接:/*****main.c*********/#include "utils.h"#include "player.h"void main() {// do something}/*******player.c**********/#include "utils.h"#include "actor.h"bool create_player() {// do something}/****actor.c************/#include "utils.h"bool create_actor() {// do something}/********* makefile *****************/test : main.o actor.occ -o test main.o actor.omain.o : main.c utils.h player.h actor.hcc -c main.cpalyer.o: player.c player.h actor.h utils.hcc -c player.cactor.o: actor.h utils.hcc -c actor.cclean:rm test ain.o player.o actor.o 优点:可毒性很强,思路清晰明了; 缺点:⿇烦,重复的依赖过多,当需要编译⼤量⽂件时容易出错;第⼆版:利⽤ makefile 的变量;/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉main.o : main.c utils.h player.h actor.hcc -c main.cpalyer.o: player.c player.h actor.h utils.hcc -c player.cactor.o: actor.h utils.hcc -c actor.c .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ) // 前⾯的(-)表⽰,执⾏过程中不 care 出错;第三版:利⽤ GUN make 的⾃动推导规则 当 make 看到(.o )⽂件,他会⾃动把(.c)⽂件加上依赖关系,包括执⾏的语句(cc -c xx.c);/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉main.o : utils.h player.h actor.hpalyer.o: player.h actor.h utils.hactor.o: actor.h utils.h .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ)第四版:对第三版的整理(有⼀些重复的 .h) 公共的⼀起依赖,单独的单独依赖/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉$(OBJ) : utils.h actor.omain.o player.o .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ)优点:简洁缺点:不好理解以上的makefike⽂件的基本写法;或许你也发现了,如果有⼏百个源⽂件咋整呢,光是⽬录就要晕死,下⾯就是针对这种情况来说⼀下⼤型⼯程 makefile 的编写设计⼆、⼤型项⽬makefile编写: Makefile 同样也有像 c / c++ 类似的include功能; 例如我们有⼀堆 a.mk , b.mk以及 foo.make和⼀个变量 $(bar),其包含了 e.mk,f.mk, 那么 include foo.make *.mk $(bar) ------- 等价-------》 include foo.make a.mk b.mk e.mk f.mk。

Makefile经典教程(掌握这些足够)

Makefile经典教程(掌握这些足够)

Makefile经典教程(掌握这些⾜够)makefile很重要什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个⼯作,但我觉得要作⼀个好的和professional的程序员,makefile还是要懂。

这就好像现在有这么多的HTML的编辑器,但如果你想成为⼀个专业⼈⼠,你还是要了解HTML的标识的含义。

特别在Unix下的软件编译,你就不能不⾃⼰写makefile 了,会不会写makefile,从⼀个侧⾯说明了⼀个⼈是否具备完成⼤型⼯程的能⼒。

因为,makefile关系到了整个⼯程的编译规则。

⼀个⼯程中的源⽂件不计数,其按类型、功能、模块分别放在若⼲个⽬录中,makefile定义了⼀系列的规则来指定,哪些⽂件需要先编译,哪些⽂件需要后编译,哪些⽂件需要重新编译,甚⾄于进⾏更复杂的功能操作,因为makefile就像⼀个Shell脚本⼀样,其中也可以执⾏的命令。

makefile带来的好处就是——“⾃动化编译”,⼀旦写好,只需要⼀个make命令,整个⼯程完全⾃动编译,极⼤的提⾼了软件开发的效率。

make是⼀个命令⼯具,是⼀个解释makefile中指令的命令⼯具,⼀般来说,⼤多数的IDE都有这个命令,⽐如:Delphi的make,Visual C++的nmake,下GNU的make。

可见,makefile都成为了⼀种在⼯程⽅⾯的编译⽅法。

现在讲述如何写makefile的⽂章⽐较少,这是我想写这篇⽂章的原因。

当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“⽂件依赖性”上做⽂章,这⾥,我仅对GNU的make进⾏讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。

必竟,这个make是应⽤最为⼴泛的,也是⽤得最多的。

⽽且其还是最遵循于IEEE 1003.2-1992标准的(POSIX.2)。

在这篇⽂档中,将以C/C++的源码作为我们基础,所以必然涉及⼀些关于C/C++的编译的知识,相关于这⽅⾯的内容,还请各位查看相关的编译器的⽂档。

[转]makefile文件的编写规则及实例

[转]makefile文件的编写规则及实例

[转]makefile⽂件的编写规则及实例1.⼀个简单的makefile例⼦假设⼀个程序有两个⽂件file1.c,file2.c,每个⽂件都包含head.h,⽣成file可执⾏⽂件file:file1.o file2.o 附属⾏(⽂件的依存关系)gcc -o file1.o file2.o 命令⾏file1.o:file1.c head.hgcc -c file1.cfile2.o:file2.c head.hgcc -c file2.c从file最终的⽬标⽂件开始倒推,依次列出⽂件的依存关系,make在执⾏时:(1)判断file可执⾏⽂件是否存在,若不存在,则执⾏命令⾏,向下寻找依存关系(2)若file存在,则检查依靠⽂件,是否存在更新,若存在更新则执⾏命令⾏,若没有更新则给出提⽰:make:'file' is up to date.2.makefile中的宏定义及内部变量宏定义:OBJS = file1.o file2.oCC = gccCFLAGS = -wall -O -g引⽤:file:$(OBJS)$(CC) $(OBJS) -o filefile1.o:file1.c head.h$(CC) $(FLAGS) -c file1.cfile2.o:file2.c head.h$(CC) $(FLAGS) -c file2.c内部变量:$@:当前规则的⽬的⽂件名$<:依靠列表中的第⼀个依靠⽂件$^:整个依靠列表file:$(OBJS)$(CC) $^ -o $@file1.o:file1.c head.h$(CC) $(FLAGS) -c $< -o $@file2.o:file2.c head.h$(CC) $(FLAGS) -c $< -o $@"$(CC) $(FLAGS) -c $< -o $@"是隐含规则,可以不写,默认使⽤此规则3.假象假设⼀个项⽬要⽣成两个可执⾏⽂件file1和file2,这两个⽂件是相与独⽴的,则在makefile开始处:all:file1 file2make总是假设all要⽣成,去检查它的依赖⽂件4.清除由make产⽣的⽂件clean:rm *.orm file执⾏:make clean则会清除由make⽣成的*.o和file⽂件如果有clean⽂件存在,则清除不会执⾏(因clean没有可依赖的⽂件,永远是最新的)使⽤PHONY⽬标,避免同名⽂件相冲突,不会检查clean⽂件存在与否,都要执⾏清除操作.PHONY : cleanclean:rm *.orm file5.makefile函数搜索当前⽬录,⽣成由*.c结尾的⽂件列表,wildcard--函数名SOURCE = $(wildcard *.c)⽤%.o替换$(SOURCE)中的%.c⽂件OBJS = $(patsubst %.c,%.O,$(SOURCE))6.产⽣新规则SOURCE = $(wildcard *.c)depends:$(SOURCE)gcc -M $(SOURCE) > depends(为每⼀个.c⽂件产⽣规则,c⽂件和相关头⽂件为依靠)在makefile⽂件中:include depends7.⼀个有效的makefile⽂件可以完成⼤部分我们所需要的依靠检查,不⽤做太多的修改就可⽤在⼤多数项⽬⾥功能:搜索当前⽬录,寻找源码⽂件,放⼊SOURCE变量⾥,利⽤patsubst产⽣⽬标⽂件(*.o)CC = gccCFLAGS = -Wall -O -gSOURCE = $(wildcard *.c,*.cc)OBJS = $(patsubst %.c,%.o,$(patsubst,%.cc,%.o,$(SOURCE)))file:$(OBJS)$(CC) $^ -o $@⽤默认规则产⽣⽬标⽂件(*.o)1:编译可执⾏程序。

makefile文件语法

makefile文件语法

makefile文件语法Makefile是一种用于自动化构建过程的工具,它使用一种特定的语法来定义构建规则和依赖关系。

下面是一些Makefile的基本语法规则:1. 目标(Target):目标是指要构建的程序或文件。

它通常以冒号(:)开头,后面跟着一个或多个依赖项(dependencies)。

```makefiletarget: dependenciescommands```2. 依赖项(Dependencies):依赖项是指要构建目标所必需的文件或目标。

在Makefile中,依赖项以空格分隔。

3. 命令(Commands):命令是指在构建目标时执行的命令行指令。

这些命令可以是编译、链接或其他任何必要的操作。

4. 变量(Variables):Makefile允许使用变量来存储值,以便在构建过程中重复使用。

变量以符号开头,后面跟着变量名。

```makefileVAR = value```5. 模式规则(Pattern Rules):模式规则允许根据文件模式匹配来构建目标。

它们使用通配符来匹配文件名,并在匹配的文件上执行相应的命令。

```makefiletargets : patterncommands```6. 条件语句(Conditionals):Makefile支持条件语句,可以根据条件执行不同的命令或规则。

条件使用ifdef、ifndef、ifeq等关键字定义。

7. 注释(Comments):Makefile使用井号()作为注释标记,任何在该符号之后的内容都会被视为注释,并被忽略。

8. 自动变量(Automatic Variables):Makefile提供了一些自动变量,可以在命令中使用,以获取有关目标、依赖项或文件名的信息。

例如,$表示当前目标,$<表示第一个依赖项等。

这些是Makefile的一些基本语法规则,但还有更多高级特性和用法,可以参考Make工具的文档或相关教程进行深入学习。

makefile文件语法规则

makefile文件语法规则

makefile文件语法规则Makefile文件的基本语法规则包括以下几点:1. 注释:以井号(#)开头的行被视为注释,不会被执行。

2. 规则:每条规则由一个目标文件和一组依赖文件组成,以及一个用于构建目标文件的命令。

规则的格式如下:Css:目标文件:依赖文件命令目标文件和依赖文件之间用冒号(:)分隔,命令部分指定了如何从依赖文件生成目标文件。

3. 变量:Makefile中可以使用变量来存储值,变量的值可以包含文本、空格、数字等。

变量名以美元符号($)开头,例如:Makefile:VAR = value命令= $VAR4. 函数:Makefile支持使用函数来执行更复杂的操作。

函数的语法如下:Scss:函数名(参数)Makefile中内置了一些常用的函数,如字符串操作函数、条件判断函数等。

也可以自定义函数。

5. 通配符:Makefile中可以使用通配符来匹配多个文件,常见的通配符有“*”和“?”。

例如,“*.c”表示匹配所有以“.c”结尾的文件,“a?b”表示匹配“ab”、“axb”、“ayb”等字符串。

6. 回声:在Makefile中,命令前面加上“@”符号可以关闭回声,即不会在执行命令时显示该命令。

例如:Makefile:@echo Hello, world!这条命令执行时不会输出“Hello, world!”的文本。

7. 模式规则:Makefile中的模式规则允许根据一组通配符匹配的文件来定义规则,格式如下:Makefile:模式:目标文件命令1命令2模式匹配的文件将按照指定的命令构建目标文件。

c语言makefile编写规则

c语言makefile编写规则

c语言makefile编写规则C语言Makefile编写规则什么是MakefileMakefile是一种用于管理和构建软件项目的文件,通常被用于编译和链接C语言程序。

Makefile中包含了一系列的规则和指令,用于告诉编译器如何编译程序中的各个部分,并最终生成可执行文件。

Makefile的基本结构Makefile的基本结构由多个规则组成,每个规则由一个目标(target)和一个或多个依赖(dependencies)组成。

目标指明了要生成的文件或要执行的操作,依赖指明了目标所依赖的文件或操作。

一个简单的Makefile规则的语法如下:target: dependenciescommand其中,target是生成的文件或要执行的操作,dependencies是目标所依赖的文件或操作,command是执行的命令。

每个规则的命令必须以一个tab键开始。

Makefile的应用场景Makefile广泛应用于C语言项目的构建中,它可以自动化执行编译、链接和清理等操作。

通过Makefile,我们可以方便地管理源代码文件、头文件和库文件之间的关系,从而提高项目的可维护性和可扩展性。

Makefile的编写规则1.目标和依赖应该使用合适的命名方式,能够清晰地表达其作用以及所依赖的内容。

避免使用中文、空格和特殊字符,使用下划线和英文字母进行命名。

2.命令行命令应该以tab键开始,而不是空格。

这是Makefile的语法要求,且使用tab键可以提高代码的可读性。

3.注意规则的顺序,确保前置依赖在目标之前。

Makefile会按照规则的声明顺序进行构建,如果前置依赖在目标之后,可能导致构建失败。

4.使用变量来定义重复使用的内容,如编译器选项、源文件列表等。

这样可以提高代码的可维护性,并方便进行后续的修改和维护。

5.使用通配符来表示一类文件,如使用*.c表示所有的C语言源文件,使用$(wildcard pattern)函数来获取符合某种模式的文件列表。

makefile 中文手册 第四章 _ Makefile的规则

makefile 中文手册 第四章 _ Makefile的规则

第四章:Makefile的规则本章我们将讨论Makefile的一个重要内容,规则。

熟悉规则对于书写Makefile至关重要。

Makefile中,规则描述了在何种情况下使用什么命令来重建一个特定的文件,此文件被称为规则“目标”(通常规则中的目标只有一个)。

规则中出目标之外的罗列的其它文件称为“目标”的依赖,而规则的命令是用来更新或者创建此规则的目标。

除了makefile的“终极目标”所在的规则以外,其它规则的顺序在makefile文件中没有意义。

“终极目标”就是当没有使用make 命令行指定具体目标时,make默认的更新的哪一个目标。

它是makefile文件中第一个规则的目标。

如果在makefile中第一个规则有多个目标的话,那么多个目标中的第一个将会被作为make的“终极目标”。

有两种情况的例外:1. 目标名以点号“.”开始的并且其后不存在斜线“/”(“./”被认为是当前目录;“../”被认为是上一级目录);2. 模式规则的目标。

当这两种目标所在的规则是Makefile的第一个规则时,它们并不会被作为“终极目标”。

“终极目标”是执行make的唯一目的,其所在的规则作为第一个被执行的规则。

而其它的规则是在完成重建“终极目标”的过程中被连带出来的。

所以这些目标所在规则在Makefile中的顺序无关紧要。

因此,我们书写的makefile的第一个规则应该就是重建整个程序或者多个程序的依赖关系和执行命令的描述。

4.1 一个例子我们来看一个规则的例子:foo.o : foo.c defs.h # module for twiddling the frobscc -c -g foo.c这是一个典型的规则。

看到这个例子,大家应该能够说出这个规则的各个部分之间的关系。

不过我们还是要把这个例子拿出来讨论。

目的是让我们更加明确地理解Makefile的规则。

本例第一行中,文件“foo.o”是规则需要重建的文件,而“foo.c”和“defs.h”是重建“foo.o”所要使用的文件。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

3 Makefile书写规则规则包含两个部分,一个是依赖关系,一个是生成目标的方法。

在Makefile中,规则的顺序是很重要的,因为,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,所以一定要让make知道你的最终目标是什么。

一般来说,定义在Makefile中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。

如果第一条规则中的目标有很多个,那么,第一个目标会成为最终的目标。

make所完成的也就是这个目标。

好了,还是让我们来看一看如何书写规则。

3.1 规则举例foo.o : foo.c defs.h # foo模块cc -c -g foo.c看到这个例子,各位应该不是很陌生了,前面也已说过,foo.o是我们的目标,foo.c和defs.h是目标所依赖的源文件,而只有一个命令“cc -c -g foo.c”(以Tab键开头)。

这个规则告诉我们两件事:1. 文件的依赖关系,foo.o依赖于foo.c和defs.h的文件,如果foo.c和defs.h的文件日期要比foo.o文件日期要新,或是foo.o不存在,那么依赖关系发生。

2. 如果生成(或更新)foo.o文件。

也就是那个cc命令,其说明了,如何生成foo.o这个文件。

(当然foo.c文件include了defs.h文件)3.2 规则的语法targets : prerequisitescommand...或是这样:targets : prerequisites ; commandcommand...targets是文件名,以空格分开,可以使用通配符。

一般来说,我们的目标基本上是一个文件,但也有可能是多个文件。

command是命令行,如果其不与“target:prerequisites”在一行,那么,必须以[Tab键]开头,如果和prerequisites在一行,那么可以用分号做为分隔。

(见上)prerequisites也就是目标所依赖的文件(或依赖目标)。

如果其中的某个文件要比目标文件要新,那么,目标就被认为是“过时的”,被认为是需要重生成的。

这个在前面已经讲过了。

如果命令太长,你可以使用反斜框(‘\’)作为换行符。

make对一行上有多少个字符没有限制。

规则告诉make两件事,文件的依赖关系和如何成成目标文件。

一般来说,make会以UNIX的标准Shell,也就是/bin/sh来执行命令。

3.3 在规则中使用通配符如果我们想定义一系列比较类似的文件,我们很自然地就想起使用通配符。

make支持三各通配符:“*”,“?”和“[...]”。

这是和Unix的B-Shell是相同的。

波浪号(“~”)字符在文件名中也有比较特殊的用途。

如果是“~/test”,这就表示当前用户的$HOME目录下的test目录。

而“~hchen/test”则表示用户hchen的宿主目录下的test目录。

(这些都是Unix下的小知识了,make也支持)而在Windows或是MS-DOS下,用户没有宿主目录,那么波浪号所指的目录则根据环境变量“HOME”而定。

通配符代替了你一系列的文件,如“*.c”表示所以后缀为c的文件。

一个需要我们注意的是,如果我们的文件名中有通配符,如:“*”,那么可以用转义字符“\”,如“\*”来表示真实的“*”字符,而不是任意长度的字符串。

好吧,还是先来看几个例子吧:clean:rm -f *.o上面这个例子我不不多说了,这是操作系统Shell所支持的通配符。

这是在命令中的通配符。

print: *.clpr -p $?touch print上面这个例子说明了通配符也可以在我们的规则中,目标print依赖于所有的[.c]文件。

其中的“$?”是一个自动化变量,我会在后面给你讲述。

objects = *.o上面这个例子,表示了,通符同样可以用在变量中。

并不是说[*.o]会展开,不!objects的值就是“*.o”。

Makefile中的变量其实就是C/C++中的宏。

如果你要让通配符在变量中展开,也就是让objects的值是所有[.o]的文件名的集合,那么,你可以这样:objects := $(wildcard *.o)这种用法由关键字“wildcard”指出,关于Makefile的关键字,我们将在后面讨论。

3.4 文件搜寻在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。

所以,当make需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。

Makefile文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。

如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。

VPATH = src:../headers上面的的定义指定两个目录,“src”和“../headers”,make会按照这个顺序进行搜索。

目录由“冒号”分隔。

(当然,当前目录永远是最高优先搜索的地方)另一个设置文件搜索路径的方法是使用make的“vpath”关键字(注意,它是全小写的),这不是变量,这是一个make的关键字,这和上面提到的那个VPATH变量很类似,但是它更为灵活。

它可以指定不同的文件在不同的搜索目录中。

这是一个很灵活的功能。

它的使用方法有三种:1. vpath < pattern> < directories>为符合模式< pattern>的文件指定搜索目录< directories>。

2. vpath < pattern>清除符合模式< pattern>的文件的搜索目录。

3. vpath清除所有已被设置好了的文件搜索目录。

vapth使用方法中的< pattern>需要包含“%”字符。

“%”的意思是匹配零或若干字符,例如,“%.h”表示所有以“.h”结尾的文件。

< pattern>指定了要搜索的文件集,而< directories>则指定了的文件集的搜索的目录。

例如:vpath %.h ../headers该语句表示,要求make在“../headers”目录下搜索所有以“.h”结尾的文件。

(如果某文件在当前目录没有找到的话)我们可以连续地使用vpath语句,以指定不同搜索策略。

如果连续的vpath语句中出现了相同的< pattern>,或是被重复了的< pattern>,那么,make会按照vpath语句的先后顺序来执行搜索。

如:vpath %.c foovpath % blishvpath %.c bar其表示“.c”结尾的文件,先在“foo”目录,然后是“blish”,最后是“bar”目录。

vpath %.c foo:barvpath % blish而上面的语句则表示“.c”结尾的文件,先在“foo”目录,然后是“bar”目录,最后才是“blish”目录。

3.5 伪目标最早先的一个例子中,我们提到过一个“clean”的目标,这是一个“伪目标”,clean:rm *.o temp正像我们前面例子中的“clean”一样,即然我们生成了许多文件编译文件,我们也应该提供一个清除它们的“目标”以备完整地重编译而用。

(以“make clean”来使用该目标)因为,我们并不生成“clean”这个文件。

“伪目标”并不是一个文件,只是一个标签,由于“伪目标”不是文件,所以make无法生成它的依赖关系和决定它是否要执行。

我们只有通过显示地指明这个“目标”才能让其生效。

当然,“伪目标”的取名不能和文件名重名,不然其就失去了“伪目标”的意义了。

当然,为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”。

.PHONY : clean只要有这个声明,不管是否有“clean”文件,要运行“clean”这个目标,只有“make clean”这样。

于是整个过程可以这样写:.PHONY: cleanclean:rm *.o temp伪目标一般没有依赖的文件。

但是,我们也可以为伪目标指定所依赖的文件。

伪目标同样可以作为“默认目标”,只要将其放在第一个。

一个示例就是,如果你的Makefile需要一口气生成若干个可执行文件,但你只想简单地敲一个make完事,并且,所有的目标文件都写在一个Makefile 中,那么你可以使用“伪目标”这个特性:all : prog1 prog2 prog3.PHONY : allprog1 : prog1.o utils.occ -o prog1 prog1.o utils.oprog2 : prog2.occ -o prog2 prog2.oprog3 : prog3.o sort.o utils.occ -o prog3 prog3.o sort.o utils.o我们知道,Makefile中的第一个目标会被作为其默认目标。

我们声明了一个“all”的伪目标,其依赖于其它三个目标。

由于伪目标的特性是,总是被执行的,所以其依赖的那三个目标就总是不如“all”这个目标新。

所以,其它三个目标的规则总是会被决议。

也就达到了我们一口气生成多个目标的目的。

“.PHONY : all”声明了“all”这个目标为“伪目标”。

随便提一句,从上面的例子我们可以看出,目标也可以成为依赖。

所以,伪目标同样也可成为依赖。

看下面的例子:.PHONY: cleanall cleanobj cleandiffcleanall : cleanobj cleandiffrm programcleanobj :rm *.ocleandiff :rm *.diff“make clean”将清除所有要被清除的文件。

“cleanobj”和“cleandiff”这两个伪目标有点像“子程序”的意思。

我们可以输入“makecleanall”和“make cleanobj”和“make cleandiff”命令来达到清除不同种类文件的目的3.6 多目标Makefile的规则中的目标可以不止一个,其支持多目标,有可能我们的多个目标同时依赖于一个文件,并且其生成的命令大体类似。

于是我们就能把其合并起来。

当然,多个目标的生成规则的执行命令是同一个,这可能会可我们带来麻烦,不过好在我们的可以使用一个自动化变量“$@”(关于自动化变量,将在后面讲述),这个变量表示着目前规则中所有的目标的集合,这样说可能很抽象,还是看一个例子吧。

相关文档
最新文档