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

依存関係ファイルには、3つのターゲットすべてに関する情報が含まれています。

ただし、依存関係ファイルの作成には多少の費用がかかるため、次のようにします。

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

したがって、2番目のビルドへの依存関係を再生成する必要があります。

チェックアウトにより、依存関係の再生成に使用されるタイムスタンプが台無しになるため、依存関係ファイルが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

しかし、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

私は make の専門家ではありませんが、$(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 に答える