Makefile自学
MakeFile的规则
- 如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
- 如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
- 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
makefile文件定义的规则如下:
target... : prerequisites ...
command
- target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。
- prerequisites就是,要生成那个target所需要的文件或是目标。
- command也就是make需要执行的命令。(任意的Shell命令)。
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。
make是如何工作的?
在默认的方式下,也就是我们只输入make命令。那么,会进行如下的步骤:
- make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
- 如果找到,它会找文件中的第一个目标文件(target),并把这个文件作为最终的目标文件。
- 如果第一个目标文件不存在,或是它所依赖的后面的 .o 文件的文件修改时间要比这个文件新,那么,他就会执行后面所定义的命令来生成这个文件。
- 如果目标文件所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
- 当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件声明make的终极任务,也就是执行文件了。
如下一个makefile样例:
反斜杠(\)是换行符的意思。这样比较便于Makefile的易读。我们可以把这个内容保存在文件为“Makefile”或“makefile”的文件中,然后在该目录下直接输入命令“make”就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make clean”就可以了。
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 \
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 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
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 kbd.o command.o display.o \
insert.o search.o files.o utils.o
在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。
这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。
makefile中使用变量
我们在makefile一开始就这样定义:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
于是,我们就可以很方便地在我们的makefile中以“$(objects)”的方式来使用这个变量了,于是我们的改良版makefile就变成下面这个样子:
objects = main.o kbd.o command.o display.o \
insert.osearch.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
......
于是如果有新的 .o 文件加入,我们只需简单地修改一下 objects 变量就可以了。
让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)
那么多的重复的[.h],能不能把其收拢起来?看以下新的文件
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o edit : $(objects)
cc -o edit $(objects) $(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h .PHONY : clean
clean :
rm edit $(objects)
这种风格,让我们的makefile变得很简单,但我们的文件依赖关系就显得有点凌乱了。
今天就先学这么多。
参考自:http://blog.csdn.net/ruglcc/article/details/7814546/
Makefile自学的更多相关文章
- Makefile总结和反序字符数组,整体右移数组,杨辉三角!
2015.1.23今天我值日 继续接着昨天Makefile的目标开始记录:第一种:有 .PHNOY声明,但是冒号后面没有依赖文件.PHNOY:clean clean://没有依赖文件 rm *.0 t ...
- 转来的 cuda makefile 写法学习
原文作者:FreeAquar 原文出处:http://www.cnblogs.com/FreeAquar/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给 ...
- Linux 编程学习笔记----动笔makefile档
Befroe Beginning. 在设置暑假的plan ,关于Linux的书籍如今在看的是ALP和Linux高级程序设计(杨宗德)第三版.在计划中的是Linux高级环境编程. 如今開始关于Linux ...
- 自学Linux Shell9.4-基于Red Hat系统工具包存在两种方式之二:源码包
点击返回 自学Linux命令行与Shell脚本之路 9.4-基于Red Hat系统工具包存在两种方式之二:源码包 本节主要介绍基于Red Had的系统(测试系统centos) 1. 工具包存在两种方式 ...
- Linux应用开发自学之路
前言 在 「关于我 」那篇博文里,朋友们应该知道了我不是科班出身,是由机械强行转行到Linux应用开发方向.下面我就详细向大家介绍自己这一路上的转行历程,希望对大家有所启发. 我是学机械专业的,对于机 ...
- vi, Java, Ant, Junit自学报告 - 实训week1
vi, Java, Ant, Junit自学报告 2017软件工程实训 15331023 陈康怡 vi Vi是linux系统的标准文本编辑器,采用指令的方式进行操作,此处仅记录部分常用的指令. vi模 ...
- 说说Makefile那些事儿
说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...
- 从零自学Hadoop(22):HBase协处理器
阅读目录 序 介绍 Observer操作 示例下载 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,Sour ...
- 编写一个通用的Makefile文件
1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...
随机推荐
- node的应用场景
I/O密集型 I/O密集的优势主要在于Node利用事件循环的处理能力,而不是启动每一个线程为每一个请求服务,资源占用极少. 是否不擅长CPU密集型业务 换一个角度,在CPU密集的应用场景中,Node是 ...
- Python文件格式 .py .pyc .pyw .pyo .pyd的主要区别
Python是一种面向对象.解释型计算机程序设计语言.Python 语法简洁.清晰,具有丰富和强大的类库.Python源代码遵循 GPL (GNU General Public License) 协议 ...
- 后端视角下的前端框架之Vue.js初探
背景 作为常年搞后端的自己来说,除了多年前学习的一点关于HTML的皮毛,对现在的前端技术栈可谓是一窍不通.但是因为最近在做的内部业务全链路监控系统,负责前端的同事做到一半去搞别的项目了,为了把项目落地 ...
- springmvc 开发流程图
- redis批量灌库
需求:将批量数据灌入redis中 如果通过代码形式将数据灌入redis中,效率比较低,以下将根据redis的特性进行快速的批量灌库 环境:centos7 将数据整理成规定格式的文件,比如: SET k ...
- Maven - <Profile>详解
转载自:https://www.cnblogs.com/wxgblogs/p/6696229.html Profile能让你为一个特殊的环境自定义一个特殊的构建:profile使得不同环境间构建的可移 ...
- Java基础11-List;Set;Map
作业解析: remove(int index); //删除指定位置的元素 List list = new ArrayList(); list.add("s1"); list.add ...
- 小程序如何传数组数据到vs后台中
首先小程序要跟vs运行的状态打通,首先要修改配置,也就是说调试的时候,小程序一使用Post请求后台的方法时就能让vs进入调试状态. 1.修改vs中的配置,注意这个.vs文件,如图: 找到这个文件 然后 ...
- 20175226 2018-2019-2《java程序设计》结对编程-四则运算(第一周-阶段总结)
结对编程-四则运算(第一周-阶段总结) 需求分析 实现一个四则运算程序,要求: 自动随机生成小学四则运算题目(加,减,乘,除) 支持整数.真分数且支持多项式 能够利用栈的思想,将中缀转换为后缀表达式 ...
- JAVA 导包,使用前面的类~
package Code413;/*1.导包,也就是指出需要使用的类,在什么位置import 包名称,类名称对于与当前同类属于同一个包的情况,可以省略导包语句不写..2.创建,格式:类名称 对象名=n ...