我希望我没有把自己画到角落里。我已经通过实现 Makefile 获得了似乎大部分的方法,但我无法让最后一点工作。我希望这里有人可以提出一种技术来做我想做的事情。
我在源存储库的版本控制文件中有我称之为“材料清单”的东西,我构建了类似的东西:
make VER=x
我希望我的 Makefile 使用 $(VER) 作为标签来从存储库中检索 BOM,生成要包含在 Makefile 中的依赖文件,重新扫描包含该依赖项,然后构建产品。
更一般地说,我的 Makefile 可能有几个目标——A、B、C 等——我可以构建每个目标的不同版本,所以我可以这样做:
make A VER=x
make B VER=y
make C VER=z
依赖文件包含所有三个目标的信息。
但是,创建依赖文件有点昂贵,所以如果我这样做:
make A VER=x
...make source (not BOM) changes...
make A VER=x
我真的很希望 Makefile 不重新生成依赖项。为了使事情尽可能复杂,我可能会这样做:
make A VER=x
.. change version x of A's BOM and check it in
make A VER=x
所以我需要重新生成对第二个构建的依赖。
签出弄乱了用于重新生成依赖项的时间戳,所以我认为我需要一种方法让依赖项文件不依赖于 BOM,而是依赖于 BOM 更改的某些指示。
我所做的是让 BOM 签出发生在 .PHONY 目标中(因此它总是被签出)并跟踪“.sig”文件中最后一次签出的内容(如果签名文件丢失或内容与新文件的签名不同,然后 BOM 更改),并且依赖项生成取决于签名)。在我的 Makefile 顶部,我有一些设置:
BOMS = $(addsuffix .bom,$(MAKECMDGOALS)
SIGS = $(subst .bom,.sig,$(BOMS))
DEP = include.d
-include $(DEP)
看来我总是需要做:
.PHONY: $(BOMS)
$(BOMS):
...checkout TAG=$(VER) $@
但是,如上所述,如果我这样做,然后继续:
$(DEP) : $(BOMS)
... recreate dependency
然后每次我调用 make 时都会更新依赖项。所以我尝试:
$(DEP) : $(SIGS)
... recreate dependency
和
$(BOMS):
...checkout TAG=$(VER) $@
...if $(subst .bom,.sig,$@) doesn't exist
... create signature file
...else
... if new signature is different from file contents
... update signature file
... endif
...endif
但是当签名改变时,依赖生成不会被触发。我认为这是因为 $(SIGS) 不是目标,所以 make 不会注意到 $(BOMS) 规则何时更新签名。
我尝试创建一个 .sig:.bom 规则并通过触摸管理签出 BOM 的时间戳,但这不起作用。
有人提出了类似的建议:
$(DEP) : $(SIGS)
... recreate dependency
$(BOMS) : $(SIGS)
...checkout TAG=$(VER) $@
$(SIGS) :
...if $(subst .bom,.sig,$(BOMS)) doesn't exist
... create it
...else
... if new signature is different from file contents
... update signature file
... endif
...endif
但是当 SIG 是从 BOM 创建时,BOM 如何依赖于 SIG?正如我读到的那样,“从 BOM 创建 SIG,如果 SIG 比 BOM 更新,则检查 BOM”。我如何引导该过程?第一个 BOM 来自哪里?