Makefile入门详解

article/2025/10/2 19:39:25

文章目录

  • 一、Makefile简介
  • 二、makefile 原理
    • 1、当有依赖文件不存在
    • 2、当所有依赖文件存在
  • 三、makefile基本规则
    • 1.makefile规则三要素
    • 2.基本规则
    • 3、makfile中的变量
      • 3.1普通变量
      • 3.2自动变量
      • 3.3例程
    • 4、makefile中的伪目标
  • 四、makefile其他常用的规则
  • 五、makefile中的函数
    • 5.1函数 subst
    • 5.2函数 patsubst
    • 5.3函数 dir
    • 5.4函数 notdir
    • 5.5函数 foreach
    • 5.6函数 wildcard
  • 六、综合例程

提示:以下是本篇文章正文内容,下面案例可供参考

一、Makefile简介

makefile主要使用在没有集成开发环境时,对工程文件进行自动化编译的工具。

makefile 的本质是一个文件,需要配合make指令进行自动化编译。

make是一个命令工具,用来解释makefile文件中的代码,从而实现自动化编译。编译使用的编译器本质上还是gcc。

makefile文件中定义了一系列的规则来指定, 哪些文件需要先编译, 哪些文件需要后编译, 哪些文件需要重新编译, 甚至于进行更复杂的功能操作。

makefile文件的命名:makefile或者Makefile。(也可通过其他方式,不使用这两个名字,通常我们使用这两个即可)

二、makefile 原理

基本原理:若想生成目标, 检查规则中的所有的依赖文件是否都存在。

1、当有依赖文件不存在

  1. 如果有的依赖文件不存在, 则向下搜索规则, 看是否有生成该依赖文件的规则:
  2. 如果有规则用来生成该依赖文件,则执行规则中的命令生成依赖文件;
  3. 如果没有规则用来生成该依赖文件, 则报错

也就是如下图所示:
在这里插入图片描述

2、当所有依赖文件存在

如果所有依赖都存在, 检查规则中的目标是否需要更新, 必须先检查它的所有依赖,依赖中有任何一个被更新, 则目标必须更新.(检查的规则是哪个时间大哪个最新)

如下图所示:
在这里插入图片描述

三、makefile基本规则

1.makefile规则三要素

  1. 目标: 要生成的目标文件
  2. 依赖: 目标文件由哪些文件生成
  3. 命令: 通过执行该命令由依赖文件生成目标

2.基本规则

规则如下:

目标:依赖命令		#注意命令需要以tab键开始
main:main.c test.cgcc main.c test.c -o main

3、makfile中的变量

makefile中使用变量有点类似于C语言中的宏定义, 使用该变量相当于内容替换, 使用变量可以使makefile易于维护, 修改起来变得简单。
makefile中有三种变量:

  1. 普通变量
  2. 自动变量
  3. 自带变量(不太了解)

3.1普通变量

变量定义是用 = 号即可,例如:

OBJS = main					//定义并赋值(通常不这样使用),会配合: 进行使用,后面会详解
$(OBJS)						//使用变量

3.2自动变量

自动变量主要有,如下所示:

  1. $@: 规则中的目标集合,在模式规则中,如果有多个目标的话,“ $@”表示匹配模式中定义的目标集合。
  2. $<:依赖文件集合中的第一个文件,如果依赖文件是以模式(即“ %” )定义的,那么“ $<”就是符合模式的一系列的文件集合
  3. $^:所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,会去除重复的依赖文件,只保留一份。
  4. $%:当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件,那么其值为空。
  5. $?:所有比目标新的依赖目标集合,以空格分开。
  6. $+:和“ $^”类似,但是当依赖文件存在重复的话不会去除重复的依赖文件。

3.3例程

CC := gcc #arm-linux-gnueabihf-gcc
TARGET := main
object := main.o test.o.PHONY : clean$(TARGET):$(object)$(CC) -o $@ $^
%.o:%.c$(CC) -o -c $@ $<
clean:rm main main.o test.o #rm main %.o

上面就是一个简单的makefile文件

4、makefile中的伪目标

Makefile 有一种特殊的目标——伪目标,一般的目标名都是要生成的文件,而伪目标不代表真正的目标名,在执行 make 命令的时候通过指定这个伪目标来执行其所在规则的定义的命令。

注意:使用伪目标的主要是为了避免 Makefile 中定义的只执行命令的目标和工作目录下的实际文件出现名字冲突

上面例程中使用的伪目标clean,是用来清理编译产生的文件。

四、makefile其他常用的规则

  1. := :一个变量在定义并赋值后,不会使用后面给该变量赋值的值,只能使用前面已经定义好的
  2. ?= :如果该变量在前面没有被赋值,就给该变量赋值。如果赋值过了,就使用之前赋值的值
  3. += :需要给前面已经定义好的变量添加一些字符串进去,类似x +=1;
  4. %:类似通配符,例:%.c,也就是以 .c 结尾的所有文件
  5. \:是makefile中行的分隔符。

五、makefile中的函数

注意:此处只说下面综合例程中使用的函数和常用的函数

5.1函数 subst

函数作用:完成字符串的替换操作。
调用形式如下:

$(subst <from>,<to>,<text>)
#from:字符串中被替换的字符串
#to:替换的字符串
#text:字符串#举例
$(subst aaa,AAA,aaabbb)
#也就是将字符串aaa替换成AAA,替换后字符串为AAAbbb

5.2函数 patsubst

函数作用:用来完成模式字符串替换
调用形式如下:

$(patsubst <pattern>,<replacement>,<text>)$(patsubst %.c,%.o,a.c b.c c.c)
#将字符串“ a.c b.c c.c”中的所有符合“ %.c”的字符串,替换为“ %.o”,替换完成以后的字符串为“ a.o b.o c.o”

5.3函数 dir

函数作用: 用来获取目录
调用形式如下:

$(dir <names…>)$(dir </src/a.c>)
#提取文件“ /src/a.c”的目录部分,也就是“ /src”

5.4函数 notdir

函数作用:除文件中的目录部分,提取文件名
调用形式如下:

$(notdir <names…>)$(notdir </src/a.c>)
#提取文件“ /src/a.c”中的非目录部分,也就是文件名“ a.c”。

5.5函数 foreach

函数作用:函数用来完成循环
调用形式如下:

$(foreach <var>, <list>,<text>)
#把参数<list>中的单词逐一取出来放到参数<var>中,然后再执行<text>所包含的表达式。每次<text>都会返回一个字符串,循环的过程中,
# <text>中所包含的每个字符串会以空格隔开,最后当整个循环结束时, <text>所返回的每个字符串所组成的整个字符串将会是函数 foreach
# 函数的返回值。

5.6函数 wildcard

函数作用:通配符“ %”只能用在规则中,只有在规则中它才会展开,如果在变量定义和函数使用时,通配符不会自动展开,这个时候就要用到函数 wildcard
调用形式如下:

$(wildcard PATTERN…)$(wildcard *.c)
#上面的代码是用来获取当前目录下所有的.c 文件,类似“%”

六、综合例程

CROSS_COMPILE	:=	arm-linux-gnueabihf-
TARGET		:=	bspCC 			:=	$(CROSS_COMPILE)gcc
LD			:=	$(CROSS_COMPILE)ld 
OBJCOPY		:=	$(CROSS_COMPILE)objcopy 
OBJDUMP		:=	$(CROSS_COMPILE)objdumpINCDIRS		:=	imx6ul	\bsp/clk		\bsp/delay	\bsp/LEDSRCDIRS		:=	project		\bsp/clk 	\bsp/delay	\bsp/LED 	INCLUDE		:=	$(patsubst %, -I %, $(INCDIRS))#SFILES		:= 	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
SFILES		:=	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES		:=	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))SFILENDIR	:=	$(notdir $(SFILES))
CFILENDIR	:=	$(notdir $(CFILES))SOBJS		:=	$(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS		:=	$(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS		:=	$(SOBJS) $(COBJS)VPATH		:=	 $(SRCDIRS).PHONY: clean$(TARGET).bin : $(OBJS)$(LD)	-Timx6ul.lds	-o	$(TARGET).elf	$^$(OBJCOPY)	-O 	binary	-S	$(TARGET).elf	$@$(OBJDUMP)	-D	-m	arm	$(TARGET).elf	>	$(TARGET).dis$(SOBJS) : obj/%.o : %.S$(CC)	-Wall	-nostdlib	-c	-O2		$(INCLUDE)	-o		$@ $<$(COBJS) : obj/%.o : %.c$(CC)	-Wall	-nostdlib	-c	-O2		$(INCLUDE)	-o		$@ $<clean:rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)print :@echo	INCLUDE	 =	$(INCLUDE)@echo 	SFILES = $(SFILES)@echo 	CFILES = $(CFILES)@echo 	SFILENDIR	=	$(SFILENDIR)@echo	CFILENDIR	=	$(CFILENDIR)@echo	SOBJS	=	$(SOBJS)@echo	COBJS	=	$(COBJS)@echo	OBJS	=	$(OBJS)

例程中的makefile适用于大型工程管理,只需要添加源文件路径和头文件路径,不需要改动太多的makefile代码,即可实现工程代码的自动化编译。


http://chatgpt.dhexx.cn/article/ktWHdYfe.shtml

相关文章

makefile脚本

文章目录 1.makefile进行工程管理2.文档里面输入的内容3.如何运行这个makefile文件3.makefile 的变量4.其他 1.makefile进行工程管理 先创建一个名称为makefile或者Makefile的文档 2.文档里面输入的内容 输入相应内容的时候&#xff0c;要遵循相应的规则 规则&#xff1a;用…

makefile简介

1.make是一个应用程序 解析源程序之间的依赖关系 根据依赖关系自动维护编译工作 执行宿主操作系统中的各种命令 2.makefile是一个描述文件 定义一系列的规则来指定源文件编译的先后顺序 拥有特定的语法规则&#xff0c;支持函数定义和函数调用 能够直接集成操作系统中的各种命…

makefile变量

1.变量和不同的赋值方式 (1)makefile中支持程序设计语言中变量的概念 (2)makefile中的变量只代表文本数据(字符串) (3)makefile中的变量名规则 变量名可以包含字符&#xff0c;数字&#xff0c;下划线 不能包含“:”&#xff0c;"#"&#xff0c;"“或” " …

Makefile介绍

Makefile 是一种常用于编译的脚本语言&#xff0c;它可以更好更方便的管理你的项目的代码编译&#xff0c;节约编译时间&#xff08;没改动的文件不编译&#xff09;。 注意 Makefile 文件命令必须是 Makefile 或者 makefile&#xff0c;并使用 make 命令编译。 1. 1个…

如何编写一个Makefile文件(手把手的教你)

如果有帮助&#xff0c;希望点赞支持&#xff0c;我会更有创作的动力哦 目录 一、概念理解&#xff08;彩蛋藏在某个地方&#xff09;1.1 什么是Makefile&#xff1f;1.2 为何使用Makefile&#xff1f; 二、实战代码演示与讲解2.1 没有makefile的项目是怎么创建运行的2.1.1 创建…

Makefile入门(超详细一文读懂)

1、Makefile编译过程 Makefile文件中的命令有一定规范&#xff0c;一旦该文件编写好以后在Linux命令行中执行一条make命令即可自动编译整个工程。不同厂家的make可能会稍有不同&#xff0c;并且语法上也有区别&#xff0c;不过基本思想都差不多&#xff0c;主要还是落在目标依赖…

刘玉真先生语录

或问&#xff1a;“古今之法门多矣&#xff0c;何以此教独名‘净明忠孝’ ? ” 先生曰&#xff1a;“别无他说&#xff0c;‘净明’只是正心诚意&#xff0c;‘忠孝’只是扶植纲常。但世人习闻此语&#xff0c;多是忽略过去&#xff0c;此间却务真践实履。” 先生曰&#xff1…

俞敏洪用20年的经验笑谈人生:不要在穷的时候假装崇高

转载于: https://www.huxiu.com/article/174774/1.html 虎嗅注&#xff1a;本文是新东方创始人、洪泰基金联合创始人俞敏洪&#xff0c;于12月1日在麻省理工学院跟学生做的一个主题演讲&#xff0c;言辞幽默&#xff0c;充满智慧&#xff0c;有太多人生的道理。本文由微信公众号…

每日言论:『模仿他人是人生陷阱』

公众号关注 「奇妙的 Linux 世界」 设为「星标」&#xff0c;每天带你玩转 Linux &#xff01; 最近&#xff0c;我们建立了一个技术交流微信群。目前群里已加入了不少行业内的大神&#xff0c;有兴趣的同学可以加入和我们一起交流技术&#xff0c;在 「奇妙的 Linux 世界」 公…

38岁,外企技术经理,失业:职场遇到瓶颈,你可能掉进了“能力陷阱”!

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) 一位读者小R&#xff0c;给我讲述了他的职场经历。 小R&#xff0c;2008年通信专业硕士毕业。先去了华为&#xff0c;做了1年觉得有点苦&#xff0c;就去学了1年英语&#xff0c;后来跳槽到摩托罗拉。…

复旦大学教师 于娟博士《为啥是我得癌症?》

复旦女教师于娟已经去世半年多了&#xff0c;但这篇《为啥是我得癌症&#xff1f;》值得每个人认真阅读。 于娟&#xff0c;女&#xff0c;32岁&#xff0c;祖籍山东济宁&#xff0c;海归&#xff0c;博士&#xff0c;复旦大学优秀青年教师&#xff0c;一个两岁孩子的母亲&a…

《思考致富》不应该指望不经历“暂时的失败”便能发财

目录 作者简介 经典摘录 机遇有个狡猾的习惯&#xff0c;喜欢从后门悄悄溜进来&#xff0c;往往还喜欢以灾难或暂时失败的方式乔装露面 离金矿仅有三英尺远 欲望&#xff1a;成就一切的起点&#xff08;通往致富之路的第一步&#xff09; 信念&#xff1a;在脑海里目睹并坚…

复旦女博士于娟:为啥是我得癌症?

复旦女博士于娟&#xff1a;为啥是我得癌症&#xff1f;【请所有的朋友看看此文】 复旦女教师于娟已经去世半年多了&#xff0c;但这篇《为啥是我得癌症&#xff1f;》值得每个人认真阅读。不要再瞎吃八吃、暴饮暴食、嗜荤如命&#xff0c;不要再拼命工作、天天熬夜&#xff0…

[转载]复旦女博士于娟——为啥是我得癌症? (转)

[转载]复旦女博士于娟——为啥是我得癌症? (转) (2012-07-30 13:47:00) 转载▼ 标签&#xff1a; 转载 黄帝内经之类。就此引用一段话&#xff1a; 下午5--7点酉时 肾经当令 晚上7--9点戌时 心包经当令 9-11点亥时 三焦经当令 11-1点子时 胆经当令 凌晨1--3点丑时 肝经当令 3…

38岁,外企技术经理,失业:职场遇到瓶颈,你可能掉进了“能力陷阱”

一位读者小R&#xff0c;给我讲述了他的职场经历。 小R&#xff0c;2008年通信专业硕士毕业。先去了华为&#xff0c;做了1年觉得有点苦&#xff0c;就去学了1年英语&#xff0c;后来跳槽到摩托罗拉。 呆了12年&#xff0c;自己也熬到了技术经理的岗位。其实&#xff0c;2013年…

于娟《生命日记》——复旦大学教师于娟对大学生健康的建议

下文很长&#xff0c;需要你花点耐心&#xff0c;总结只有一句&#xff1a;珍惜、享受。 “在生死临界点的时候&#xff0c;你会发现&#xff0c;任何的加班&#xff08;长期熬夜等于慢性自杀&#xff09;&#xff0c;给自己太多的压力&#xff0c;买房买车的需求&#xff0c;这…

此生未完成 --- 于娟

文章目录 图书外观好句摘录Part1 病隙日记01 “为啥是我得癌症”的非学术报告02 我的二〇一〇 Part2 人间烟火03 写给我的宝贝04 碎落在身后的时光05 远在天涯06 生为女人 Part3 唯念芳辰07 刹那芳华&#xff1a;于娟的诗 图书外观 好句摘录 Part1 病隙日记 01 “为啥是我得癌…

于娟的忠告----生命只有一次,活着才是王道啊

复旦女教师于娟已经去世半年多了,但这篇《为啥是我得癌症?》值得每个人认真阅读。 于娟,女,32岁,祖籍山东济宁,海归,博士,复旦大学优秀青年教师,一个两岁孩子的母亲,乳腺癌晚期患者。 2009年12月被确诊患上了乳腺癌,2010年1月2日于娟被进一步确诊乳腺癌晚期, 2011年…

于娟的忠告----生命只有一次,活着才是王道啊!!!

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴! 复旦女教师于娟已经去世半年多了,但这篇《为啥是我得癌症?》值得每个人认真阅读。 于…

于娟临终前的忠告(二)

复旦大学女教师于娟已经去世一年多了&#xff0c;但这篇《为啥是我得癌症&#xff1f;》值得每个人认真阅读。 于娟&#xff0c;女&#xff0c;32岁&#xff0c;祖籍山东济宁&#xff0c;海归&#xff0c;博士&#xff0c;复旦大学优秀青年教师&#xff0c;一个两岁孩子的母亲&…