Makefile的简单使用
Posted Heavy sea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Makefile的简单使用相关的知识,希望对你有一定的参考价值。
一、Makefile核心规则
目标文件(target)… : 依赖文件(prerequiries)…
tab键+ 命令(command)
如果依赖文件比目标文件更加新,那么执行命令来重新生成目标文件
举例:
a.c
#include <stdio.h>
int main()
{
func_b();
return 0;
}
b.c
#include <stdio.h>
void func_b()
{
printf("this is A!\\n");
}
可用命令gcc -o test a.c b.c
进行编译,但现在需要用make命令,编写Makefile文件
我们知道可以用gcc -c 命令分别对a.c 和 b.c 文件进行编译不链接,形成a.o 和 b.o 文件,然后再对a.o 和 b.o 文件进行链接形成可执行文件test。基于这一点,可以编写以下Makefile文件(后续进行完善)
test: a.o b.o
gcc -o test a.o b.o
a.o: a.c
gcc -c -o a.o a.c
b.o: b.c
gcc -c -o b.o b.c
二、 Makefile语法
1.通配符: %.o
表示目标 $@
表示第一个依赖文件 $<
表示所有依赖文件 $^
2.假相目标: .PHONY
根据以上语法可对之前的Makefile文件进行改进
若make 不指定目标,默认执行第一条命令,即生成可执行文件test;若指定目标clean则执行删除有关文件。
Makefile命令执行条件是:目标文件不存在或者依赖文件比目标文件新
若文件目录存在clean文件,而无依赖文件,则执行不了删除命令,则需要使用.PHONY
test: a.o b.o
gcc -o $@ $^
%.o: %.c
gcc -c -o $@ $<
clean:
rm *.o test -f
.PHONY: clean
3.即时变量 延时变量
:= 即时变量
= 延时变量
?= 延时变量,如果是第一次定义才起效,如果在前面该变量已定义则忽略这句
+= 附加,它是即时变量还是延时变量取决于前面的定义
有以下Makefile文件
A为即时变量,在定义时就确定,此时变量C为空
B为延时变量 使用时才确定
A := $(C)
B = $(C)
C = ab
D = hello
D ?= heavysea
all:
@echo A = $(A)
@echo B = $(B)
@echo D = $(D)
C += ee
~
执行make命令:
A =
B = ab ee
D = hello
三、Makefile部分常用函数
1. $(foreach var f,list,text)
把参数list中的单词逐一取出来放到var所指的变量中,然后再执行text所包含的表达式
2. $(filter pattern…,text)
在text中取出符合pattern格式的值
3. $(filter-out pattern…,text)
在text中取出不符合pattern格式的值
4. $(wildcard pattern)
pattern 定义了条件名的格式
wildcard 取出其中存在的文件
5. $(patsubst pattern,replacement, $(var))
从列表中取出每一个值,如果符合pattern,则替换为replacement
Makefile
A = a b c
B = $(foreach f,$(A),$(f).o)
C = a b c d e/
// 查找C中符合 .../的形式
D = $(filter %/,$(C))
// 查找C中不符合 .../的形式
E = $(filter-out %/,$(C))
//取出存在的.c文件
file = $(wildcard *.c)
file2 = a.c b.c c.c d.c e.c
// 取出file2中且存在的文件
file3 = $(wildcard $(file2))
// 从file2中取出的值若符合.c形式则替换为.d文件
dep_files = $(patsubst %.c,%.d,$(file2))
all:
@echo B = $(B)
@echo D = $(D)
@echo E = $(E)
@echo file = $(file)
@echo file3 = $(file3)
@echo dep_files = $(dep_files)
运行结果如下图
四、Makefile的实例(自动检测头文件)
文件目录下有a.c b.c 文件
objs = a.o b.o
// .a.o.d .b.o.d
// 需要判断是否存在依赖文件
dep_files := $(patsubst %,.%.d,$(objs))
dep_files := $(wildcard $(dep_files))
// 警告作为错误提醒 指定头文件路径
CFLAGS = -Werror -I .
test: $(objs)
gcc -o $@ $^
// 把依赖文件包含进来
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o: %.c
gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d
clean:
rm *.o test -f
// 删除依赖文件
distclean:
rm $(dep_files)
.PHONY: clean
有关依赖文件的常用命令
// 打印出依赖
gcc -M b.c
// 把依赖写入文件b.d
gcc -M -MF b.d b.c
// 编译b.o 把依赖写入文件b.d
gcc -c -o b.o b.c -MD -MF b.d
以上是关于Makefile的简单使用的主要内容,如果未能解决你的问题,请参考以下文章