学习Linux(29)MakeFile

make工具:它可以帮助我们找出项目里面修改变更过的文件,并根据依赖关系,找出受修改影响的其他相关文件,然后对这些文件按照规则进行单独的编译,这样一来,就能避免重新编译项目的所有的文件。
Makefile文件:上面提到的规则、依赖关系主要是定义在这个Makefile文件中的,我们在其中合理地定义好文件的依赖关系之后,make工具就能精准地进行编译工作。
在这里插入图片描述

从我们上面的介绍,大家可以知道,我们管理一个项目工程,实质上就是管理项目文件间的依赖关系。 所以我们在学习和使用Makefile的时候,一定要牢牢抓住它这种面向依赖的思想, 心里一定要谨记,Makefile中所有的复杂、晦涩的语法都是更好地为解决依赖问题而存在的。 理解了它的本质目的之后,我们以后在学习它的过程中就不用死记硬背各种语法了, 只要想想这个本质目的,你会觉得一切都是那么地顺理成章。
在这里插入图片描述
在这里插入图片描述

Makefile 三要素:
目标、命令、依赖

三要素的关系:
目标:依赖的文件或是其他目标

命令1
命令2
。。。。

示例代码
在这里插入图片描述

默认执行目标,以第一个目标为准
在这里插入图片描述

指定执行目标
在这里插入图片描述

未修改过的目标不会再执行
在这里插入图片描述

伪目标命令:指定伪目标
在这里插入图片描述

main.c
在这里插入图片描述

mp3.c
在这里插入图片描述

直接使用GCC编译程序并执行
在这里插入图片描述

使用Makefile来管理项目
在这里插入图片描述
在这里插入图片描述

为了避免每次修改任何一个文件,都要全部编译,对Makefile进行改造。
在这里插入图片描述
在这里插入图片描述

然并卯,我以为修改了main.c后在执行make,会自动只编译main.c,没想到压根就不执行编译了。因为main.o是存在的,就不会在编译了,也就是说要手动去编译main.c,在来执行make命令。。。我要你有何用!
在这里插入图片描述
在这里插入图片描述

好的,由于少写了依赖的.c文件,所以没有达到理想效果。
学到后面才发现,这样才是理想状态,只会编译修改过的.c文件。
在这里插入图片描述

系统变量(常用)
在这里插入图片描述

自定义变量
= 延迟赋值:只有系统调用它的时候才会赋值、
在这里插入图片描述

:= 立即赋值:在引用之前就已经有确定的值了。
在这里插入图片描述

?= 空赋值:只有当这个变量为空的时候才会赋值
在这里插入图片描述

+= 追加赋值:并不会改变原有的值,会在后面追加内容
在这里插入图片描述

自动化变量
符号 意义
$@ 匹配目标文件
% 与 @类似,但$%仅匹配“库”类型的目标文件
$< 依赖中的第一个目标文件
$^ 所有的依赖目标,如果依赖中有重复的,只保留一份
$+ 所有的依赖目标,即使依赖中有重复的也原样保留
$? 所有比目标要新的依赖目标

$< 指向第一个依赖文件
在这里插入图片描述

$^ 指向全部的依赖文件
在这里插入图片描述

$@ 指向目标
在这里插入图片描述

用变量对Makefile进行改造
在这里插入图片描述

在这里插入图片描述

模式匹配
% 匹配任意多个非空字符
在这里插入图片描述

使用%通配符对Makefile进行改造
在这里插入图片描述
在这里插入图片描述

默认规则
.o文件默认使用.c文件来编译

在这里插入图片描述

条件分支
ifeq(arg1, arg2)
分支1
else
分支2
endif
在这里插入图片描述

使用gcc编译工具链
在这里插入图片描述

使用arm-linux-gnueabihf-gcc编译工具链
在这里插入图片描述

使用函数
https://www.gnu.org/manual/manual.html Makefile官网手册

patsubst函数功能为模式字符串替换。它的格式如下:
1 $(patsubst 匹配规则, 替换规则, 输入的字符串)
当输入的字符串符合匹配规则,那么使用替换规则来替换字符串,当匹配规则中有“%”号时,替换规 则也可以例程“%”号来提取“%”匹配的内容加入到最后替换的字符串中。有点抽象,请直接阅读以下示例:
#执行如下函数
$(patsubst %.c, build_dir/%.o, hello_main.c )#函数的输出为:
build_dir/hello_main.o

#执行如下函数$(patsubst %.c, build_dir/%.o, hello_main.xxx )#由于hello_main.xxx不符合匹配规则"%.c",所以函数没有输出
第一个函数调用中,由于“hello_main.c”符合“%.c”的匹配规则(%在Makefile中的类似于*通配符),而且“%”从“hello_main.c”中提取出了“hello_main”字符,把这部分内容放到替换规则“build_dir/%.o”的“%”号中,所以最终的输出为”build_di r/hello_main.o”。
第二个函数调用中,由于由于“hello_main.xxx”不符合“%.c”的匹配规则,“.xxx”与“.c”对不上,所以不会进行替换,函数直接返回空的内容。

在这里插入图片描述

7.8.1.1. notdir函数
notdir函数用于去除文件路径中的目录部分。它的格式如下:
KaTeX parse error: Expected 'EOF', got '#' at position 114: …保留 文件名。使用范例如下: #̲以下是范例(notdir ./sources/hello_func.c)
#上面的函数执行后会把路径中的“./sources/”部分去掉,输出为: hello_func.c
在这里插入图片描述

7.8.1.2. wildcard函数
wildcard函数用于获取文件列表,并使用空格分隔开。它的格式如下:
( w i l d c a r d 匹 配 规 则 ) 例 如 函 数 调 用 “ (wildcard 匹配规则) 例如函数调用“ (wildcard)(wildcard *.c)”,函数执行后会把当前目录的所 有c文件列出。假设我们在上图中的Makefile目录下执行该函数,使用范例如下:

#在sources目录下有hello_func.c、hello_main.c、test.c文件#执行如下函数
$(wildcard sources/*.c)#函数的输出为:
sources/hello_func.c sources/hello_main.c sources/test.c

在这里插入图片描述

foreach函数
它是一个循环函数。类似于Linux的shell中的for语句。
$(foreach VAR,LIST,TEXT)
在这里插入图片描述

大改造,将Makefile打造成能通用的版本。
在这里插入图片描述

完美,老实说:刚看到视频上这么改造,我凌乱了,捋了半小时才消化。
在这里插入图片描述

Makefile解决头文件依赖
先取出头文件路径,然后在编译的时候添加头文件(gcc -I +“头文件”)
在这里插入图片描述

这样在编译的时候就不会提示警告了,会连头文件一起编译
在这里插入图片描述

在修改了头文件后,重新执行make命令,并没有重新编译
在这里插入图片描述

修改Makefile添加所有的.h文件,并在编译的时候也参与。
在这里插入图片描述

这样就能达到理想中,每次头文件修改,所有相关的文件都重新编译。
在这里插入图片描述

初探Makefile文件,头晕眼花,博大精深啊

Hankin
2020.07.15

注释。
Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用“ #”字符,这个就
像 C/C++中的“// ”一样。如果你要在你的 Makefile 中使用“#”字符,可以用反斜框进行
转义,如:“# ”。
最后,还值得一提的是,在 Makefile 中的命令,必须要以 [Tab] 键开始。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值