引言
随着嵌入式技术的飞速发展,从 STM32 到 Linux 驱动开发的跨越成为热门趋势。这不仅拓宽了开发者的视野,也推动了硬件与软件的深度融合,为智能设备的创新注入了强大动力。
Makefile简介
Makefile 是一种用于自动化编译和构建项目的工具配置文件。它通过定义目标文件、依赖关系和生成目标的命令,帮助开发者高效地管理项目构建过程。当项目文件发生变化时,Makefile 能自动识别并仅重新编译受影响的部分,节省时间和精力。
Makefile三要素包括目标,依赖和命令。我是这么理解的,目标,就是我们需要实现的功能;依赖就是我们实现功能中所依赖的东西;命令自然就是为实现功能而执行的命令。
Makefile变量
1,系统变量
echo "(CC)" 、 echo "(AS)" 和 echo "$(MAKE)" 是三个命令,它们分别打印出变量 CC 、 AS 和 MAKE 的值。这些变量通常在Makefile中定义,用于指定编译器、汇编器和make工具本身。
2,自定义变量
首先是'=',注意,这个=跟我们平时用的等于号是不一样的,平时我们用的'='是直接赋值的形式,而在Makefile中,它是延时赋值的意思。简单理解就是只有当该变量被调用的时候,才会被赋值。如图:

我先给变量A赋值1,然后再创建一个变量B让其等于A变量的值,最后再给A变量重新赋值2。通过Make可以看到,B变量输出的值是等于2不是等于1。这说明这也就可以很好地理解为什么在Makefile中'='是属于延时赋值了。
第二个是':=',这个在Makefile中代表的是立即赋值,跟我们平时的'='是一样的,即立即给变量赋值。如图:

我在刚刚代码的基础上加入':',就可以把延时赋值'='改成了':='立即赋值。图中可以看出,变量A输出的值是第一次给A赋的值,也就是1,而不是输出2。
第三个是'?=',这个在Makefile中代表的是空赋值。简单理解就是只有当变量为空时,变量赋值才有效,如图:

先给变量A空赋值1,再次给变量A赋值2,可以看到,输出的是1,而不是2。因为变量A第一次就被赋值为1,所以第二次赋值2是无效的。
第四个是'+=',这个在Makefile中代表的是追加赋值。顾名思义,就是在原变量的基础上追加数据,如图:

变量A已经被空赋值1后,再给变量A追加赋值2,结果就是输出1和2。
自动化变量
第一个是'$<',这个命令是代表第一个依赖目标。如图:

使用这个'$<'命令打印出来的是targeta,也就是第一个所依赖的文件。
第二个是'$^',这个命令是代表全部依赖目标。如图:

使用'$^'命令,打印出来的是全部的依赖目标,也就是targeta和targetb。
第三个是'$@',这个命令代表我们所需要输出的目标,如图:

使用'$@'命令,打印出来的是目标,也就是我们所需要的目标all。
模式匹配
首先是'%'符号,它的作用是匹配多个非空字符,如图:

图中我指定的目标名称为:stm32,然后执行是没有问题的也是输出我想要的结果。
默认规则
通常情况下,.o文件默认使用.c文件来进行编译。
Makefile条件分支
第一个语句:
ifeq (var1,var2)
event1
else
event2
endif
ifeq指令用于比较两个变量var1和var2的值。如果它们的值相等,那么event1里面的命令会被执行。如果它们的值不相等,那么event2里面的命令会被执行。endif用于结束条件分支。如图:

我的思路是判断var1是否等于var2,但很显然,1不等于2,所以输出的是no,也就是执行上面的event2。
第二个语句:
ifneq (var1,var2)
event1
else
event2
endif
对比上面的语句可以看出,该语句多了一个n,这个n代表的意思正好跟上面的相反。该语句中,如果var1等于var2,就执行event2里面的命令;如果不相等则执行event1里面的内容。如图:

因为var1不等于var2,所以就执行event1里面命令。
Makefile常用函数
Patsubst
patsubst 函数是GNU Make中的一个内置函数,用于字符串替换。它的作用是将一个字符串中的所有匹配指定模式的子串替换为另一个字符串。这个函数在处理文件名和路径时特别有用,因为它可以自动地将文件扩展名从一个格式转换为另一个格式。如图:

解释一下,%.c 表示任何以 .c 结尾的文件,而%.o 表示任何以 .o 结尾的文件。当使用 patsubst 函数时,它会查找所有匹配 %.c 模式的文件名,并将 .c 替换为 .o 。简单来说就是把所有的.c文件改成.o文件。
Notdir
notdir 是 Makefile 中的一个内置函数,用于从文件名中移除目录路径,只保留文件名本身。如图:

解释一下,part5文件的路径如图所示,然后调用该notdir函数之后,打印出来的就只剩part5这个文件名了,去掉了路径。
Wildcard
wildcard 函数用于生成匹配特定模式的文件列表。如图:

首先是ls查看一下当前目录下有上面文件,可以看到有一个main.c文件,然后执行一下make,打印出来的就是当前目录下所有以.c文件了。
Foreach
foreach 函数用于对列表中的每个元素执行特定的操作。如图:

使用 foreach 函数遍历 dirs 变量中的每个目录名称,并使用 wildcard 函数查找每个目录下的所有文件。 $(dir)/* 是一个通配符模式,匹配指定目录下的所有文件。 foreach 函数将每个目录下匹配的文件列表收集起来,最终赋值给 files 变量。
总结
以上观点仅代表个人看法,如有不足,欢迎指出!
