我希望自己没有把自己画成一个角落。通过实现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)不是目标,因此当$(BOMS)规则更新签名时make不会注意到。
我尝试创建一个.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
但是当从BOM创建SIG时,BOM如何依赖于SIG?正如我读到的那样,“从BOM中创建SIG,如果SIG比BOM更新,那么请检查BOM”。我该如何引导该过程?第一个BOM来自哪里?
答案 0 :(得分:1)
Make能够检测实际的文件更改非常糟糕,而不仅仅是更新的时间戳。
对我来说,问题的根源是bom-checkout总是修改bom的时间戳,导致重新生成依赖关系。我可能会尝试解决这个问题 - 尝试检查bom而不会弄乱时间戳。结帐工具周围的包装脚本可能会起作用;首先将bom签出到临时文件,将其与已检出的版本进行比较,并仅在新版本不同时替换它。
如果您没有严格限制使用make,那么还有其他工具可以更好地检测实际文件更改(例如,SCons)。
答案 1 :(得分:0)
我不是制作专家,但我会尝试让$(BOMS)依赖于$(SIGS),并使$(SIGS)目标执行你目前在$(BOMS)下的if / else规则)目标。
$(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
编辑:你是对的,当然,你不能让$(BOM)依赖于$(SIGS)。但是为了重新创建$(DEP),您需要将$(SIG)作为目标。也许有一个中间目标,它取决于$(BOM)和$(SIG)。
$(DEP) : $(SIGS)
... recreate dependency
$(NEWTARGET) : $(BOMS) $(SIGS)
$(BOMS) :
...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
$(SIGS)可能还需要依赖于$(BOMS),我会玩那个并看看。