Makefile 第六章 makefile的一个示例
正如前面所说的,如果一个工程有3个头文件,和8个c文件,我们为了完成前面所述的那三个规则,我们的makefile应该是下面的这个样子的。
先回顾一下前文提到的规则:
target ... : prerequisites ...
command
...
...
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
反斜杠(\)是换行符的意思。这样比较便于makefile的易读。
我们可以把这个内容保存在名字为“makefile”或“Makefile” 的文件中,然后在该目录下直接输入命令“make”就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下 “make clean”就可以了。
在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。
在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个tab键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。
这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像c语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找它的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。
原文地址:https://www.cnblogs.com/vx-cg248805770/p/11647594.html
- c++课程设计(日历)
- 一个程序,让你理解运算符重载操作
- HDUOJ ---1423 Greatest Common Increasing Subsequence(LCS)
- 在运算符重载++,--,+=,-=...
- 排序一栏(总结帖)
- 编程思想 之「异常及错误处理」
- nyoj-----284坦克大战(带权值的图搜索)
- nyoj-----42一笔画问题
- hdu-------1081To The Max
- nyoj------170网络的可靠性
- HDUOJ-------1052Tian Ji -- The Horse Racing(田忌赛马)
- 初学Java之Pattern与Matcher类
- 初学java之StringBuffer类的常用方法
- 初学java之大数处理
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring 数据初始 H2 后进行数据查询提示 Schema not found 错误
- Discourse CentOS 8 全新安装手册
- H2 数据库插入时间的方法
- Spring 配置的 H2 控制台 frameOptions 导致无法访问
- Spring Boot 和 Hibernate 的 H2 数据库配置来进行启动测试
- Java时间处理-LocalDateTime简介
- iOS音视频接入 - TRTC iOS端真机日志导出
- jQuery根据填写的input的数值导出excel表格
- 小程序根据返回值英文渲染出对应的中文
- 小程序返回的时间戳转化成时间
- 小程序使用 组件库 vant-weapp详细教程
- 小程序数据渲染根据返回值计算百分比并且显示
- JS获取当前系统时间戳的方法
- TensorFlow 2建立神经网络分类模型——以iris数据为例
- 突击并发编程JUC系列-阻塞队列 BlockingQueue