在下面的情况下,是什么导致make每隔一次失败(因此每隔一次就成功一次)?
约简Makefile
helm/%: $(HELMFILE_DIR)/[0-9][0-9]_%.yaml
@echo $@
$(HELMFILE_DIR)/[0-9][0-9]_%.yaml: services/helm/%/[0-9][0-9]_*.yaml | $(HELMFILE_DIR)
cp $? $(HELMFILE_DIR)/
$(HELMFILE_DIR):
mkdir -p $(HELMFILE_DIR)来自4个连续make clean helm/external_dns调用的控制台输出:
# make clean helm/external_dns
rm -rf ./helm
mkdir -p ./helm/helmfile.d
cp services/helm/external_dns/40_external_dns.yaml ./helm/helmfile.d/
helm/external_dns
# make clean helm/external_dns
rm -rf ./helm
make: *** No rule to make target 'helm/helmfile.d/40_external_dns.yaml', needed by 'helm/external_dns'. Stop.
# make clean helm/external_dns
rm -rf ./helm
mkdir -p ./helm/helmfile.d
cp services/helm/external_dns/40_external_dns.yaml ./helm/helmfile.d/
helm/external_dns
# make clean helm/external_dns
rm -rf ./helm
make: *** No rule to make target 'helm/helmfile.d/40_external_dns.yaml', needed by 'helm/external_dns'. Stop.编辑-更多信息:
Makefile的
HELM_DIR := ./helm
HELMFILE_DIR := $(HELM_DIR)/helmfile.d
.PHONY: build clean
.PRECIOUS: $(HELMFILE_DIR)/%.yaml $(HELMFILE_DIR)/%.values.yaml.gotmpl
clean:
rm -rf $(HELM_DIR)有趣的是,当
make clean helm/external_dns每隔一次失败一次,make clean; make helm/external_dns每次都会成功。在Makefile的上述部分中,NN_,其中NN是从00到99的2位数字,按字母顺序排列)。代码的原始部分是:helm/%: $(HELMFILE_DIR)/%.yaml
@echo $@
$(HELMFILE_DIR)/%.yaml: services/helm/%/*.yaml | $(HELMFILE_DIR)
cp $? $@
$(HELMFILE_DIR):
mkdir -p $(HELMFILE_DIR)文件系统的
# make clean
rm -rf ./helm
# tree
.
├── Makefile
├── services
│ └── helm
│ └── external_dns
│ └── 40_external_dns.yaml
# make clean helm/external_dns
rm -rf ./helm
mkdir -p ./helm/helmfile.d
cp services/helm/external_dns/40_external_dns.yaml ./helm/helmfile.d/
helm/external_dns
# tree
.
├── Makefile
├── helm
│ └── helmfile.d
│ └── 40_external_dns.yaml
├── services
│ └── helm
│ └── external_dns
│ └── 40_external_dns.yaml
# make clean helm/external_dns
rm -rf ./helm
make: *** No rule to make target 'helm/helmfile.d/40_external_dns.yaml', needed by 'helm/external_dns'. Stop.
# tree
.
├── Makefile
├── services
│ └── helm
│ └── external_dns
│ └── 40_external_dns.yaml我希望这是足够的信息来重新讨论这个问题。
发布于 2021-07-09 09:00:41
问题的根本原因是通配符匹配。第一次,当./helm/40_external_dns.yaml不存在时,该模式与任何现有文件不匹配,因此它保持原样:
$ make clean helm/external_dns -dpr
...
Considering target file 'helm/external_dns'.
File 'helm/external_dns' does not exist.
Looking for an implicit rule for 'helm/external_dns'.
Trying pattern rule with stem 'external_dns'.
Trying implicit prerequisite 'helm/helmfile.d/[0-9][0-9]_external_dns.yaml'.
Trying pattern rule with stem 'external_dns'.
Trying implicit prerequisite 'helm/helmfile.d/[0-9][0-9]_external_dns.yaml'.
Looking for a rule with intermediate file 'helm/helmfile.d/[0-9][0-9]_external_dns.yaml'.
Avoiding implicit rule recursion.
Trying pattern rule with stem 'external_dns'.
Trying implicit prerequisite 'services/helm/external_dns/40_external_dns.yaml'.
Trying rule prerequisite 'helm/helmfile.d'.
Found an implicit rule for 'helm/external_dns'.
...
helm/external_dns: helm/helmfile.d/[0-9][0-9]_external_dns.yaml
# Command line target.
# Implicit rule search has been done.
# Implicit/static pattern stem: 'external_dns'
# File does not exist.
# File has been updated.
# Successfully updated.
...
# automatic
# < := helm/helmfile.d/[0-9][0-9]_external_dns.yaml
...
# recipe to execute (from 'Makefile', line 5):
@echo $@但是,在第二次调用时,文件./helm/40_external_dns.yaml确实存在,因此它与通配符匹配,并且正在被解析。所以现在helm/external_dns不依赖于helm/helmfile.d/[0-9][0-9]_external_dns.yaml,而是依赖于helm/helmfile.d/40_external_dns.yaml。你自己看看:
$ make clean helm/external_dns -dpr
...
Considering target file 'helm/external_dns'.
File 'helm/external_dns' does not exist.
Looking for an implicit rule for 'helm/external_dns'.
Trying pattern rule with stem 'external_dns'.
Trying implicit prerequisite 'helm/helmfile.d/40_external_dns.yaml'.
Found an implicit rule for 'helm/external_dns'.
Considering target file 'helm/helmfile.d/40_external_dns.yaml'.
File 'helm/helmfile.d/40_external_dns.yaml' does not exist.
Looking for an implicit rule for 'helm/helmfile.d/40_external_dns.yaml'.
Trying pattern rule with stem 'helmfile.d/40_external_dns.yaml'.
Trying implicit prerequisite 'helm/helmfile.d/[0-9][0-9]_helmfile.d/40_external_dns.yaml.yaml'.
Trying pattern rule with stem 'helmfile.d/40_external_dns.yaml'.
Trying implicit prerequisite 'helm/helmfile.d/[0-9][0-9]_helmfile.d/40_external_dns.yaml.yaml'.
Looking for a rule with intermediate file 'helm/helmfile.d/[0-9][0-9]_helmfile.d/40_external_dns.yaml.yaml'.
Avoiding implicit rule recursion.
Trying pattern rule with stem 'helmfile.d/40_external_dns.yaml'.
Trying implicit prerequisite 'services/helm/helmfile.d/40_external_dns.yaml/[0-9][0-9]_*.yaml'.
Trying pattern rule with stem 'helmfile.d/40_external_dns.yaml'.
Trying implicit prerequisite 'services/helm/helmfile.d/40_external_dns.yaml/[0-9][0-9]_*.yaml'.
Looking for a rule with intermediate file 'services/helm/helmfile.d/40_external_dns.yaml/[0-9][0-9]_*.yaml'.
Avoiding implicit rule recursion.
Avoiding implicit rule recursion.
No implicit rule found for 'helm/helmfile.d/40_external_dns.yaml'.
Finished prerequisites of target file 'helm/helmfile.d/40_external_dns.yaml'.
Must remake target 'helm/helmfile.d/40_external_dns.yaml'.
make: *** No rule to make target 'helm/helmfile.d/40_external_dns.yaml', needed by 'helm/external_dns'. Stop.
...
helm/external_dns: helm/helmfile.d/40_external_dns.yaml
# Command line target.
# Implicit rule search has been done.
# Implicit/static pattern stem: 'external_dns'
# File does not exist.
# File has not been updated.
# recipe to execute (from 'Makefile', line 5):
@echo $@
...
# Not a target:
helm/helmfile.d/40_external_dns.yaml:
# Implicit rule search has been done.
# File does not exist.
# File has not been updated.主要的一点是,glob模式不是常规的make特性,正如您所看到的,在扩展它们时有一些注意事项。顺便说一下,clean并不是唯一失败的东西。在随后的调用中,如果源文件发生更改,您的文件也不会被更新,原因与依赖40_external_dns.yaml不是[0-9][0-9]_external_dns.yaml的原因完全相同。例如,见:
$ make helm/external_dns
mkdir -p ./helm/helmfile.d
cp services/helm/external_dns/40_external_dns.yaml ./helm/helmfile.d/
helm/external_dns
# Edit the original file
$ touch services/helm/external_dns/40_external_dns.yaml
# Note that it is not copied
$ make helm/external_dns
helm/external_dns这种文件结构通过将部分文件名作为源目录名来增加复杂性,但是我将计算目标文件名,以准确地知道必须复制什么而不是随机的glob扩展,例如:
$ cat Makefile
HELM_DIR := ./helm
HELMFILE_DIR := $(HELM_DIR)/helmfile.d
.SECONDEXPANSION:
.PHONY: helm/%
helm/%: $$(addprefix $(HELMFILE_DIR)/,$$(notdir $$(wildcard services/helm/$$*/[0-9][0-9]_$$*.yaml)))
@echo $@
.PRECIOUS: $(HELMFILE_DIR)/%.yaml
$(HELMFILE_DIR)/%.yaml: $$(wildcard services/helm/$$(subst $$(firstword $$(subst _, ,$$*))_,,$$*)/$$*.yaml) | $(HELMFILE_DIR)
cp $< $@
$(HELMFILE_DIR):
mkdir -p $(HELMFILE_DIR)
.PHONY: clean
clean:
rm -rf $(HELM_DIR)输出:
$ make helm/external_dns
mkdir -p ./helm/helmfile.d
cp services/helm/external_dns/40_external_dns.yaml helm/helmfile.d/40_external_dns.yaml
helm/external_dns
# Nothing to do on next call
$ make helm/external_dns
helm/external_dns
# Update file if changed
$ touch services/helm/external_dns/40_external_dns.yaml
$ make helm/external_dns
cp services/helm/external_dns/40_external_dns.yaml helm/helmfile.d/40_external_dns.yaml
helm/external_dns
# And the clean is fixed
$ make clean helm/external_dns
rm -rf ./helm
mkdir -p ./helm/helmfile.d
cp services/helm/external_dns/40_external_dns.yaml helm/helmfile.d/40_external_dns.yaml
helm/external_dns
$ make clean helm/external_dns
rm -rf ./helm
mkdir -p ./helm/helmfile.d
cp services/helm/external_dns/40_external_dns.yaml helm/helmfile.d/40_external_dns.yaml
helm/external_dnshttps://stackoverflow.com/questions/68284119
复制相似问题