Dependencies 如何使用一个Makefile高效地构建不同版本的组件

Dependencies 如何使用一个Makefile高效地构建不同版本的组件,dependencies,makefile,Dependencies,Makefile,我希望我没有把自己画成一个角落。我已经通过实现一个Makefile获得了看起来最有用的东西,但我无法完成最后一点工作。我希望这里有人能建议一种技巧来做我想做的事情 我在源存储库中的版本控制文件中有我称之为“物料清单”的内容,我构建了如下内容: make VER=x $(DEP) : $(SIGS) ... recreate dependency $(BOMS) : $(SIGS) ...checkout TAG=$(VER) $@ $(SIGS) : ...if $(s

我希望我没有把自己画成一个角落。我已经通过实现一个Makefile获得了看起来最有用的东西,但我无法完成最后一点工作。我希望这里有人能建议一种技巧来做我想做的事情

我在源存储库中的版本控制文件中有我称之为“物料清单”的内容,我构建了如下内容:

make VER=x
$(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
我希望我的Makefile使用$(VER)作为标记,从存储库中检索BOM表,生成要包含在Makefile中的依赖项文件,重新扫描该依赖项,然后构建产品

更一般地说,我的Makefile可能有几个目标——A、B、C等,我可以为每个目标构建不同的版本,因此我可以:

make A VER=x
make B VER=y
make C VER=z
make A VER=x
.. change version x of A's BOM and check it in
make A VER=x
依赖项文件包含关于所有三个目标的信息

但是,创建依赖项文件有点昂贵,因此如果我这样做:

make A VER=x
...make source (not BOM) changes...
make A VER=x
我真的希望Makefile不重新生成依赖项。为了使事情尽可能复杂,我可能会:

make A VER=x
make B VER=y
make C VER=z
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

但是当签名更改时,依赖项生成不会出错。我认为这是因为$(SIGS)不是目标,所以make不会注意到$(BOMS)规则何时更新签名

我尝试创建一个.sig:.bom规则,并用touch管理签出的bom的时间戳,但没有成功

有人提出如下建议:

make VER=x
$(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来自哪里?

我不是make专家,但我会尝试让$(BOM)依赖于$(SIGS),并让$(SIGS)目标执行您当前在$(BOM)目标下的if/else规则

编辑:你是对的,当然,你不能让$(BOM)依赖$(SIGS)。但是为了让$(DEP)重新创建,您需要将$(SIG)作为目标。可能有一个同时依赖于$(BOM)和$(SIG)的中间目标


$(SIGS)可能还需要依赖于$(BOMS),我将使用它,看看。

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

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

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