【Linux】make模式规则

Makefile 模式规则

Makefile 中第 3~8 行是将对应的.c 源文件编译为.o 文件,每一个 C 文件都要写一个对应的规则,如果工程中 C 文件很多的话显然不能这么做。为此,我们可以使用 Makefile 中的 模式规则,通过 模式规则 我们就可以使用一条规则来将所有的.c 文件编译为对应的.o 文件。

模式规则中,至少在规则的目标定定义中要包涵“%”,否则就是一般规则,目标中的“%”表示对文件名的匹配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以 .c 结尾的文件,类似与通配符,a.%.c 就表示以 a. 开头,以 .c 结束的所有文件。

当“%”出现在目标中的时候,目标中“%”所代表的值决定了依赖中的“%”值,使用方法如下:

%.o : %.c
	命令

Makefile 自动化变量

        模式规则中,目标和依赖都是一系列的文件,每一次对模式规则进行解析的时候都会是不同的目标和依赖文件,而命令只有一行,如何通过一行命令来从不同的依赖文件中生成对应的目标?自动化变量就是完成这个功能的!所谓自动化变量就是这种变量会把模式中所定义的一系列的文件自动的挨个取出,直至所有的符合模式的文件都取完,自动化变量只应该出现在规则的命令中,常用的自动化变量如表:

自动化变量描述
$@规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模式中定义的目标集合。
$<依赖文件集合中 的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么“$<”就是符合模式的一系列的文件集合。
$^所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,“$^”会去除重复的依赖文件,只保留一份。

表中的 7 个自动化变量中,常用的三种:$@$<$^,我们使用自动化变量来完成 Makefile,最终完整代码:

修改后的完成的 Makefile,可以看出精简了很多,核心就在于第 5、6 这两行,第 5 行使用了 模式规则,第 6 行使用了 自动化变量。


模式规则

模式规则类似于普通规则。只是在模式规则中,目标名中需要包含有模式字符"%",包含有模式字符"%"的目标被用来匹配一个文件名,"%" 可以匹配任何非空字符串。规则的依赖文件中同样可以使用"%",依赖文件中模式字符"%"的取值情况由目标中的"%"来决定。

例如:对于模式规则"%.o : %.c",它表示的含义是:所有的.o文件依赖于对应的.c文件。

下列示例就是一个makefile內建的模式规则,由所有的.c文件生成对应的.o文件:

%.o : %.c
    $(CC) -c $(CFLAGS) $< -o $@

根据这个模式规则,makefile提供了隐式推导规则。

同时,模式规则的依赖可以不包含"%",当依赖不包含"%"时代表的是所有与模式匹配的目标都依赖于指定的依赖文件。

静态模式规则

静态模式可以更加容易地定义多目标的规则,它的语法是这样的:

目标 ...: 目标模式 : 依赖的模式
        命令
        ...

相对于普通的模式规则,静态模式规则则显得更加地灵活,作为模式规则的一种,仍然使用"%"来进行模式的匹配,我们来看下面一个简单的例子:

当前目录下的文件:foo.c foo.h bar.c bar.h main.c. makefile内容:

1 OBJ = foo.o bar.o
2 main:${OBJ}
3     cc ${OBJ} main.c -o main
4 ${OBJ}:%.o : %.c
5     cc -c $^

执行make时的运行log:

cc -c foo.c 
cc -c bar.c 
cc foo.o bar.o main.c -o main

make在编译时会将执行的指令打印出来,这一部分就是实际被执行的指令。

可以看到,在makefile第二行,main的依赖文件为${OBJ},即foo.obar.o,make在当前目录中并没有找到这两个文件,所以就需要寻找生成这两个依赖文件的规则。

第四行就是生成foo.obar.o的规则,所以需要先被执行,这一行使用了静态模式规则,对于存在于${OBJ}中的每个.o文件,使用对应的.c文件作为依赖,调用命令部分,而命令就是生成.o文件。

可以看到,相对应普通的模式规则,静态模式规则相对来说更加地灵活。


makefile命令模板1(百搭)

src = $(wildcard *.c)        # 找到当前目录下所有后缀为.c 的文件,赋值给 src
obj = $(patsubst %.c, % , $(src))    # 把 src 变量里所有 %.c 的文件替换成 %


ALL:$(obj)


$(obj):%:%.c  #静态模式规则
	gcc $< -o $@

clean:
	rm -rf $(obj)

.PHONY: clean ALL

 输出:

gcc mycp.c -o mycp
gcc open.c -o open

makefile命令模板2

src = $(wildcard *.c)    # 找到当前目录下所有后缀为.c 的文件,赋值给 src	
target = $(patsubst %.c, %.out, $(src))    # 把 src 变量里所有 %.c 的文件替换成 %.out
	

ALL:$(target)


$(target):%.out:%.c
	gcc $< -o $@

clean:
	rm -rf $(target)

.PHONY: clean ALL

# $@ : 在规则命令中, 表示规则中的目标
# $< : 在规则命令中, 表示规则中的第一个条件,如果将该变量用在模式规则中,它可以将依赖条件列表中的依赖依次取出,套用模式规则
# $^ : 在规则命令中, 表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复项,则去重

输出:

gcc mycp.c -o mycp.out
gcc open.c -o open.out

我感觉加了这个.out后,老是会出bug。不推荐这个写法。

makefile命令模板3(常用)

src = $(wildcard *.c)
targets = $(patsubst %.c, %, $(src))

CC = gcc
CFLAGS = -lpthread -m32 -Wall -g    #在Linux 64平台上编译32位程序

all:$(targets)

$(targets):%:%.c
	$(CC) $< -o $@ $(CFLAGS)

.PHONY:clean all
clean:
	-rm -rf $(targets) 

参考链接:

深入解析Makefile系列(2) -- 常用的通配符、內建变量和模式规则

Linux C 编程(Vim,GCC,Makefile 规则,模式规则,自动化变量,伪目标)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值