2

我希望我没有把自己画到角落里。我已经通过实现 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 来自哪里?

4

2 回答 2

1

Make 在检测实际文件更改方面非常糟糕,而不仅仅是更新的时间戳。

在我看来,问题的根源在于 bom-checkout 总是会修改 bom 的时间戳,从而导致重新生成依赖项。我可能会尝试解决这个问题——尝试在不弄乱时间戳的情况下签出 bom。结帐工具周围的包装脚本可能会起作用;首先将 bom 签出到一个临时文件,将其与已签出的版本进行比较,仅当新版本不同时才替换它。

如果您没有严格限制使用 make,那么还有其他工具可以更好地检测实际文件更改(例如 SCons)。

于 2008-09-17T20:30:02.613 回答
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),我会用它看看。

于 2008-09-16T12:15:39.473 回答