荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: zzt (我命由我不由天), 信区: Linux
标  题: GNU make指南[转](四)
发信站: BBS 荔园晨风站 (Wed Jun  7 08:23:29 2000), 转信

【 以下文字转载自 zzt 的信箱 】
【 原文由 zzt.bbs@flanker.uestc.edu.cn 所发表 】
发信人: bclz (依然是不见不散), 信区: Linux
标  题: GNU make指南[转](四)
发信站: 一网深情 (Wed May 26 10:27:38 1999), 转信



   2.4 隐含规则 (Implicit Rules)
   请注意,在上面的例子里,几个产生 .o 文件的命令都是一样的。 都是从 .c
   文件和相关文件里产生 .o 文件,这是一个标准的步 骤。其实 make 已?-
   知道怎么做——它有一些叫做隐含规则的内
   置的规则,这些规则告诉它当你没有给出某些命令的时候,应该 怎么办。
   如果你把生成 foo.o 和 bar.o 的命令从它们的规则中删除, make
   将会查找它的隐含规则,然后会找到一个适当的命令。它的命令会
   使用一些变量,因此你可以按照你的想法来设定它:它使用变量 CC
   做为编译器(象我们在前面的例子),并且传递变量 CFLAGS (给 C
   编译器,C++ 编译器用 CXXFLAGS ),CPPFLAGS ( C 预 处理器旗标),
   TARGET_ARCH (现在不用考虑这个),然后它加 入旗标 '-c' ,后面跟变量 $<
   (第一个依靠名),然后是旗 标 '-o' 跟变量 $@
   (目的文件名)。一个C编译的具体命令将 会是:
   $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
   当然你可以按照你自己的需要来定义这些变量。这就是为什么用 gcc 的 -M 或
   -MM 开关输出的码可以直接用在一个 makefile 里。
   2.5 假象目的 (Phony Targets)
   假设你的一个项目最后需要产生两个可执行文件。你的主要目标
   是产生两个可执行文件,但这两个文件是相互独立的——如果一
   个文件需要重建,并不影响另一个。你可以使用“假象目的”来
   达到这种效果。一个假象目的跟一个正常的目的几乎是一样的,
   只是这个目的文件是不存在的。因此, make 总是会假设它需要
   被生成,当把它的依赖文件更新后,就会执行它的规则里的命令 行。
   如果在我们的 makefile 开始处输入:
   all : exec1 exec2
   其中 exec1 和 exec2 是我们做为目的的两个可执行文件。 make 把这个 'all'
   做为它的主要目的,每次执行时都会尝试把 'all'
   更新。但既然这行规则里没有哪个命令来作用在一个叫 'all' 的
   实际文件(事实上 all 并不会在磁碟上实际产生),所以这个规
   则并不真的改变 'all' 的状态。可既然这个文件并不存在,所以 make
   会尝试更新 all 规则,因此就检查它的依靠 exec1, exec2
   是否需要更新,如果需要,就把它们更新,从而达到我们的目的。
   假象目的也可以用来描述一组非预设的动作。例如,你想把所有由 make
   产生的文件删除,你可以在 makefile 里设立这样一个规则:
   veryclean :
     rm *.o
     rm myprog
   前提是没有其它的规则依靠这个 'veryclean' 目的,它将永远
   不会被执行。但是,如果你明确的使用命令 'make veryclean' , make
   会把这个目的做为它的主要目标,执行那些 rm 命令。
   如果你的磁碟上存在一个叫 veryclean 文件,会发生什么事?这
   时因为在这个规则里没有任何依靠文件,所以这个目的文件一定是
   最新的了(所有的依靠文件都已臼亲钚碌牧耍约仁褂没? 确命令 make
   重新产生它,也不会有任何事情发生。解决方法是标 明所有的假象目的(用
   .PHONY),这就告诉 make 不用检查它们
   是否存在于磁碟上,也不用查找任何隐含规则,直接假设指定的目
   的需要被更新。在 makefile 里加入下面这行包含上面规则的规则:
   .PHONY : veryclean
   就可以了。注意,这是一个特殊的 make 规则,make 知道 .PHONY
   是一个特殊目的,当然你可以在它的依靠里加入你想用的任何假象 目的,而
   make 知道它们都是假象目的。
   2.6 函数 (Functions)
   makefile 里的函数跟它的变量很相似——使用的时候,你用一个 $
   符号跟开括号,函数名,空格后跟一列由逗号分隔的参数,最后
   用关括号结束。例如,在 GNU Make 里有一个叫 'wildcard' 的函
   数,它有一个参数,功能是展开成一列所有符合由其参数描述的文
   件名,文件间以空格间隔。你可以像下面所示使用这个命令:
   SOURCES = $(wildcard *.c)
   这行会产生一个所有以 '.c' 结尾的文件的列表,然后存入变量 SOURCES
   里。当然你不需要一定要把结果存入一个变量。
   另一个有用的函数是 patsubst ( patten substitude, 匹配替
   换的缩写)函数。它需要3个参数——第一个是一个需要匹配的
   式样,第二个表示用什么来替换它,第三个是一个需要被处理的
   由空格分隔的字列。例如,处理那个竟厦娑ㄒ搴蟮谋淞浚?
   OBJS = $(patsubst %.c,%.o,$(SOURCES))
   这行将处理所有在 SOURCES 字列中的字(一列文件名),如果它的 结尾是
   '.c' ,就用 '.o' 把 '.c' 取代。注意这里的 % 符号将匹
   配一个或多个字符,而它每次所匹配的字串叫做一个‘柄’(stem) 。
   在第二个参数里, % 被解读成用第一参数所匹配的那个柄。
   2.7 一个比较有效的 makefile
   利用我们现在所学的,我们可以建立一个相当有效的 makefile 。 这个
   makefile 可以完成大部分我们需要的依靠检查,不用做太大
   的改变就可直接用在大多数的项目里。
   首先我们需要一个基本的 makefile 来建我们的程序。我们可以让
   它搜索当前目录,找到源码文件,并且假设它们都是属于我们的项
   目的,放进一个叫 SOURCES 的变量。这里如果也包含所有的 *.cc
   文件,也许会更保险,因为源码文件可能是 C++ 码的。
   SOURCES = $(wildcard *.c *.cc)
   利用 patsubst ,我们可以由源码文件名产生目标文件名,我们需
   要编译出这些目标文件。如果我们的源码文件既有 .c 文件,也有 .cc
   文件,我们需要使用相嵌的 patsubst 函数呼叫:
   OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCES)))
   最里面一层 patsubst 的呼叫会对 .cc 文件进行后缀替代,产生的结
   果被外层的 patsubst 呼叫处理,进行对 .c 文件后缀的替代。
   现在我们可以设立一个规则来建可执行文件:
   myprog : $(OBJS)
     gcc -o myprog $(OBJS)
   进一步的规则不一定需要, gcc 已局涝趺慈ド赡勘晡募? (object files)
   。下面我们可以设定产生依靠信息的规则:
   depends : $(SOURCES)
     gcc -M $(SOURCES) > depends
   在这里如果一个叫 'depends' 的文件不存在,或任何一个源码文件
   比一个已存在的 depends 文件新,那么一个 depends 文件会被生 成。depends
   文件将会含有由 gcc 产生的关于源码文件的规则(注 意 -M
   开关)。现在我们要让 make 把这些规则当做 makefile 档
   的一部分。这里使用的技巧很像 C 语言中的 #include 系统——我 们要求
   make 把这个文件 include 到 makefile 里,如下:
   include depends
   GNU Make 看到这个,检查 'depends' 目的是否更新了,如果没有,
   它用我们给它的命令重新产生 depends 档。然后它会把这组(新)
   规则包含进来,继续处理最终目标 'myprog' 。当看到有关 myprog
   的规则,它会检查所有的目标文件是否更新——利用 depends 文件
   里的规则,当然这些规则现在已臼歉鹿牧恕?
   这个系统其实效率很低,因为每当一个源码文件被改动,所有的源码
   文件都要被预处理以产生一个新的 'depends' 文件。而且它也不是 100%
   的安全,这是因为当一个 header 档被改动,依靠信息并不会
   被更新。但就基本工作来说,它也算相当有用的了。

--

           执子之手,与子谐老。

※ 来源:.一网深情 bbs.uestc.edu.cn.[FROM: 202.115.16.2]
--
※ 转寄:.一网深情 bbs.uestc.edu.cn.[FROM: 210.39.3.50]
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.11]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店