我们的工程有 8 个 C 文件,和 3 个头文件,
我们要写一个 Makefile 来告诉 make 命令如何编译和链接这几个文件。我们的规则是:
1)如果这个工程没有编译过,那么我们的所有 C 文件都要编译并被链接。
2)如果这个工程的某几个 C 文件被修改,那么我们只编译被修改的 C 文件,并链接目
标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的 C 文件,
并链接目标程序。

在讲述这个 Makefile 之前,还是让我们先来粗略地看一看 Makefile 的规则。

target ... : prerequisites ...
command
...
...
target 也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是
一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites 就是,要生成那个 target 所需要的文件或是目标。
command 也就是 make 需要执行的命令。(任意的 Shell 命令)

让 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 \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
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 buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
-rm edit $(objects)
这种方法,也就是 make 的“隐晦规则”。上面文件内容中,
“.PHONY”表示,clean 是个
伪目标文件。.PHONY 意思表示 clean 是一个“伪目标”,。而在 rm 命令前面加了一个小减号
的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。当然,clean 的规则不
要放在文件的开头,不然,这就会变成 make 的默认目标,相信谁也不愿意这样。不成文的
规矩是——“clean 从来都是放在文件的最后”

四、环境变量 MAKEFILES
如果你的当前环境中定义了环境变量 MAKEFILES,那么,make 会把这个变量中的值做一个
类似于 include 的动作。这个变量中的值是其它的 Makefile,用空格分隔。只是,它和
include 不同的是,从这个环境变中引入的 Makefile 的“目标”不会起作用,如果环境
变量中定义的文件发现错误,make 也会不理。
但是在这里我还是建议不要使用这个环境变量,因为只要这个变量一被定义,那么当你使用
make 时,所有的 Makefile 都会受到它的影响,这绝不是你想看到的。在这里提这个事,
只是为了告诉大家,也许有时候你的 Makefile 出现了怪事,那么你可以看看当前环境中有
没有定义这个变量。

五、make 的工作方式
GNU 的 make 工作时的执行步骤入下:(想来其它的 make 也是类似)
1、读入所有的 Makefile。
2、读入被 include 的其它 Makefile。
3、初始化文件中的变量。
4、推导隐晦规则,并分析所有规则。
5、为所有的目标文件创建依赖关系链。
6、根据依赖关系,决定哪些目标要重新生成。
7、执行生成命令。

1-5 步为第一个阶段,6-7 为第二个阶段。第一个阶段中,如果定义的变量被使用了,那么,
make 会把其展开在使用的位置。但 make 并不会完全马上展开,make 使用的是拖延战术,
如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部
展开。

第五章
书写规则
规则包含两个部分,一个是依赖关系,一个是生成目标的方法。
在 Makefile 中,规则的顺序是很重要的,因为,Makefile 中只应该有一个最终目标,其
它的目标都是被这个目标所连带出来的,所以一定要让 make 知道你的最终目标是什么。一
般来说,定义在 Makefile 中的目标可能会有很多,但是第一条规则中的目标将被确立为最
终的目标。如果第一条规则中的目标有很多个,那么,第一个目标会成为最终的目标。make
所完成的也就是这个目标。

makefile_2的更多相关文章

  1. 4通用Makefile编写

    a.c #include<stdio.h> #include "a.h" int main() { printf("hello world\n"); ...

随机推荐

  1. ZOJ 3430 Detect the Virus

    传送门: Detect the Virus                                                                                ...

  2. 深入浅出MySQL双向复制技术

    设置MySQL数据同步(单向&双向)由于公司的业务需求,需要网通和电信的数据同步,就做了个MySQL的双向同步,记下过程,以后用得到再翻出来,也贴出来供大家参考. 一.准备服务器 由于MySQ ...

  3. httpd设置HTTPS双向认证

    去年用tomcat.jboss配置过HTTPS双向认证,那时候主要用的是JDK自带的keytool工具.这次是用httpd + openssl,区别比较大 在网上搜索了很多文章,发现全面介绍的不多,或 ...

  4. Protocol Buffer技术详解(C++实例)

    Protocol Buffer技术详解(C++实例) 这篇Blog仍然是以Google的官方文档为主线,代码实例则完全取自于我们正在开发的一个Demo项目,通过前一段时间的尝试,感觉这种结合的方式比较 ...

  5. ALTER 语句修改数据表

    1.修改数据表名:alter table 表名 rename 新表名; 2.修改列名: alter table 表名 change 列名 新列名(可以与旧的一样) 类型 默认值; 3.修改类型: al ...

  6. 使用spring集成hibernate

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  7. 使用SqlSessionTemplate实现数据库的操作

    EmployeeMapper.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE map ...

  8. 如何在windows中编写R程序包(转载)

    网上有不少R包的编译过程介绍,挑选了一篇比较详细的,做了稍许修改后转载至此,与大家分享 如何在windows中编写R程序包 created by helixcn modified by binaryf ...

  9. Spring3中的mvc:interceptors标签配置拦截器

    mvc:interceptors 这个标签用于注册一个自定义拦截器或者是WebRequestInterceptors. 可以通过定义URL来进行路径请求拦截,可以做到较为细粒度的拦截控制. 例如在配置 ...

  10. Don't make me think 摘录与读后感

    别让我思考 ——Krug可用性第一定律 点击多少次都没关系,只要每次点击都是无需思考,明确无误的选择.——Krug可用性第二定律 去掉每个页面上一般的文字, 然后把剩下的文字再去掉一半 ——Krug可 ...