makefile总结
概述
makefile常用来管理编译,控制生成最终代码的过程
make是可执行程序,用来执行makefile脚本的。
make工具源代码地址http://ftp.gnu.org/gnu/make/
makefile脚本在执行时,先看需要的目标在不在,若在,会检查各个源文件的时间stamp,若有时间变化就会重新执行,若无就不执行。
若不在,就会将这个目标重新生成一遍。
书写格式
目标:依赖
<TAB>命令
字符串变量的定义
1.全局定义,最终的值将会是整个makefile中最后被指定的值
x = foo
y = $(x) bar
x = xyz
y的值将会是 xyz bar ,而不是 foo bar
2.像C语言一样的变量定义,随定义,随使用
x := foo
y := $(x) bar
x := xyz
y的值将会是 foo bar, 而不是xyz bar了
3.定义带默认值的变量
var ?= init_value
4.将SHELL命令结果赋值给变量
var := $(shell ls *.c)
字符串变量值的获取
$(var) #推荐用法
${var}
$var
修改带默认值的变量值
make var=ttt
变量字符串的追加
var += test1
var += test2
shell命令的使用
不显示SHELL命令,直接输出命令执行结果
@echo $(VAR)
SHELL命令执行失败,中断流程
rm test.c
SHELL命令执行失败,不中断流程
-rm test.c
执行下级目录的makefile
make -C dir
自动变量
类型 | 说明 |
---|---|
$@ | 表示TARGET |
$< | 表示第一个依赖 |
$^ | 所有依赖 |
$? | 有更新的依赖 |
$(CURDIR) | 当前所在目录 |
定义伪目标
伪目标是用来指示目标是一个操作,不受实际项目中重名的文档影响。
这是为了避免目标名与生成的文件名产生冲突。
常常将clean
目标定义为伪目标,如下:
.PHONY:clean
clean:
rm -f *.bin
其实在我看来,将其称之为声明操作
更为合适。
具体内容见下面这篇BLOG.
https://www.cnblogs.com/idorax/p/9306528.html
条件判断
ifeq ($(MODE), release)
CFLAGS := -O2 -Wall -Werror -fPIC
LTYPE := release`
else
CFLAGS := -g -Wall -Werror -fPIC
LTYPE := debug
endif
使用方法:
make MODE=release
文件引入
ARC_INC := build/arm.inc
include $(ARC_INC)
常用函数
字符串函数 -- 只能是字符串,不能用变量替换
1.字符串替换
$(subst from, to,text)
2.通配替换
$(patsubst pattern, replacement,text)
3.去掉多余的空格与前导空格
$(strip string)
4.查找string
$(findstring str1,str2)
5.过滤出所要的类型
$(filter types, objects)
6.过滤掉某些类型
$(filterout types,objects)
7.按首字母进行排序,并去掉重复项
$(sort str1 str2 ...)
文件名函数
1.获得文件所在的路径(提取目录)
$(dir files name)
2.去掉文件名中的路径部分(不要目录)
$(notdir files name)
3.提取文件名中的后缀(只要后缀后)
$(suffix names ...)
4.提取不带后缀的文件名
$(basename names ...)
5.追加后缀
$(addsuffix suffix, names ...)
6.增加前缀
$(addprefix prefix, names ...)
7.通过通配符,列出当前目录下所有文件
$(wildcard *.c)
$(wildcard %.c) # %在makefile中也是通配符,此列表示所有所有以“.c”为后缀的文件。