跟我一起写Makefile书签版PDF清晰版

所需积分/C币:10 2013-09-06 16:36:56 543KB PDF
收藏 收藏
举报

跟我一起写Makefile书签版PDF清晰版:有书签的 ,网上其他版本都没有书签,不方便阅读及查阅。
在讲述这个 Makefile之前,还是让我们先来粗略地看一看 Makefile的规则。 target. prerequisites.. command target也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标 签( Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述 prerequisites就是,要生成那个 target所需要的文件或是月标 command也航是make需要执行的命令。(仟意的Shel命令) 这是一个文件的依赖关系,也就是说, target这一个或多个的目标文件依赖于 prerequisIteS中的文件,其生成规则定义在 command中。说白一点就是说, prerequisites 中如果有一个以上的文件比 target文件要新的话, command所定义的命令就会被执行 这就是 Makefile的规则。也就是 Makefile中最核心的内容。 说到底, Makefile的东西就是这样一点,好像我的这篇文档也该结束了。叫呵。还不尽 然,这是 Makefile的主线和核心,但要写好一个 Makefile还不够,我会以后面一点 点地结合我的工作经验给你慢慢到来。内容还多着呢。:) 、一个示例 正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所 述的那三个规则,我们的 Makefile应该是下面的这个样子的。 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 l 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 d 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 kbdo command. o display. o insert o search. o files. o utilso 反斜杠()是换行符的意思。这样比较便于 Makefile的易读。我们可以把这个内容保存 在文件为“ Makefile”或“ makefile”的文件中,然后在该目录下直接输入命令“make”就 可以生成执行文件edit。如果要删除执行文件和所有的中间目标文仵,那么,只要简单 地执行一下“ make clean”就可以了。 在这个 makefile中,目标文件( target)包含:执行文件cdt和中间目标文件(*o) 依赖文件( prerequisites)就是冒号后面的那些,文件和h文件。每一个o文件都有 组依赖文件,而这些。文件又是执行文件edit的依赖文件。依赖关系的实质上就是说 明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。 在定义好依赖关系后,后续的那一行定义了如何生成日标文件的操作系统命令,一定 要以一个Tab键作为丌头。记住,make并不管命令是怎么工作的,他只管执行所定义 的命令。make会比较 targets文件和 prerequisites文件的修改日期,如果 prerequisites文 件的日期要比 targets文件的日期要新,或者 target不存在的话,那么,make就会执行 后续定义的命令。 这里要说明一点的是, clean不是一个文件,它只不过是一个动作名宇,有点像C语言 中的 lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性, 也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得 指出这个 lable的名宇。这样的方法非常有用,我们可以在一个 makefile中定义不用的 编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。 三、make是如何工作的 在默认的方式下,也就是我们只输入make命令。那么, 1、make会在当前目录下找名字叫“ Makefile¨或“ makefile”的文作。 2、如果找到,它会找文件中的第一个目标文件( target),在上面的例子中,他会找到 edit'这个文件,并把这个文件作为最终的目标文件。 3、如果edit文件不存在,或是edit所依赖的后面的.o文件的文件修改时间要比edit这 个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件 4、如果edit所依赖的.o文件也存在,那么make会在当前文件中找日标为.o文件的依赖 性,如果找到则再根据那一个规则生成o文件。(这有点像一个堆栈的过程) 5、当然,你的C文件和H文件是存在的啦,于是make会生成.,文件,然后再用.o文 件生命make的终极任务,也就是执行文件edit了。 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编 译出第一个目标文件。在找寻的过程屮,如果出现错误,比如最后被依赖的文件找不到, 那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功 make根本不理,make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面 的文件还是不在,那么对不起,我就不工作啦。 通过上述分析,我们知道,像 clcan这种,没有被第一个目标文件直接或间接关联,那 么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令 “ make clean”,以此来淸除所有的目标文件,以便重编译。 于是在我们编程中,如果这个工程已被编译过了,当我们修改了其中一个源文件,比 如 file. c,那么根据我们的依赖性,我们的目标ileo会被重编译(也就是在这个依性 关系后面所定义的命令),丁是fle0的文件也是最新的啦,于是file.。的文件修改时 间要匕edit要新,所以edit也被重新链接了(详见edit目标文件后定义的命令)。 而如果我们改变」“ command.h”,那么,kdb.o、 command.o和 files.o都会被重编译,并 且,edit会被重链接 四、 makefile中使用变量 在上面的例子中,先让我们看看edit的规则 edit: main. o kbd o command. o display. o insert o scarcho files. o utils o cc -o edit main.o kbd o command. o display.o insert o search. o files, o utils o 我们可以看到[o]文件的字符串被重复了两次,如果我们的工程需要加入一个新的[o] 文件,那么我们需要在两个地方加(应该是三个地方,还有一个地方在cean中)。当 然,我们的 makefile并不复杂,所以在两个地方加也不累,但如果 makefile变得复杂, 那么我们就有可能会忘掉一个需要加入的地方,而导致编译失败。所以,为了 makefile 的易维护,在 makefile中我们可以使用变量。 makefile的变量也就是一个字符串,理解 成C语言中的宏可能会更好。 比如,我们声明一个变量,叫 objects, OBJECIS.objs,OBJS,obj,或是OBJ,反正不管 什么啦,只要能够表示obj文件就行了。我们在 makefile一开始就这样定义 objects=main. o kbd o command.o display. o insert o search. o files. o utils o 于是,我们就可以很方便地在我们的 makefile中以“s( objects)”的方式来使用这个变量 ,于是我们的改良版 makefile就变成下面这个样子: objects=main.o kbd o command. o display.o insert o scarch. o files. o utils o edit: S(objects) cc-o edit s(objects main. o: main.c defs. h 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 earch o: search. c defs. h buffe 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 S(objects) 丁是如果有新的.。文件加入,我们只需简单地修改一下 objects变量就可以了。 关于变量更多的话题,我会在后续给你一一道来。 五、让make自动推导 GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们 就没必要去在每一个[o]文件后都写上类似的命令,因为,我们的make会自动识别, 并自己推导命令。 只要make看到一个[o]文件,它就会自动的把[c]文件加在依赖关系中,如果make找 到一个 whatever. o,那么 whatever. c,就会是 whatever:o的依赖文件。并且cc-c whatever. c也会被推导出来,于是,我们的 makefile再也不用写得这么复杂。我们的是 新的 makefile又出炉了 objects-main. o kbd o command. o display. o l insert o search. o files. o utils o edit: S(objects) cc-o edit s(objects) main.O kbd o: defs h command. h command. o: defs. h command.h display. o: defs. h buffer h insert. o: defs . h buffer h search. o: defs. h buffer h files. o: defs. h bufferh command. h utils o: defs. h PHONY clean clean rm edit S(objects) 这种方法,也就是make的“隐腾规则”。上面文件内容中,“ PHONY”表示, clean是 个伪目标文件。 关于更为详细的“隐晦规则”和“伪目标文件”,我会在后续给你一一道来。 六、另类风格的 makefile 即然我们的make可以自动推导命令,那么我看到那堆[.o和[h]的依赖就有点不爽,那 么多的重复的[h],能不能把其收拢起来,好吧,没有问题,这个对于make来说很容 易,谁叫它提供了自动推导命令和文件的功能呢?来看看最新风格的 makefile吧 objects- main. o kbdo command. o display. o insert o search. o files. o utils o edit: Objects) cc-o edit S(objects S(objects): defs. h kbd o command. o files. o: command. h display. o inserto search. o files. o: buffer. h PHONY: clean clean rm edit S(objects) 这种风格,让我们的 makefile变得很简单,但我们的文件依赖关系就显得有点凌乱了。 鱼和熊掌不可兼得。还看你的喜好了。我是不喜欢这种风格的,一是文件的依赖关系看 不清楚,二是如果文件一多,要加入几个新的.0文件,那就理不清楚了。 七、清空日标文件的规则 每个 Makefile中都应该写一个清空目标文件(.。和执行文件)的规则,这不仅使于重 编译,也很利于保持文件的清洁。这是一个“修养”(呵呵,还记得我的《编程修养》 吗)。一般的风格都是: clean rm edit S(objects) 更为稳健的做法是: PHONY clean rm edit s(objects 前面说过, PHONY意思表示 clean是一个“伪目标”,。而在m命令前面加了一个小 减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。当然, clean 的规则不要放在文件的开头,不然,这就会变成make的默认目标,相信谁也不愿意这 样。不成文的规矩是——“ clean从来都是放在文件的最后”。 上面就是一个 makefile的概貌,也是 makefile的基础,下面还有很多 makefile的相关 细节,准备好了吗?准备好了就来。 Makefile总述 Makefile里有什么? Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。 1、显式规则。显式规则说明了,如何生成一个或多的的日标文件。这是山 Makefile的书 写者明显指出,要生成的文件,文件的依赖文件,生成的命令。 2、隐胨规则。由于我们的make有自动推导的功能,所以隐暸的规则可以让我们比较粗 糙地简略地书写 Makefile,这是由make所支持的。 3、变量的定义。在 Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有 点你C语言中的宏,当 Makefile被执行时,其中的变量都会被扩展到相应的引用位置 4、文件指示。其包括了三个部分,一个是在一个 Makefile中引用另一个 Makefile,就像 C语言屮的 include一样;另一个是指根据某些情况指定 Makefile中的有效部分,就像 C语言中的预编译爿if一样;还有就是定义一个多行的命令。有关这一部分的内容,我 会在后续的部分中讲述。 5、注释。 Makefile中只有行注释,和UNX的Shel脚本一样,其注释是用“#字符,这 个就像CC++屮的“∥一样。如果你要在你的 Makefile中使用“#”字符,可以用反斜框 进行转义,如:“# 最后,还值得一提的是,在 Makefile中的命令,必须要以[Tab键开始 Makefile的文件名 默认的情况下,make命令会在当前目录下按顺序找寻文件名为 “ GNUmakefile¨'、“ makefile”、" Makefile”的文件,找到∫解释这个文件。在这三个文件 名中,最好使用“ Makefile”这个文仆名,因为,这个文件名第一个字符为大写,这样 有一种显目的感觉。最好不要用“ GNUmakefile”,这个文件是GNU的make识别的。有 易外一些make只对全小写的“ makefile”文件名敏感,但是基本上来说,大多数的 mak都支持“ makefile”和“ Makefile”这两种默认文件名。 当然,你可以使用别的文件名来书写 Makefile,比如: “Make. Linux”,“Make. Solaris”,“Make.AIX”等,如果要指定特定的 Makefile,你 可以使用make的“f和“-file”参数,如:make- f make, Linux或make-file Makc.AIX 、引用其它的 Makefile 在 Makefile使用 include关键字可以把别的 Makefile包含进来,这很像C语言的 include,被包含的文件会原模原样的放在当前文件的包含位置。 include的语法是 include <filename> filename可以是当前操作系统 Shell的文件模式(可以保含路径和通配符) 在 include前面可以有一些空字符,但是绝不能是[Tab键开始。 include和< filename>可 以用一个或多个空格隔开。举个例子,你有这样几个 Makefile:amk、b,mk、cmk,还有 个文件叫 foo. make,以及一个变量s(bar),其包含了emk和fmk,那么,下面的语 include foo. make. mk $(bar) 等价于: include foo make amk b. mk c mk c mk f mk make命令开始时,会把找寻 include所指出的其它 Makefile,并把其内容安置在当前的 位置。就好像¢C艹的 include指令一样。如果文件都没有指定绝对路径或是相对路径的 话,make会在当前目录卜首先寻找,如果当前目录卜没有找到,那么,make还会在 下面的几个目录下找 1、如果make执行时,有“T”或“- include-dir¨”参数,那么make就会在这个参数所指 定的目录下去寻找。 2、如果目求 prefix> include(一般是:/usr/ ocal/ bin或/ usr/include)存在的话,make也 会去找 如果有文件没有找到的话,make公生成一条警告信息,但不会马上出现致命错误。它 会继续载入其它的文件,一日完成 makefile的读取,make会再重试这些没有找到,或 是不能读取的文件,如果还是不行,make才会出现一条致命信息。如果你想让make不 理那些无法读取的文件,而继续执行,你可以在 include前加一个减号“-”。如 include <filename> 其表示,无论 include过程中出现什么错误,都不要报错继续执行。和其它版本make兼 容的相关命令是 sinclude,其作用和这一个是一样的。 四、环境变量 MAKEFILES 如果你的当前环境中定义了环境变量 MAKEFILES,那么,make会把这个变量中的值 做一个类似于 include的动作。这个变量中的值是其它的 Makefile,用空格分隔。只是, 它和 include不同的是,从这个环境变中引入的 Makefile的“目标”不会起作用,如果 环境变量中定义的文件发现错误,make也会不理。 但是在这里我还是建议不要使用这个环境变量,因为只要这个变量一被定义,那么当 你使用make时,所有的 Makefile都会受到它的影响,这绝不是你想看到的。在这里提 这个事,只是为了告诉大家,也许有时候你的 Makefile出现了怪事,那么你可以看看 当前环境中有没有定义这个变量 五、make的工作方式 GNU的make工作时的执行步骤入:(想来其它的make也是类似)

...展开详情
试读 74P 跟我一起写Makefile书签版PDF清晰版
立即下载 低至0.43元/次 身份认证VIP会员低至7折
一个资源只可评论一次,评论内容不能少于5个字
sengmitnick 非常不错的一本书。。。。以后用makefile久可以用来查询了
2014-01-17
回复
上传资源赚积分or赚钱
最新推荐
跟我一起写Makefile书签版PDF清晰版 10积分/C币 立即下载
1/74
跟我一起写Makefile书签版PDF清晰版第1页
跟我一起写Makefile书签版PDF清晰版第2页
跟我一起写Makefile书签版PDF清晰版第3页
跟我一起写Makefile书签版PDF清晰版第4页
跟我一起写Makefile书签版PDF清晰版第5页
跟我一起写Makefile书签版PDF清晰版第6页
跟我一起写Makefile书签版PDF清晰版第7页
跟我一起写Makefile书签版PDF清晰版第8页
跟我一起写Makefile书签版PDF清晰版第9页
跟我一起写Makefile书签版PDF清晰版第10页
跟我一起写Makefile书签版PDF清晰版第11页
跟我一起写Makefile书签版PDF清晰版第12页
跟我一起写Makefile书签版PDF清晰版第13页
跟我一起写Makefile书签版PDF清晰版第14页
跟我一起写Makefile书签版PDF清晰版第15页

试读结束, 可继续读5页

10积分/C币 立即下载 >