荔园在线

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

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


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

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


   2) GNU Make 工具
   ~~~~~~~~~~~~~~~~
   2.1 基本 makefile 结构
       GNU Make 的主要工作是读进一个文本文件, makefile 。这个文
       件里主要是有关哪些文件(‘target’目的文件)是从哪些别的
       文件(‘dependencies’依靠文件)中产生的,用什么命令来进行
       这个产生过程。有了这些信息, make 会检查磁碟上的文件,如果
       目的文件的时间戳(该文件生成或被改动时的时间)比至少它的一
       个依靠文件旧的话, make 就执行相应的命令,以便更新目的文件。
       (目的文件不一定是最后的可执行档,它可以是任何一个文件。)
       makefile 一般被叫做“makefile”或“Makefile”。当然你可以 在 make
       的命令行指定别的文件名。如果你不特别指定,它会寻
       找“makefile”或“Makefile”,因此使用这两个名字是最简单 的。
       一个 makefile 主要含有一系列的规则,如下:
       : ...
       (tab)<command>
       (tab)<command>
       .
       .
       .
       例如,考虑以下的 makefile :
       === makefile 开始 ===
       myprog : foo.o bar.o
         gcc foo.o bar.o -o myprog
       foo.o : foo.c foo.h bar.h
         gcc -c foo.c -o foo.o
       bar.o : bar.c bar.h
         gcc -c bar.c -o bar.o
       === makefile 结束 ===
       这是一个非常基本的 makefile —— make 从最上面开始,把上
       面第一个目的,‘myprog’,做为它的主要目标(一个它需要保
       证其总是最新的最终目标)。给出的规则说明只要文件‘myprog’
       比文件‘foo.o’或‘bar.o’中的任何一个旧,下一行的命令将
       会被执行。
       但是,在检查文件 foo.o 和 bar.o 的时间戳之前,它会往下查 找那些把
       foo.o 或 bar.o 做为目标文件的规则。它找到的关于 foo.o
       的规则,该文件的依靠文件是 foo.c, foo.h 和 bar.h 。
       它从下面再找不到生成这些依靠文件的规则,它就开始检查磁碟
       上这些依靠文件的时间戳。如果这些文件中任何一个的时间戳比 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 文件),进而可执行文件被重新连接(因为 .o
       文件被改变了)。其实真正的得益是在当你改变一个 header
       档的时候——你不再需要记住那个源码文件依靠它,因为所有的 资料都在
       makefile 里。 make 会很轻松的替你重新编译所有那 些因依靠这个
       header 文件而改变了的源码文件,如有需要,再 进行重新连接。
       当然,你要确定你在 makefile 中所写的规则是正确无误的,只
       列出那些在源码文件中被 #include 的 header 档
       2.2 编写 make 规则 (Rules)
       最明显的(也是最简单的)编写规则的方法是一个一个的查
       看源码文件,把它们的目标文件做为目的,而C源码文件和被它 #include
       的 header 档做为依靠文件。但是你也要把其它被这些 header 档
       #include 的 header 档也列为依靠文件,还有那些被
       包括的文件所包括的文件 然后你会发现要对越来越多的文件
       进行管理,然后你的头发开始脱落,你的脾气开始变坏,你的脸
       色变成菜色,你走在路上开始跟电线杆子碰撞,终于你捣毁你的
       电脑显示器,停止编程。到低有没有些容易点儿的方法呢?
       当然有!向编译器要!在编译每一个源码文件的时候,它实在应
       该知道应该包括什么样的 header 档。使用 gcc 的时候,用 -M
       开关,它会为每一个你给它的C文件输出一个规则,把目标文件
       做为目的,而这个C文件和所有应该被 #include 的 header 文
       件将做为依靠文件。注意这个规则会加入所有 header 文件,包
       括被角括号(`<', `>')和双引号(`"')所包围的文件。其实我们可以
       相当肯定系统 header 档(比如 stdio.h, stdlib.h 等等)不会
       被我们更改,如果你用 -MM 来代替 -M 传递给 gcc,那些用角括 号包围的
       header 档将不会被包括。(这会节省一些编译时间)
       由 gcc 输出的规则不会含有命令部分;你可以自己写入你的命令
       或者什么也不写,而让 make 使用它的隐含的规则(参考下面的 2.4
       节)。
       2.3 Makefile 变量
       上面提到 makefiles 里主要包含一些规则。它们包含的其它的东
       西是变量定义。
       makefile 里的变量就像一个环境变量(environment variable)。
                                                        Linux迷之家 (p15 of 31)
       事实上,环境变量在 make 过程中被解释成 make 的变量。这些
       变量是大小写敏感的,一般使用大写字母。它们可以从几乎任何
       地方被引用,也可以被用来做很多事情,比如:

   i) 贮存一个文件名列表。在上面的例子里,生成可执行文件的
       规则包含一些目标文件名做为依靠。在这个规则的命令行
       里同样的那些文件被输送给 gcc 做为命令参数。如果在这
       里使用一个变数来贮存所有的目标文件名,加入新的目标
       文件会变的简单而且较不易出错。
       ii) 贮存可执行文件名。如果你的项目被用在一个非 gcc 的系
       统里,或者如果你想使用一个不同的编译器,你必须将所
       有使用编译器的地方改成用新的编译器名。但是如果使用一
       个变量来代替编译器名,那么你只需要改变一个地方,其
       它所有地方的命令名就都改变了。
       iii) 贮存编译器旗标。假设你想给你所有的编译命令传递一组
       相同的选项(例如 -Wall -O -g);如果你把这组选项存
       入一个变量,那么你可以把这个变量放在所有呼叫编译器
       的地方。而当你要改变选项的时候,你只需在一个地方改
       变这个变量的内容。

   要设定一个变量,你只要在一行的开始写下这个变量的名字,后 面跟一个 =
   号,后面跟你要设定的这个变量的值。以后你要引用 这个变量,写一个 $
   符号,后面是围在括号里的变量名。比如在 下面,我们把前面的 makefile
   利用变量重写一遍:
   === makefile 开始 ===
   OBJS = foo.o bar.o
   CC = gcc
   CFLAGS = -Wall -O -g
   myprog : $(OBJS)
     $(CC) $(OBJS) -o myprog
   foo.o : foo.c foo.h bar.h
     $(CC) $(CFLAGS) -c foo.c -o foo.o
   bar.o : bar.c bar.h
     $(CC) $(CFLAGS) -c bar.c -o bar.o
   === makefile 结束 ===
   还有一些设定好的内部变量,它们根据每一个规则内容定义。三个
   比较有用的变量是 $@, $< 和 $^ (这些变量不需要括号括住)。 $@
   扩展成当前规则的目的文件名, $< 扩展成依靠列表中的第 一个依靠文件,而
   $^ 扩展成整个依靠的列表(除掉了里面所有重
   复的文件名)。利用这些变量,我们可以把上面的 makefile 写成:
   === makefile 开始 ===
   OBJS = foo.o bar.o
   CC = gcc
   CFLAGS = -Wall -O -g
   myprog : $(OBJS)
     $(CC) $^ -o $@
   foo.o : foo.c foo.h bar.h
     $(CC) $(CFLAGS) -c $< -o $@
   bar.o : bar.c bar.h
     $(CC) $(CFLAGS) -c $< -o $@
   === makefile 结束 ===
   你可以用变量做许多其它的事情,特别是当你把它们和函数混合
   使用的时候。如果需要更进一步的了解,请参考 GNU Make 手册。 ('man
   make', 'man makefile')

--

           执子之手,与子谐老。

※ 来源:.一网深情 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软件 网络书店