学习Linux(29)MakeFile
make工具:它可以帮助我们找出项目里面修改变更过的文件,并根据依赖关系,找出受修改影响的其他相关文件,然后对这些文件按照规则进行单独的编译,这样一来,就能避免重新编译项目的所有的文件。
Makefile文件:上面提到的规则、依赖关系主要是定义在这个Makefile文件中的,我们在其中合理地定义好文件的依赖关系之后,make工具就能精准地进行编译工作。
从我们上面的介绍,大家可以知道,我们管理一个项目工程,实质上就是管理项目文件间的依赖关系。 所以我们在学习和使用Makefile的时候,一定要牢牢抓住它这种面向依赖的思想, 心里一定要谨记,Makefile中所有的复杂、晦涩的语法都是更好地为解决依赖问题而存在的。 理解了它的本质目的之后,我们以后在学习它的过程中就不用死记硬背各种语法了, 只要想想这个本质目的,你会觉得一切都是那么地顺理成章。
Makefile 三要素:
目标、命令、依赖
三要素的关系:
目标:依赖的文件或是其他目标
示例代码
默认执行目标,以第一个目标为准
指定执行目标
未修改过的目标不会再执行
伪目标命令:指定伪目标
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函数用于获取文件列表,并使用空格分隔开。它的格式如下:
(wildcard匹配规则)例如函数调用“(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] 键开始。
- Linux Make(Makefile)由浅入深的学习与示例剖析
- Linux Make(Makefile)由浅入深的学习与示例剖析
- linux下Makefile的学习之八(隐含规则)
- Linux Make(Makefile)由浅入深的学习与示例剖析
- Linux学习之Makefile和Configure文件说明
- linux下Makefile的学习之七(make 的运行)
- Linux学习笔记——举例说,makefile 添加宏定义
- Linux Make(Makefile)由浅入深的学习与示例剖析
- linux下Makefile学习
- Linux 我的第一个makefile(Linux指令学习笔记)
- 【Linux学习】 写一个简单的Makefile编译源码获取当前系统时间
- Linux下的C语言学习之Makefile编写
- Linux学习之Makefile文件的编写
- linux基础学习之 Linux makefile 教程
- linux 学习makefile
- Linux学习之GCC&GDB,Makefile
- linux 下 c++ makefile学习文档
- LINUX学习之Makefile(转)
- linux命令 sed Makefile学习
- Linux学习笔记——例说makefile 单个C文件