make & makefile

make是Linux下的一个工具,根据makefile的内容进行源文件的编译,也就是一个解释Makefile指令的命令行工具,执行make命令时,会先查找Makefile的文件作为编译文件,找不到再查找makefile,它根据Makefile中的第一个目标依次找它依赖的目标

make 执行后会有3个退出码
1. 什么都不提示表示执行成功
2. 返回1,说明make运行时产生错误
3. 若使用了-q选项,使得make有一些目标不用更新,返回2
4. make的指令行要缩进一个tab键,不是4个空格

使用
make [options] [target]
-f filename 显式指定文件作为makefile
-C dirname 指定make在开始运行后的工作目录为dirname
-e 不允许在Makefile中替换环境变量的赋值
-k 执行命令出错时,放弃当前目标,继续维护其它目标,也就是跳过错误
-n 仅仅用于显示执行过程,不实际执行
-p 显示所有的变量和内部规则
-r 忽略内部规则
-s 执行单不显示命令,常用来检测Makefile的正确性
-S 若执行出错就退出
-t 修改每个目标的创建日期
-I 忽略运行make中执行命令的错误
-V 显示make的版本号

Makefile的规则是若这个文件未被编辑过,则所有的C文件都会被编译和连接,若某几个文件被修改,则只需要编译修改后的文件,若头文件被修改,则只需要编译引用了这几个头文件的C文件

Makefile包含5个方面的内容:
1. 显式规则:显式指出生成文件、依赖文件
2. 隐式规则:make有自动推导的功能,可以简略的写makefile
3. 变量定义:类似C的宏,会被扩展到其它引用的地方
4. 文件指示:可以向其它语言的include一样,包含其它Makefile文件
5. 注释:#

在规则里使用通配符

~/test表示当前用户目录下的test
* 表示所有 eg rm *.o表示移除所有的 .o 文件
? 匹配一个字符
[...]
$? 是一个自动化变量,表示所有比目标新的依赖文件的集合

Note
*.o 不会展开,想要展开的话使用 $(wildcard *.o)
objects=*.o 不会展开
objects:=$(wildcard *.o) 会展开
.PHONY 用来显式的指定一个目标为伪目标,不管这个文件是否存在,都执行命令

变量

变量可以是包含字符、数字、下划线,但不能是: = # 空字符(空格或者回车),大小写敏感,需要赋初值,使用时需要在变量前加$,最好用() 或者 {}将变量包裹起来,若要真实使用$,要写成$$

eg: objects = program.o foo.o utils.o
    program:$(objects)
    gcc -o program $(objects)
    $(objects):defs.h

:=使得前边的变量不能使用后边的变量
?=若值未定义,则使用后边的值
+=给变量追加值,若前边的未定义,自动使用后边的值
define 将多条命令定义为一个变量
override <var>:=<val>

目标变量和模式变量

<target..>:<var-assignment>
<target..>:overide<var-assignment>
<target>为目标序列,<var-assignment>为各种表达式eg `:=` `?=` `+=`

模式变量就是将target写成pattern
eg %.o:CFLAGS=-O

常用函数调用

$(subst <from>,<to>,<text>) 将text中的from替换成to
$(patsubst <from>,<to>,<text>) 将查找符号模式pattern的单词进行替换
$(findstring <find>,<in>)在in中查找find,找到返回,否则返回空串
$(filter <pattern>,<text>)以pattern模式过滤字符串中的单词,保留符号pattern的
$(filter-out <pattern>,<text>)去除符号某个模式的
$(sort <list>)将list中的单词按字母升序排列
$(word <n>,<text>)从单词中取出第n个
$(wordlist <s>,<e>,<text>)从第start取到第n个
$(words <text>)单词个数统计
$(firstword <text>)取字符串的第一个单词

$(dir <names..>)从文件序列中取出目录
$(notdir <names..>)取文件名
$(suffix <names..>)取文件后缀
$(basename <names..>)取前缀
$(addsufix <suffix>,<names..>)加后缀
$(addprefix <prefix>,<names..>)加前缀
$(join <list1>,<list2>)将list2中的每个单词对应插入到list1后边

$(foreach <var>,<list>,<text>)list中的值被取出,放到var中,进行text的处理
$(if<condition>,<then-part>)
$(if<condition>,<then-part>,<else-part>)
$(call <express>,<param1>,<param2>)
eg. revers=$(2)$(1)
    foo=$(call revers,a,b) 那么foo就是b a
$(origin <var>)判断变量是在哪里定义的
eg. ifdef a #如果存在变量a
ifeq "$(origin a)" "evnvirenment" #如果变量a是环境变量
a=test #将环境变量a重新定义
endif
endif

$(shell ..)直接执行shell命令
eg. a:=$(shell cat foo)将foo的内容赋值给a
控制make的函数
$(error <text..>)函数产生致命错误,错误信息为text
makefile的自动化变量
$@ 所有目标变量的集合
$% 仅当目标是函数库文件时,表示规则中的目标成员名
$< 依赖目标中的第一个目标名字,若依赖目标是以模式(%)定义的,则表示符合模式的一系列文集
$? 所有比目标新的依赖目标的集合
$^ 所有依赖目标的集合,若有重复,自动去除
$+$^不去重
$* 目标模式中%及其之前的步伐
$(@D)|$(*D) 取文件目录部分
$(@F)|$(*F) 取文件部分,不包括后缀
$(%D) 函数包文件的目录部分
$(%F) 函数包文件成员的文件部分
$(<D) 依赖目标中的第一个目标的目录部分
$(<F) 依赖目标中的第一个目标的文件名部分
$(^D) 所有依赖目标的目录部分(无相同)
$(^F) 所有依赖目标的文件名部分(无相同)
$(+D) 所有依赖目标的目录部分(可以相同)
$(+F) 所有依赖目标的文件名部分(可以相同)
$(?D) 所有被更新文件的目录部分
$(?F) 所有被更新文件的文件名部分
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值