文章目录
- 1、准备环境
- 1.2、规则
- 1.3、假目标
- 1.4、变量
- 1.5、自动变量
- 1.6、函数
- addprefix 函数
- filter函数
- filter-out函数
- patsubst函数
- strip函数
- wildcard函数
1、准备环境
准备一台Linux机器,验证环境中是否呗正确安装了,使用make -v命令进行验证
1.2、规则
最简单的例子输出hello world,创建一个makefile文件,文件输入一下文件内容
运行:make
# 加上@的意思是不希望他把这条命令打出来
all:
@echo "hello world"
总结:
1、一个Makefile中可以定义多个目标。
2、调用make可以通过附加参数告诉他要做什么。
3、当Makefile得到目标后,先找到定义目标的规则,然后运行规则中的命令达到构建目标的目的,现在所示例的Makefile中,没一个规则中都只有一条命令,而实际的Makefile,每一个规则可以包含很多条命令。
1、例1
all: test
@echo "Hello World"
test:
@echo "Just for test!"
这里应用了makefile中的依赖概念,all ⽬标后⾯的 test 是告诉 make,all ⽬标依赖 test ⽬标,这⼀依赖⽬标在 Makefile 中⼜被称之为先决条件。出现这种⽬标依赖关系时,make⼯具会按 从左到右的先后顺序先构建规则中所依赖的每⼀个⽬标。如果希望构建 all ⽬标,那么make 会在构建它之 前得先构建 test ⽬标,这就是为什么我们称之为先决条件的原因。
2、例2
foo.c
#include <stdio.h>
void foo ()
{
printf ("This is foo ()!\n");
}
main.c
extern void foo();
int main ()
{
foo();
return 0;
}
Makefile
all: main.o foo.o
gcc -o simple main.o foo.o
main.o: main.c
gcc -o main.o -c main.c
foo.o: foo.c
gcc -o foo.o -c foo.c
clean:
rm simple main.o foo.o
1.3、假目标
在前⾯的 sample 项⽬中,现在假设在程序所在的⽬录下⾯有⼀个 clean ⽂件,这个⽂件也可以通过 touch 命令来创建。创建以后,运⾏ make clean 命令,你会发现 make 总是提示 clean ⽂件是最新 的,⽽不是按我们所期望的那样进⾏⽂件删除操作,从原理上我们还是可以理解的,这是 因为 make 将 clean 当作⽂件,且在当前⽬录找到了这个⽂件,加上 clean ⽬标没有任何先决条件,所 以,当我们要求 make 为我们构建 clean ⽬标时,它就会认为 clean 是最新的。那对于这种情况,在现实中也难免存在所定义的⽬标与所存在的⽂件是同名的,采⽤ Makefile如何处理这 种情况呢?Makefile 中的假⽬标(phony target)可以解决这个问题。假⽬标可以采⽤.PHONY 关键字,来定义,需要注意的是其必须是⼤写字⺟。
.PHONY: clean
all: main.o foo.o
gcc -o simple main.o foo.o
main.o: main.c
gcc -o main.o -c main.c
foo.o: foo.c
gcc -o foo.o -c foo.c
clean:
rm simple main.o foo.o
1.4、变量
.PHONY: clean
CC = gcc
RM = rm
EXE = simple
OBJS = main.o foo.o
$(EXE): $(OBJS)
$(CC) -o $(EXE) $(OBJS)
main.o: main.c
$(CC) -o main.o -c main.c
foo.o: foo.c
$(CC) -o foo.o -c foo.c
clean:$(RM)
$(EXE) $(OBJS)
1.5、自动变量
@ ⽤于表示⼀个规则中的⽬标。当我们的⼀个规则中有多个⽬标时, @⽤于表示⼀个规则中的⽬标。当我们的⼀个规则中有多个⽬标时, @⽤于表示⼀个规则中的⽬标。当我们的⼀个规则中有多个⽬标时,@所指的是其中任何造成命令 被运⾏的⽬标。
$^则表示的是规则中的所有先择条件。
$<表示的是规则中的第⼀个先决条件。
.PHONY: all
all: first second third
@echo "\$$@ = $@"
@echo "$$^ = $^"
@echo "$$< = $<"
执⾏
make
@ = all
^ = first second third
< = first
重写的makefile
.PHONY: clean
CC = gcc
RM = rm
EXE = simple
OBJS = main.o foo.o
$(EXE): $(OBJS)
$(CC) -o $@ $^
main.o: main.c
$(CC) -o $@ -c $^
foo.o: foo.c
$(CC) -o $@ -c $^
clean:
$(RM) $(EXE) $(OBJS)
通配符:
.PHONY: clean
CC = gcc
RM = rm
EXE = simple
OBJS = main.o foo.o
$(EXE): $(OBJS)
$(CC) -o $@ $^
%.o: %.c
$(CC) -o $@ -c $^
clean:
$(RM) $(EXE) $(OBJS)
1.6、函数
采⽤了 wildcard 和 patsubst 两个函数后 simple 项⽬的 Makefile。
.PHONY: clean
CC = gcc
RM = rm
EXE = simple
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS)) -》把.c 替换为.o
$(EXE): $(OBJS)
$(CC) -o $@ $^
%.o: %.c $(CC) -o $@ -c $^
clean:
$(RM) $(EXE) $(OBJS)
addprefix 函数
addprefix 函数是⽤来在给字符串中的每个⼦串前加上⼀个前缀,其形式是: $(addprefix prefix, names…)
.PHONY: all
without_dir = foo.c bar.c main.o
with_dir := $( addprefix objs/, $(without_dir))
all: @echo $(with_dir)
执⾏
$make
objs/foo.c objs/bar.c objs/main.o
filter函数
filter 函数⽤于从⼀个字符串中,根据模式得到满⾜模式的字符串,其形式是: $(filter pattern…, text)
PHONY: all
sources = foo.c bar.c baz.s ugh.h
sources := $(filter %.c %.s, $(sources))
all:
@echo $(sources)
执⾏
$make
foo.c bar.c baz.s
filter-out函数
filter-out 函数⽤于从⼀个字符串中根据模式滤除⼀部分字符串,其形式是: $(filter-out pattern…, text),从 objects 变量中给滤除了。filter 与 filter-out 是互补的。
.PHONY: all
objects = main1.o foo.o main2.o bar.o
result = $(filter-out main%.o, $(objects))
all:
@echo $(result)
执⾏
$make
foo.o bar.o
patsubst函数
patsubst 函数是⽤来进⾏字符串替换的,其形式是: $(patsubst pattern, replacement, text)
.PHONY: all
mixed = foo.c bar.c main.o
objects := $(patsubst %.c, %.o, $(mixed))
all:
@echo $(objects)
执⾏
$make
foo.o bar.o main.o
strip函数
strip 函数⽤于去除变量中的多余的空格,其形式是: $(strip string)
.PHONY: all
original = foo.c bar.c
stripped := $(strip $(original))
all:
@echo "original = $(original)"
@echo "stripped = $(stripped)"
执⾏
$make
original = foo.c bar.c
stripped = foo.c bar.c
wildcard函数
wildcard 是通配符函数,通过它可以得到我们所需的⽂件,这个函数如果我们在 Windows 或是Linux 命 令⾏中的“*”。其形式是: $(wildcard pattern)
.PHONY: all
SRCS = $(wildcard *.c)
all:
@echo $(SRCS)
执⾏
$make
bar.c foo.c main.c