Makefile笔记
2019-05-20 本文已影响0人
delta1037
Makefile 简介
makefile用来制定编译的规则及其其它更复杂的操作.并且能实现整个工程的自动化编译,提高编译效率
Makefile 格式:
target : prerequisites
<tab> command
目标:target
- 文件名 : *.o ... (可以是多个,即使是最终目标文件)
- 操作的名字(伪目标) : clean ...
- 通过 .PHONY 来声明clean是一个伪目标,而不是一个目标文件,例:
.PHONY: clean
clean:
rm *.o temp
前置条件 prerequisites
一组文件名 : 用空格分开
只要有一个前置条件的文件有过更新,目标就要重新构建
命令 command
由一行或者多行的shell命令组成,命令之前必须有tab键
- 每行命令在一个单独的shell中执行,这些shell之间没有继承关系
- 多行命令依赖解决: 1、加上.ONESHELL: 2、 用逗号分隔 3、添加换行转义
Makefile 语法
注释
# 这是注释
target : prerequisites
<tab> command
回声 echoing
在执行每一条命令时都会在终端打印这条命令,在命令之前加上@可以关闭
通配符
Makefile通配符与bash一致,主要有
- : 可以匹配任何字符
- ?: 匹配任意单个字符
- [...] : 匹配一个单字符范围,
模式匹配
对文件名进行类似正则运算的匹配,适应于大量同类型的文件
%.o : %.c
变量
变量可以用等号赋值,访问时可以使用$(Variable)来访问
所以在使用美元符号的时候可以使用$$来转义
赋值:
VARIABLE = value
# 在执行时扩展,允许递归扩展。
VARIABLE := value
# 在定义时扩展。
VARIABLE ?= value
# 只有在该变量为空时才设置值。
VARIABLE += value
# 将值追加到变量的尾端。
内置变量
- $(CC) : 指向当前使用的编译器
- $(MAKE) :指向当前使用的Make工具
自动变量
- $@ : 指代当前需要生成的目标
- $< : 指代第一个前置条件
- $? : 指代比目标更新的所有前置条件
- $^ : 指代所有前置条件
判断和循环
判断
ifeq ($(CC),gcc)
libs=$(libs_for_gcc)
else
libs=$(normal_libs)
endif
循环
LIST = one two three
all:
for i in $(LIST); do \
echo $$i; \
done
函数
格式
$(function arguments)
# 或者
${function arguments}
shell函数
srcfiles := $(shell echo src/{00..99}.txt)
wildcard函数
srcfiles := $(wildcard src/*.txt)
subst 函数
$(subst from,to,text)
patsubst函数
$(patsubst pattern,replacement,text)
替换后缀名
min: $(OUTPUT:.js=.min.js)
Makefile 执行
通过make命令工具来解释makefile中的指令,makefile告诉make需要怎么去编译和链接目标程序,make还能根据当前文件情况确定哪些文件需要重新编译
$ make # 自动寻找Makefile
$ make -f Makefile
$ make --file=Makefile
附:编译和链接
基本流程
- 源文件--编译-->中间文件
- 中间文件--链接-->可执行文件
编译链接细节
- 编译时,编译器需要的是语法,函数与变量的声明是否正确,只要正确就能生成中间文件
- 链接时,主要是链接函数和全局变量,连接时只管中间目标文件
- 在中间文件过多时,可以给中间文件打包
注
中间文件:
- Windows:*.obj
- UNIX : *.o 文件
打包文件:
- Window : 库文件(Library File) .lib
- Unix : Archive File, .a