linux之提取Makefile中与%匹配的部分字符串

insus 阅读:23 2024-10-24 08:47:37 评论:0

我正在做我的 CS 作业,其中包含许多单文件程序。我的工作目录如下所示:

133.c 134.c 220.c 281.c 337.c 338.c 339.c makefile 

我写了一个这样的Makefile:

%: %.c 
    ${CC} ${CFLAGS} -o $@ $^ 

因此,当我想编译问题 220 的程序时,我输入以下内容:
ibug@wsl:~ $ make 220 
gcc  -o 220 220.c 
ibug@wsl:~ $ 

问题

我想写一个 clean-%规则,这样当我在 shell 中运行它时,结果应该如下所示
ibug@wsl:~ $ make clean-133 
rm -f 133 
ibug@wsl:~ $ make clean-281 
rm -f 281 
ibug@wsl:~ $ make clean-337 
rm -f 337 

我已经走了这么远:
.PHONY: clean-% 
 
SRC = $(wildcard %.c) 
BIN = $(patsubst %.c,%,$(SRC)) 
 
clean-%: 
    rm -f ?????? 

我应该用什么代替问号?

我正在使用 GNU Make 4.1(在 Linux 的 Windows 子系统上)。

请您参考如下方法:

您正在寻找 automatic variable $* ,其中包含词干(即与 % 匹配的部分):

clean-%: 
    rm -f $* 

但是,请继续阅读。

虚假目标、模式和隐含规则

添加先决条件 clean-%.PHONY目标:
.PHONY: clean-% 

不转模式规则 clean-%变成一个虚假的目标,而是将显式规则,其实际目标名称是 clean-% (不是模式),变成虚假的目标。

原因是只有明确规则的目标才能成为虚假目标,模式不能成为虚假目标。因此,看起来像模式的虚假目标(即包含 % )并不是真正的模式(即 % 实际上是 % )。

添加所有可能的值 clean-%可以匹配到 .PHONY也无济于事,因为虚假目标会做 不是 匹配隐式模式规则。所以,如果你这样做:
.PHONY: clean-foo 
clean-foo永远不会匹配隐式模式规则(即,它永远不会匹配你的 clean-% 模式规则)。

定义 clean-xxx作为虚假目标

我猜你真的想要这些 clean-xxx目标是假目标,因为这些目标不代表文件系统上的实际文件。

使用静态模式规则

与隐式模式规则不同, static pattern rules可以匹配虚假目标。以下方法包括定义一个可以匹配那些 clean-xxx 的单个静态模式规则。虚假目标:
list := $(patsubst %.c,%,$(wildcard *.c)) 
 
# list of clean-xxx targets 
clean-targets := $(addprefix clean-,$(list)) 
 
.PHONY: $(clean-targets) 
 
$(clean-targets): clean-%: 
    rm -f $* 

上面的静态模式规则将匹配任何 clean-xxx在其目标列表中指定的虚假目标(即 $(clean-targets)

使用显式规则

以下方法包括动态生成这些 clean-xxx规则作为显式规则而不是单个模式规则:
list := $(patsubst %.c,%,$(wildcard *.c)) 
 
define create-clean-target 
    $(eval .PHONY: clean-$1); 
    $(eval clean-$1:; rm -f $1) 
endef 
 
 
# dynamically generate the clean-xxx targets 
$(foreach t,$(list),$(call create-clean-target,$t)) 

用户自定义函数 create-target定义一个明确的目标 clean-xxx , 为 xxx传递给函数的参数。由于要定义的这个目标是一个显式目标,所以它也可以成为一个虚假目标。


标签:linux
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号