一、为什么使用 makefile?

makefile 带来的好处就是“自动化编译”,一旦写好,只需要一个 make 命令, 整个工程完全自动编译, 极大的提高了软件开发的效率。
同时,makefile 文件中可以定义一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile 就像一个 Shell 脚本一样,其中也可以执行操作系统的命令。

二、makefile 的命名规则

(1)规则:

目标...: 依赖... // 注意:一个 makefile 中可以有多个规则
(tab)命令 // 注意:tab 缩进不能是 4 个空格.....

(2)三要素:
目标:要生成的目标文件。
依赖:目标文件由哪些文件生成。
命令:如何通过执行该命令使依赖文件生成目标文件。

三、makefile 的设计思路

(1) 需求:
1)含有头文件、加减乘除的实现文件、测试 main 文件。
(include 目录包含 head.h 、add.c div.c mul.c sub.c 、main.c) 。
2)将这 3 类文件制作成 makefile 文件,实现自动编译,生成 app 可执行文件。

1、第一版本:最简单

app: add.c div.c mul.c sub.c main.cgcc add.c div.c mul.c sub.c main.c -o app -I include

(1)说明:
目标:app 文件
依赖:用于生成目标(add.c div.c mul.c sub.c main.c)
命令:gcc 编译(-o 指定名称 app 因为有头文件,所以要有 –I)
(2) 缺陷:
改变一个依赖文件(例:只 touch add.c 甚至不改变其内容),所有依赖文件都要重新更新编译

2、第二版本:依赖于.o 文件

app: main.o add.o div.o mul.o sub.ogcc main.o add.o div.o mul.o sub.o -o app

(1) 相较于第一个版本,依赖于.o 文件。
(2) 命令依然是 gcc,区别是由.o 生成 app。
(3)第一个目标(app)称为终极目标。因为终极目标依赖于.o 文件,所以需要依赖于“.c 文件”生成“.o 目标”,因此,有以下内容:

main.o: main.c
gcc -c main.c -I include
add.o: add.c
gcc -c add.c -I include
div.o: div.c
gcc -c div.c -I include
mul.o: mul.c
gcc -c mul.c -I include
sub.o: sub.c
gcc -c sub.c -I include

(4)相较于第一版的好处是改变一个依赖文件,只有 改变的依赖文件和终极目标需要重新生成,其他不动。
(5) 缺陷:
相似代码体太多
(6)铺垫知识:
1)makefile 中的变量:
makefile 中的变量有点类似于 C 语言中的宏定义,使用该变量相当于内容替换,使用变量可以使 makefile 易于维护,修改起来变得简单。
2)变量的分类:普通变量、自动变量
普通变量 (严格区分大小写),定义 key = val 引用 val $(key)。举例 foo = a.o b.o c.o $(foo) 就相当于 a.o b.o c.o
自动变量:特别注意:自动变量只能在规则的命令中使用.
$@ 表示规则中的目标
$< 表示规则中的第一个依赖条件
$^ 表示规则中的所有的依赖条件

3、第三版本: “模式规则”(利用 makefile 变量 和 占位符% 实现)

app: main.o add.o div.o mul.o sub.o
gcc $^ -o $@ // $^ 指所有的.o文件 //$@ 指app ,编译所有的.o文件生成目标,并指定为app
%.o:%.c // % 是占位符
gcc -c $< -o $@ -I include // $< 第一个的.c 文件 ,编译一个.c 文件($<)生成.o 文件($@)

(1)缺陷:
终极目标 app 的依赖是完全定死的,扔到另一个项目中就不能用了,可移植性差。
(2)铺垫知识:makefile 函数(所有的函数都有返回值,我们基本都是需要它的返回值)
1)wildcard :查找指定目录下的指定类型的文件

src = $(wildcard ./*.c) //找到当前目录下所有后缀为.c 的文件,引用返回值给 src

2)patsubst :匹配替换

obj = $(patsubst %.c , %.o , $(src) ) //把 src 变量里所有后缀为.c 的文件替换成.o ,$(src) == *.c

4、第四版本:利用 makefile 函数

// makefile 函数
src = $(wildcard *.c) // 当前目录下,所有 .c 文件
obj = $(patsubst %.c , %.o , $(src) ) // 当前目录下,所有 以.c 文件生成的.o 文件
// makefile 普通变量
target = app // 如果主体多次使用 app,想修改终极目标,只需要在这里改一次就行了
cc = gcc
// makefile 自动变量(模式规则)
$( target): $(obj)
$(cc) $^ -o $@
%.o:%.c
$(cc) -c $< -o $@ -I include

(1)缺陷:每次重新编译都需要手工清理中间.o 文件和最终目标文件
(2)铺垫知识: clean / make clean
用途:清除编译生成的中间.o 文件和最终目标文件
1)出现的问题:make clean 如果当前目录下有同名 clean 文件,则不执行用于清除的 clean 命令,这时解决方法为:.PHONY:clean(伪目标声明)。
效果:声明伪目标之后, makefile 将不会检查该目标是否存在或者该目标是否需要更新。
2) clean 命令中的特殊符号:
– 此条命令出错,make 也会继续执行后续的命令。如:-rm main.o
rm –f :强制执行,主要解决:如果要删除的文件不存在使用 –f 不会报错。
3)@不显示命令本身,只显示结果。如:@echo clean done
(3)其他:
1)make 默认执行终极目标,可通过“make 目标名”指定要执行的目标,例如 make clean
2)make –f:例如,有 makefile、makefile1,使用 make 命令,默认执行 makefile,若想指定运行makefile1,则 make –f makefile1

5、第五版本:最终版本

// makefile 函数
src = $(wildcard *.c)
obj = $(patsubst %.c , %.o , $(src) )
// makefile 普通变量
target = app
cc = gcc
// makefile 自动变量(模式规则)
$( target): $(obj)$(cc) $^ -o $@
%.o:%.c $(cc) $< -c -I include -o $@
// 清理工作
.PHONY: clean //添加伪目标,防止歧义 // 注意以 “." 开头
clean:rm -f $(target) rm -f $(obj)

四、 makefile 的工作原理

1、目标的生成

若想生成目标,首先检查规则中的所有的依赖文件是否都存在:
如果有的依赖文件不存在, 则向下搜索规则,看是否有生成该依赖文件的规则:
(1)如果有规则用来生成该依赖文件,则执行规则中的命令生成依赖文件,再生成终极目标。
(2)如果没有规则用来生成该依赖文件,则报错
例如:
第一版本:依赖文件.c 都存在,直接生成目标。
第二版本:依赖文件.o 不存在,向下搜索。
有生成该依赖文件的规则(依赖.c 生成目标.o)则也可以生成目标。

2、目标的更新:

如果所有依赖都存在,想要检查规则中的目标是否需要更新,必须先检查它的所有依赖,依赖中有任何一个被更新,则有关目标必须更新。
(1)说明:
第一版本中,一个依赖被更新,所有依赖都更新,然后更新终极目标。
第二版本中,一个依赖被更新,只有该依赖对应的目标更新,然后再更新终极目标。
(2)是否更新的判断方法:看“依赖的最后访问时间”是否晚于“目标的最后访问时间”。
依赖的最后访问时间 < 目标的最后生成时间 早于 不更新。
依赖的最后访问时间 > 目标的最后生成时间 晚于 更新。

Linux学习:makefile介绍相关推荐

  1. Linux学习-01-Linux介绍

    1 Linux简介 1.1 操作系统介绍 操作系统(Operating System,OS):也是软件的一种,是硬件基础上的第一层软件,位于硬件和应用程序之间的底层的软件,是硬件和其它软件沟通的桥梁( ...

  2. linux下Makefile学习--注释很好

    什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都 为你做了这个工作,但我觉得要作一个好的和 professional的程序员,makefile还 ...

  3. linux添加自己的库,Linux学习笔记——例叙makefile 增加自定义共享库

    Linux学习笔记--例说makefile 增加自定义共享库 0.前言 从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己 ...

  4. Linux学习笔记 文件服务Vsftp详细介绍

    Linux学习笔记 文件服务Vsftp详细介绍 知识点: 1.FTP使用TCP连接和TCP端口 2.在进行通信时,FTP需要建立两个TCP连接: 一个用于控制信息,TCP端口号缺省为21 一个用于数据 ...

  5. Linux学习笔记之——Linux系统内部相关介绍

    Linux学习笔记之--Linux系统内部相关介绍 摘要:主要记录一些比较有用的能够帮助理解和使用Linux的知识.比如一些相关概念.没兴趣的看看就好.知道有这么个东西.注意事项.和一些常用目录的作用 ...

  6. 我的Linux学习记录(蓝桥)————入门环境介绍

    我的Linux学习之旅(蓝桥) 嘿,首先让我们看看Linux的页面: 差不多长这个样,其中呢: 这个玩意就是你windows的这个玩意 这个东西,就是你windows下win+R然后输入cmd跳出来的 ...

  7. linux下makefile

    概述 -- 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都 为你做了这个工作,但我觉得要作一个好的和 professional的程序员,mak ...

  8. linux 内核 企鹅,Linux 内核 Makefile 体系简单分析

    众所周知,Linux内核是使用make命令来配置并编译的,那必然少不了Makefile.在内核目录树中我们可以看到内核编译系统的顶层Makefile文件.但是如此复杂.庞大的内核源码绝不可能使用一个或 ...

  9. Linux学习笔记 驱动开发篇

    ARM Linux 驱动开发篇 本篇我们将会详细讲解 Linux 中的三大类驱动:字符设备驱动.块设备驱动和网络设备驱动. 字符设备最多,从最简单的点灯到 I2C.SPI.音频等都属于字符设备驱动的类 ...

  10. linux 学习之路

    很多同学接触Linux不多,对Linux平台的开发更是一无所知. 而现在的趋势越来越表明,作为一个优秀的软件开发人员,或计算机IT行业从业人员, 掌握Linux是一种很重要的谋生资源与手段. 下来我将 ...

最新文章

  1. dockefile nginx php,dockerfile自动部署nginx+php7
  2. 微信拦截URL,使用自己内置的web组件打开URL,为什么没人声讨?
  3. 如果要和外国人做项目,加入一个teams是第一步,就跟我们的企业微信,钉钉差不多
  4. win32程序启用控制台-- 调试输出
  5. Linux命令学习(三):文件操作命令(1)
  6. STL--lower_bound()upper_bound();
  7. 如何使用Angular rxjs进行优雅限流
  8. Java中的迭代与递归
  9. sha256加密_有加密传输数据的需求?来试试stunnel
  10. bat 调用class文件_[Golang实现JVM第五篇]静态方法调用的实现
  11. 普中科技51单片机_【笔记】-普中科技-51单片机-按键
  12. 诺基亚n8系统更新服务器模式,新年新版本 诺基亚N8最新固件PR1.1亮相
  13. 汤国安:GIS教育可能要崩盘
  14. 惠普电脑u盘重装系统步骤_惠普电脑怎么用u盘重装系统步骤
  15. 迅雷离线下载脚本 — LinuxTOY
  16. CVPR 2022 Oral|PoseConv3D开源: 基于人体姿态的动作识别新范式
  17. 由“微博”的发展史预测“轻博客”的命途
  18. 项目review会议的步骤_8个步骤,使您的下一次会议更有效率
  19. linux如何设置开启在指定的tty下自启动程序
  20. windos 为什么会突然服务停止了_Win7系统print spooler服务总是自动停止怎么办?

热门文章

  1. 来试试读论文的新神器!AMiner发布“论文背景文献”一键生成工具,帮你搞清一篇论文的“来龙去脉”...
  2. ACL 2018论文解读 | 基于路径的实体图关系抽取模型
  3. python怎么批量处理数据的优点_Python数据处理干货,一文带你深入理解pandas的批量处理方式...
  4. ceph-deploy mod add_GTA5 1.50NPC自杀 MOD [支持1.411.50版本] 覆盖版【5.19MB】
  5. java的jbutton啥意思,Jbutton和Jpanel和JFrame之间的区别?
  6. jmeter mysql 连接复用_JMeter 连接MySQL
  7. 使用回溯算法分析八皇后问题
  8. 「中间件系列一」kafka消息中间件
  9. 微服务架构下的安全认证与鉴权
  10. 牛客题霸 NC30 数组中未出现的最小正整数