2

公正な警告: 私はメイクファイルを使用するのが初めてなので、これは明らかなことかもしれません。私がやろうとしているのは、その生成ツールのソース ファイル (.abc ファイルと呼びます) が変更されたときだけ、make を使用してサードパーティのコード生成ツールを実行することです。MD5 のビルド方法を示すhttp://www.cmcrossroads.com/ask-mr-make/6795-rebuilding-when-a-files-checksum-changesの例を参照し、アイデアを少し調整しました。

ファイル: abc.mk

target = all
files    := $(wildcard Abc/*.abc)
bltfiles := $files $(addsuffix .built,$files)

all: $bltfiles

%.built: %.abc %.abc.md5
    @echo "Building $*"
    @ #Command that generates code from a .abc file
    @touch $@

%.md5: FORCE
    @echo "Checking $* for changes..."
    @ #Command to update the .md5 file, if the sum of the .abc file is different

FORCE:

私が意図しているのは、各 .abc ファイルに .abc.built と .abc.md5 の 2 つの補助ファイルを含めることです。.built ファイルは、生成ツールによって生成されたコードをターゲットとして簡単に定義できないため、最後にビルドされたときのダミーのターゲットとタイムスタンプにすぎません。.md5 ファイルには、.abc ファイルの最後の既知のコンテンツのハッシュが含まれています。ファイルのハッシュが変更された場合にのみ更新する必要があります。

ただし、.built ファイルは、存在しない場合にのみ作成されます。.md5 ルールはまったく実行されず、.abc ファイルのタイムスタンプが新しい場合でも、.built ルールは再構築されません。私は何か間違ったことをしていますか?

更新: 後世のために、ここに私が仕事をしたバージョンがあります:

ファイル: abc.mk

# Call this makefile as: make all --file=abc.mk

# Default Target
target = all

COMP_ABC_FILES := $(wildcard Abc/*.abc)
COMP_BLT_FILES := $(COMP_ABC_FILES) $(addsuffix .built, $(COMP_ABC_FILES) )

# This line is needed to keep make from deleting intermediary output files:
.SECONDARY: 

# Targets:
.PHONY: all
all: $(COMP_BLT_FILES)

Abc/%.abc.built: Abc/%.abc Abc/%.abc.md5
    @echo "Building $*"
    @ #Command that generates code from a .abc file
    @touch $@

%.md5: FORCE
    @echo "Checking $* for changes..."
    @$(if $(filter-out $(shell cat $@ 2>/dev/null),$(shell md5sum $*)),md5sum $* > $@)

# Empty rule to force re-build of files:
FORCE:

clean:
    @echo "Cleaning .built & .md5 files..."
    @rm Abc/*.built
    @rm Abc/*.md5
4

2 に答える 2

1

次の 3 か所でメイクファイルを修正します。

target = all
files    := $(wildcard Abc/*.abc)
bltfiles := $(files) $(patsubst %.abc,%.built,$(files))

all: $(bltfiles)

#Abc/%.abc.built: Abc/%.abc Abc/%.abc.md5
%.built: %.abc %.abc.md5
    @echo "Building $*"
    @ #Command that generates code from a .abc file
    @touch $@

%.md5: FORCE
    @echo "Checking $* for changes..."
    @ #Command to update the .md5 file, if the sum of the .abc file is different

FORCE:

変更点に注意してください:

  1. bltfiles := $(files) $(patsubst %.abc,%.built,$(files))

    %.built"Abc/a.abc.built Abc/b.abc.built" の代わりに "Abc/ a.built Abc/b.built" という結果になります。

  2. all: $(bltfiles)

    上記のように$(files)、'$bltfiles' は である必要が$(bltfiles)あり$(f)ilesまし$(b)ltfilesた。

ヒント: ここでは、makefile の構文を強調表示するエディターがあると便利です。


デモ

mkdir -pv Abc; touch Abc/{a,b,c,d,e,f,g}.abc
make -Bs -f abc.mk

のような出力

Checking Abc/e.abc for changes...
Building Abc/e
Checking Abc/g.abc for changes...
Building Abc/g
Checking Abc/b.abc for changes...
Building Abc/b
Checking Abc/f.abc for changes...
Building Abc/f
Checking Abc/a.abc for changes...
Building Abc/a
Checking Abc/c.abc for changes...
Building Abc/c
Checking Abc/d.abc for changes...
Building Abc/d
于 2012-10-08T16:58:57.287 に答える
0

Sehe が修正しましたが、説明しませんでした: Makefile の構文は、シェルの構文と同じではありません。デフォルトでは (歴史から失われた理由により) make 変数の長さは 1 文字のみです。より長い変数名が必要な場合は、正しく解析されるように括弧で囲む必要があります。$filesたとえば、 を記述すると、文字列 "iles" が実際に展開されます。これは、make が "f" 変数 (空) の値のみを解析して展開するためです。

はい、変です。しかし、それがmakeの仕組みです。変数は常に括弧に入れてください。

于 2012-10-08T17:03:46.340 に答える