如果我这样做:
.PHONY: all
all: reports
reports : *.csv
@echo $^
make 按预期在一行中列出目录中的所有 .CSV 文件。但当我这样做时:
.PHONY: all
all: reports
reports : %.csv
@echo $^
我得到“*** 没有规则来创建“报告”所需的目标“%.csv”。停止。
我缺少一些基本的东西。 .csv 文件是我希望 makefile 对它们执行的操作的源代码。它们存在于目录中。为什么make想要制作它们?
我期望 make 依次获取每个 .csv 文件(使用 %.csv),并在本示例中回显每个文件名。 (当然,稍后将用实际命令替换回显),如果我能理解如何获取不是 .c 文件的源代码。
我得到“*** 没有规则来创建“报告”所需的目标“%.csv”。 停下来。
我缺少一些基本的东西。 .csv 文件是我想要的源 makefile 对它们执行的操作。它们存在于目录中。为什么 make 想制作它们吗?
首先,您忽略了
make
不想构建任何现有文件。 诊断表明它想要构建一个名为 %.csv
的文件。 “%
”是一个字面字符。
更广泛的情况似乎是您假设
%
用作通用通配符,相当于 glob 表达式中的 *
。 至少在 GNU make
中不是,并且根据 POSIX 不是这样。 GNU 的 make
实现确实在某些特定情况下将该字符用于特殊目的,但您的示例没有呈现任何这些情况。
您可能将您的用法与 GNU
make
“模式规则”混淆了,但模式规则在目标中有一个 %
(恰好是 1),而您的 reports
规则中不是这种情况。 在模式规则中,先决条件中的 %
对应于规则目标中所考虑的目标的相同文本,但有一些注意事项。 这允许 GNU make
根据名称之间的关系将先决条件与目标进行匹配。
我期望 make 依次获取每个 .csv 文件(使用 %.csv),并在本示例中回显每个文件名。
想要对任意文件执行操作听起来像是脚本工作。
make
不是脚本引擎,makefile 也不是脚本。制定规则不是函数。 如果您想编写脚本,请使用 Bash、Python、Perl 或其他语言编写。
POSIX 没有指定 shell 通配符对
make
有任何意义,也没有指定任何其他类似的机制,因此可移植的 shell 脚本无法执行您所描述的操作。 然而,正如您所发现的,某些实现(尤其是 GNU 的实现)确实可以识别 shell 通配符,因此,如果您愿意将自己限制为具有该属性的 make
实现,那么您已经知道如何实现您所要求的目标。