ImageVerifierCode 换一换
格式:DOCX , 页数:10 ,大小:24.78KB ,
资源ID:8186580      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8186580.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(深入Makefile.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

深入Makefile.docx

1、深入MakefileGNU Make 工具2.1 基本 makefile 结构GNU Make 的主要工作是读进一个文本文件, makefile 。这个文 件里主要是有关哪些文件(target目的文件)是从哪些别的 文件(dependencies依靠文件)中产生的,用什么命令来进行 这个产生过程。有了这些信息, make 会检查磁碟上的文件,如果 目的文件的时间戳(该文件生成或被改动时的时间)比至少它的一 个依靠文件旧的话, make 就执行相应的命令,以便更新目的文件。 (目的文件不一定是最后的可执行档,它可以是任何一个文件。)makefile 一般被叫做“makefile”或“Makefi

2、le”。当然你可以 在 make 的命令行指定别的文件名。如果你不特别指定,它会寻 找“makefile”或“Makefile”,因此使用这两个名字是最简单 的。一个 makefile 主要含有一系列的规则,如下:: .(tab)(tab).例如,考虑以下的 makefile := makefile 开始 =myprog : foo.o bar.ogcc foo.o bar.o -o myprogfoo.o : foo.c foo.h bar.hgcc -c foo.c -o foo.obar.o : bar.c bar.hgcc -c bar.c -o bar.o= makefile 结束

3、=这是一个非常基本的 makefile make 从最上面开始,把上 面第一个目的,myprog,做为它的主要目标(一个它需要保 证其总是最新的最终目标)。给出的规则说明只要文件myprog 比文件foo.o或bar.o中的任何一个旧,下一行的命令将 会被执行。但是,在检查文件 foo.o 和 bar.o 的时间戳之前,它会往下查 找那些把 foo.o 或 bar.o 做为目标文件的规则。它找到的关于 foo.o 的规则,该文件的依靠文件是 foo.c, foo.h 和 bar.h 。 它从下面再找不到生成这些依靠文件的规则,它就开始检查磁碟 上这些依靠文件的时间戳。如果这些文件中任何一个的时

4、间戳比 foo.o 的新,命令 gcc -o foo.o foo.c 将会执行,从而更新 文件 foo.o 。 接下来对文件 bar.o 做类似的检查,依靠文件在这里是文件 bar.c 和 bar.h 。现在, make 回到myprog的规则。如果刚才两个规则中的任 何一个被执行,myprog 就需要重建(因为其中一个 .o 档就会比 myprog新),因此连接命令将被执行。希望到此,你可以看出使用 make 工具来建立程序的好处前 一章中所有繁琐的检查步骤都由 make 替你做了:检查时间戳。 你的源码文件里一个简单改变都会造成那个文件被重新编译(因 为 .o 文件依靠 .c 文件),进而

5、可执行文件被重新连接(因为 .o 文件被改变了)。其实真正的得益是在当你改变一个 header 档的时候你不再需要记住那个源码文件依靠它,因为所有的 资料都在 makefile 里。 make 会很轻松的替你重新编译所有那 些因依靠这个 header 文件而改变了的源码文件,如有需要,再 进行重新连接。当然,你要确定你在 makefile 中所写的规则是正确无误的,只 列出那些在源码文件中被 #include 的 header 档2.2 编写 make 规则 (Rules)最明显的(也是最简单的)编写规则的方法是一个一个的查 看源码文件,把它们的目标文件做为目的,而源码文件和被它 #inclu

6、de 的 header 档做为依靠文件。但是你也要把其它被这些 header 档 #include 的 header 档也列为依靠文件,还有那些被 包括的文件所包括的文件然后你会发现要对越来越多的文件 进行管理,然后你的头发开始脱落,你的脾气开始变坏,你的脸 色变成菜色,你走在路上开始跟电线杆子碰撞,终于你捣毁你的 电脑显示器,停止编程。到低有没有些容易点儿的方法呢?当然有!向编译器要!在编译每一个源码文件的时候,它实在应 该知道应该包括什么样的 header 档。使用 gcc 的时候,用 -M 开关,它会为每一个你给它的文件输出一个规则,把目标文件 做为目的,而这个文件和所有应该被 #inc

7、lude 的 header 文 件将做为依靠文件。注意这个规则会加入所有 header 文件,包 括被角括号()和双引号()所包围的文件。其实我们可以 相当肯定系统 header 档(比如 stdio.h, stdlib.h 等等)不会 被我们更改,如果你用 -MM 来代替 -M 传递给 gcc,那些用角括 号包围的 header 档将不会被包括。(这会节省一些编译时间)由 gcc 输出的规则不会含有命令部分;你可以自己写入你的命令 或者什么也不写,而让 make 使用它的隐含的规则(参考下面的 2.4 节)。2.3 Makefile 变量上面提到 makefiles 里主要包含一些规则。它们

8、包含的其它的东 西是变量定义。makefile 里的变量就像一个环境变量(environment variable)。 事实上,环境变量在 make 过程中被解释成 make 的变量。这些 变量是大小写敏感的,一般使用大写字母。它们可以从几乎任何 地方被引用,也可以被用来做很多事情,比如:i) 贮存一个文件名列表。在上面的例子里,生成可执行文件的 规则包含一些目标文件名做为依靠。在这个规则的命令行 里同样的那些文件被输送给 gcc 做为命令参数。如果在这 里使用一个变数来贮存所有的目标文件名,加入新的目标 文件会变的简单而且较不易出错。ii) 贮存可执行文件名。如果你的项目被用在一个非 gcc

9、 的系 统里,或者如果你想使用一个不同的编译器,你必须将所 有使用编译器的地方改成用新的编译器名。但是如果使用一 个变量来代替编译器名,那么你只需要改变一个地方,其 它所有地方的命令名就都改变了。iii) 贮存编译器旗标。假设你想给你所有的编译命令传递一组 相同的选项(例如 -Wall -O -g);如果你把这组选项存 入一个变量,那么你可以把这个变量放在所有呼叫编译器 的地方。而当你要改变选项的时候,你只需在一个地方改 变这个变量的内容。要设定一个变量,你只要在一行的开始写下这个变量的名字,后 面跟一个 = 号,后面跟你要设定的这个变量的值。以后你要引用 这个变量,写一个 $ 符号,后面是围

10、在括号里的变量名。比如在 下面,我们把前面的 makefile 利用变量重写一遍:= makefile 开始 =OBJS = foo.o bar.oCC = gccCFLAGS = -Wall -O -gmyprog : $(OBJS)$(CC) $(OBJS) -o myprogfoo.o : foo.c foo.h bar.h$(CC) $(CFLAGS) -c foo.c -o foo.obar.o : bar.c bar.h$(CC) $(CFLAGS) -c bar.c -o bar.o= makefile 结束 =还有一些设定好的内部变量,它们根据每一个规则内容定义。三个 比较有用

11、的变量是 $, $ 和 $ (这些变量不需要括号括住)。 $ 扩展成当前规则的目的文件名, $ 扩展成依靠列表中的第 一个依靠文件,而 $ 扩展成整个依靠的列表(除掉了里面所有重 复的文件名)。利用这些变量,我们可以把上面的 makefile 写成:= makefile 开始 =OBJS = foo.o bar.oCC = gccCFLAGS = -Wall -O -gmyprog : $(OBJS)$(CC) $ -o $foo.o : foo.c foo.h bar.h$(CC) $(CFLAGS) -c $ -o $bar.o : bar.c bar.h$(CC) $(CFLAGS) -

12、c $ -o $= makefile 结束 =你可以用变量做许多其它的事情,特别是当你把它们和函数混合 使用的时候。如果需要更进一步的了解,请参考 GNU Make 手册。 (man make, man makefile)2.4 隐含规则 (Implicit Rules)请注意,在上面的例子里,几个产生 .o 文件的命令都是一样的。 都是从 .c 文件和相关文件里产生 .o 文件,这是一个标准的步 骤。其实 make 已经知道怎么做它有一些叫做隐含规则的内 置的规则,这些规则告诉它当你没有给出某些命令的时候,应该 怎么办。如果你把生成 foo.o 和 bar.o 的命令从它们的规则中删除, m

13、ake 将会查找它的隐含规则,然后会找到一个适当的命令。它的命令会 使用一些变量,因此你可以按照你的想法来设定它:它使用变量 CC 做为编译器(象我们在前面的例子),并且传递变量 CFLAGS (给 C 编译器,C+ 编译器用 CXXFLAGS ),CPPFLAGS ( C 预 处理器旗标), TARGET_ARCH (现在不用考虑这个),然后它加 入旗标 -c ,后面跟变量 $ (第一个依靠名),然后是旗 标 -o 跟变量 $ (目的文件名)。一个编译的具体命令将 会是:$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $ depends在这里如果一

14、个叫 depends 的文件不存在,或任何一个源码文件 比一个已存在的 depends 文件新,那么一个 depends 文件会被生 成。depends 文件将会含有由 gcc 产生的关于源码文件的规则(注 意 -M 开关)。现在我们要让 make 把这些规则当做 makefile 档 的一部分。这里使用的技巧很像 C 语言中的 #include 系统我 们要求 make 把这个文件 include 到 makefile 里,如下:include dependsGNU Make 看到这个,检查 depends 目的是否更新了,如果没有, 它用我们给它的命令重新产生 depends 档。然后它会

15、把这组(新) 规则包含进来,继续处理最终目标 myprog 。当看到有关 myprog 的规则,它会检查所有的目标文件是否更新利用 depends 文件 里的规则,当然这些规则现在已经是更新过的了。这个系统其实效率很低,因为每当一个源码文件被改动,所有的源码 文件都要被预处理以产生一个新的 depends 文件。而且它也不是 100% 的安全,这是因为当一个 header 档被改动,依靠信息并不会 被更新。但就基本工作来说,它也算相当有用的了。2.8 一个更好的 makefile这是一个我为我大多数项目设计的 makefile 。它应该可以不需要修 改的用在大部分项目里。我主要把它用在 djg

16、pp 上,那是一个 DOS 版的 gcc 编译器。因此你可以看到执行的命令名、 alleg 程序包、 和 RM -F 变量都反映了这一点。= makefile 开始 =# # Generic makefile # # by George Foot # email: george.footmerton.ox.ac.uk # # Copyright (c) 1997 George Foot # All rights reserved. # 保留所有版权 # # No warranty, no liability; # you use this at your own risk. # 没保险,不负责

17、 # 你要用这个,你自己担风险 # # You are free to modify and # distribute this without giving # credit to the original author. # 你可以随便更改和散发这个文件 # 而不需要给原作者什么荣誉。 # (你好意思?) # # Customising# 用户设定# Adjust the following if necessary; EXECUTABLE is the target# executables filename, and LIBS is a list of libraries to lin

18、k in# (e.g. alleg, stdcx, iostr, etc). You can override these on makes# command line of course, if you prefer to do it that way.# # 如果需要,调整下面的东西。 EXECUTABLE 是目标的可执行文件名, LIBS# 是一个需要连接的程序包列表(例如 alleg, stdcx, iostr 等等)。当然你# 可以在 make 的命令行覆盖它们,你愿意就没问题。# EXECUTABLE := mushroom.exeLIBS := alleg# Now alter

19、any implicit rules variables if you like, e.g.:# 现在来改变任何你想改动的隐含规则中的变量,例如CFLAGS := -g -Wall -O3 -m486CXXFLAGS := $(CFLAGS)# The next bit checks to see whether rm is in your djgpp bin# directory; if not it uses del instead, but this can cause (harmless)# File not found error messages. If you are not u

20、sing DOS at all,# set the variable to something which will unquestioningly remove# files.# 下面先检查你的 djgpp 命令目录下有没有 rm 命令,如果没有,我们使用# del 命令来代替,但有可能给我们 File not found 这个错误信息,这没# 什么大碍。如果你不是用 DOS ,把它设定成一个删文件而不废话的命令。# (其实这一步在 UNIX 类的系统上是多余的,只是方便 DOS 用户。 UNIX# 用户可以删除这行命令。)ifneq ($(wildcard $(DJDIR)/bin/rm.

21、exe),)RM-F := rm -felseRM-F := delendif# You shouldnt need to change anything below this point.# 从这里开始,你应该不需要改动任何东西。(我是不太相信,太了!)SOURCE := $(wildcard *.c) $(wildcard *.cc)OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE)DEPS := $(patsubst %.o,%.d,$(OBJS)MISSING_DEPS := $(filter-out $(wildcard

22、$(DEPS),$(DEPS)MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.c,$(MISSING_DEPS) $(patsubst %.d,%.cc,$(MISSING_DEPS)CPPFLAGS += -MD.PHONY : everything deps objs clean veryclean rebuildeverything : $(EXECUTABLE)deps : $(DEPS)objs : $(OBJS)clean :$(RM-F) *.o$(RM-F) *.dveryclean: clean$(RM-F) $(EXECUTABLE)rebuild: veryclean everythingifneq ($(MISSING_DEPS),)$(MISSING_DEPS) :$(RM-F) $(patsubst %.d,%.o,$)endif-include $(DEPS)$(EXECUTABLE) : $(OBJS)gcc -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS)= makefile 结束 =有几个地方值得解

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1