借助实例轻松掌握 Makefile -- 萌芽破土



萌芽破土篇

在这里插入图片描述

实例1:hello world


编辑 Makefile

all:
	echo "hello world"


编译执行

$ make
$ make all 


结果输出

在这里插入图片描述


语法说明

  • echo 前面必须只有 TAB(即你键盘上的 TAB键),且至少有一个 TAB,不能用空格代替。


实例2:Makefile定义多个目标


编辑 Makefile

all:
	echo "hello world"
	
test:
	echo "hello test"


编译执行

$ make 
$ make all
$ make test 


结果输出

在这里插入图片描述


语法说明

  • Makefile 中包含多个目标时,直接使用 make 编译省略模式下,默认编译第一个目标。


实例3:Makefile注释


编辑 Makefile

all:
	@echo "hello world"
	
test:
	@echo "hello test"


编译执行

$ make 
$ make all
$ make test 


结果输出

在这里插入图片描述

语法说明

  • 使用 @ 符号,告诉make在运行时不要将这一行命令显示出来。


实例4:简单的依赖


编辑 Makefile

all:test
	@echo "hello world"
	
test:
	@echo "hello test"


编译执行

$ make 
$ make test 


结果输出

在这里插入图片描述


语法说明

  • all:test 告诉 make,all 目标依赖 test 目标,这一依目标在Makefile中又被称为先决条件。出现这种目标依赖关系时,make工具会按照从左到右的先后顺序先构建规则中的每一个目标。比如这里,如果要构建 all ,那么 make 会在构建它之前先构建 test 目标。


实例5:simple程序编译

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


编译执行

$ make 


结果输出

在这里插入图片描述


语法说明

  • 写 Makefile 文件的关键是理清文件之间的依赖关系。


实例6:假目标

实例 5 的 Makefile 中有一个clean文件,我们希望能够通过 clean 命令,清理历史文件。不过,在执行 clean 指令时候发现,没法对文件进行删除。这是因为 make 将 clean 当作条件,且在当前目录找到了这个文件,加上 clean 目标没有任何先决条件,所以,当我们要求 make 为我们构建 clean 目标时,它就会认为 clean 是最新的。

在这里插入图片描述

对于这种情况,可以通过 Makefile 中的假目标来解决,假目标可以通过关键字 .PHONY 定义。


编辑 Makefile

.PHONY:clean
all: main.o foo.o
	gcc -o simple main.o foo.o
maiin.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


编译执行

$ make 
$ ./simple
$ make clean


结果输出

在这里插入图片描述


语法说明

  • Makefile 假目标关键字 .PHONY


实例7:Makefile变量


编辑 Makefile

.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)


编译执行

$ make 
$ ./simple
$ make clean


结果输出

在这里插入图片描述

语法说明

  • 变量定义:变量名=变量值;
  • 变量引用:$(变量名) 或 ${变量名}


实例8:Makefile自动变量


编辑 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)


编译执行

$ make 
$ ./simple
$ make clean


结果输出

在这里插入图片描述


语法说明

  • $ @ 用于表示一个规则中的目标;当一个规则中目标有多个时,$ @指的是其中任何造成命令被运行的目标;
  • $ ^ 用于表示规则中的所有先决条件;
  • $ < 用于表示规则中的第一个先决条件。
  • 在Makefile中 ’ $ ’ 具有特殊的含义,因此如果需要采用 echo 输出 ’ $ ’ ,则需要用两个连着的 ‘ $ ’;同时 ‘$ @’ 对 Shell 也有特殊的意思,因此需要在 ‘$$@’ 前面增加一个脱字节 ‘ \ ’.


附加实例

//Makefile
.PHONY: all
all: first second third
	@echo "\$$@ = $@"
	@echo "$$^ = $^"
	@echo "$$< = $<"
first second third:

//输出
$make
$@ = all
$^ = first second third
$< = first


实例9:Makefile特殊变量


1. MAKE

编辑 Makefile

.PHONY: all
all: 
	@echo "MAKE = $(MAKE)"


编译执行

$ make 


结果输出
在这里插入图片描述


语法说明

  • MAKE 变量表示make命令名是什么;
  • 使用场景:当我们需要在Makefile中调用另外一个Makefile时需要用到它,采用这种方式有利于写一个容易移植的Makefile。



2. MAKECMDGOALS

编辑 Makefile

.PHONY: all clean
all clean: 
	@echo "\$$@ = $@"
	@echo "MAKECMDGOALS = $(MAKECMDGOALS)"


编译执行

$ make 
$ make all
$ make clean
$ make all clean


结果输出
在这里插入图片描述


语法说明

  • MAKECMDGOALS 表示是当前用户输入的 make 目标是什么。


实例10:Makefile变量的类别


1. 递归扩展变量

编辑 Makefile

.PHONY: all
foo=$(var1)
var1=-$(var2)
var2=100

all: 
	@echo $(foo)


编译执行

$ make 


结果输出在这里插入图片描述


语法说明

  • = 符号定义的变量称之为递归扩展变量。



2. 简单扩展变量

编辑 Makefile

.PHONY: all clean
x = foo
y = $(x) b
x = later
xx := foo
yy := $(xx) b
xx := later

all:
	@echo "x = $(y), xx = $(yy)"


编译执行

$ make 


结果输出
在这里插入图片描述


语法说明

  • := 符号定义的变量称之为简单扩展变量。



3. 条件赋值变量

编辑 Makefile

.PHONY: all clean
foo = x
foo ?= y
bar ?= y

all:
	@echo "foo = $(foo), bar = $(bar)"


编译执行

$ make 


结果输出
在这里插入图片描述


语法说明

  • ?= 符号定义的变量称之为条件赋值变量;
  • 含义:当变量以前没有定义,就定义它并将左边的值赋给它;如果先前已经定义过了,就不会改变它原来的值。


实例11:Makefile高级变量引用功能

编辑 Makefile

.PHONY: all
foo=a.o b.o c.o
bar := $(foo:.o=.c)

all: 
	@echo "bar = $(bar)"


编译执行

$ make 


结果输出在这里插入图片描述


语法说明

  • 上面实例中变量引用的一种高级功能,在赋值的同时完成后缀替换。


实例12:override指令

编辑 Makefile

.PHONY: all
override foo=100

all: 
	@echo "foo = $(foo)"


编译执行

$ make 
$ make foo=0


结果输出

在这里插入图片描述


语法说明

  • override 可以使得定义变量的值不被覆盖。如上面:make foo=0 输出的值依然为100。


实例13:Makefile模式

编辑 Makefile

.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)


编译执行

$ make 
$ ./simple


结果输出

在这里插入图片描述


语法说明

  • % 字符模式类似Windows操作系统中的通配符。


实例14:addprefix函数

编辑 Makefile

.PHONY: all
without_dir = foo.c bar.c main.o
with_dir := $( addprefix objs/, $(without_dir))

all:
	@echo $(with_dir)


编译执行

$ make 


结果输出

在这里插入图片描述


语法说明

  • addprefix 用于给字符串中每个子串前都加上一个前缀,形式:$(addprefix prefix, names…)


实例15:filter 函数

编辑 Makefile

.PHONY: all
text = a.c b.c c.s d.h
text := $(filter %.c %.s, $(text))
all:
	@echo $(text)


编译执行

$ make 


结果输出
在这里插入图片描述


语法说明

  • filter 用于从一个字符串中,根据模式得到满足模式的字符串,形式:$(filter pattern…, text)


实例16:filter-out 函数

编辑 Makefile

.PHONY: all
text = a.c b.c c.s d.h
text := $(filter-out %.c %.s, $(text))
all:
	@echo $(text)


编译执行

$ make 


结果输出

在这里插入图片描述


语法说明

  • filter-out 用于从一个字符串中,根据模式滤除一部分字符串,形式:$(filter-out pattern…, text)


实例17:patsubst 函数

编辑 Makefile

.PHONY: all
text = a.c b.c c.c
text := $(patsubst %.c %.h, $(text))
all:
	@echo $(text)


编译执行

$ make 


结果输出

在这里插入图片描述


语法说明

  • patsubst 用于字符串替换;同时patsubst函数可以使用模式,所以也可以用于替换前缀等;形式:$(patsubst pattern,replacement,text)


实例18:strip 函数

编辑 Makefile

.PHONY: all
src = a.c  b.c  c.c
dst := $(strip $(src))
all:
	@echo "src = $(src)"
	@echo "dst = $(dst)"


编译执行

$ make 


结果输出

在这里插入图片描述


语法说明

  • patsubst 用于去除变量中多余的空格;形式:$(strip string)


实例19:wildcard 函数

编辑 Makefile

//显示当前Makefile目录下所有 .c 文件
.PHONY: all
src = $(wildcard *.c)
all:
	@echo $(src)


编译执行

$ make 


结果输出(默认Makefile所在目录中包含了foo.c main.c bar.c等文件)

在这里插入图片描述


语法说明

  • wildcard 通配符函数,类似于 Windows 或 linux 命令行中的 " * ";形式:$(wildcard pattern)

猜你喜欢

转载自blog.csdn.net/locahuang/article/details/126966304