首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“制造”每隔一次失败一次

“制造”每隔一次失败一次
EN

Stack Overflow用户
提问于 2021-07-07 10:17:03
回答 1查看 72关注 0票数 0

在下面的情况下,是什么导致make每隔一次失败(因此每隔一次就成功一次)?

约简Makefile

代码语言:javascript
复制
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调用的控制台输出:

代码语言:javascript
复制
# 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

  1. 缺失部分

代码语言:javascript
复制
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)

有趣的是,当

  1. make clean helm/external_dns每隔一次失败一次,make clean; make helm/external_dns每次都会成功。在Makefile的上述部分中,
  2. 增加了对helmfile编号的支持(添加前缀NN_,其中NN是从00到99的2位数字,按字母顺序排列)。代码的原始部分是:

代码语言:javascript
复制
helm/%: $(HELMFILE_DIR)/%.yaml
    @echo $@
$(HELMFILE_DIR)/%.yaml: services/helm/%/*.yaml | $(HELMFILE_DIR)
    cp $? $@
$(HELMFILE_DIR):
    mkdir -p $(HELMFILE_DIR)

文件系统的

  1. 状态:

代码语言:javascript
复制
# 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

我希望这是足够的信息来重新讨论这个问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-09 09:00:41

问题的根本原因是通配符匹配。第一次,当./helm/40_external_dns.yaml不存在时,该模式与任何现有文件不匹配,因此它保持原样:

代码语言:javascript
复制
$ 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。你自己看看:

代码语言:javascript
复制
$ 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的原因完全相同。例如,见:

代码语言:javascript
复制
$ 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扩展,例如:

代码语言:javascript
复制
$ 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)

输出:

代码语言:javascript
复制
$ 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_dns
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68284119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档