1

私は、 http: //www.cmcrossroads.com/article/atomic-rules-gnu-make? page=0%2C0 にある「GNU Make のアトミック ルール」に関する John Graham-Cumming の優れた記事を使用しようとしています。

ただし、次のような単純なレシピのない別のルールを使用して、2 つのファイル間の依存関係を指定する必要がある場合があります。

a : b

これは常に期待どおりに機能しますが、2 つのアトミック ルール間の依存関係を指定すると、惨めに失敗します。以下は、3 つのテストケースを含む単純な Makefile です。

atomic = $(eval $1: $(firstword $1).sentinel ; @:) \
         $(firstword $1).sentinel : $2 ; touch $$@ \
         $(foreach _, $1, $(if $(wildcard $_), , $(shell rm -f $(firstword $1).sentinel)))

d1 d2 d3:
    touch $@

## Test case 1 using sentinel and dependency (u1 u2 : t1 t2) specified in call to atomic
$(call atomic, t1 t2, d1)
    touch t1 t2

$(call atomic, u1 u2, t1 t2)
    touch u1 u2

## Test case 2 using sentinel and dependency (w1 w2 : v1 v2) specified as another rule does not work
$(call atomic, v1 v2, d2)
    touch v1 v2

$(call atomic, w1 w2, )
    touch w1 w2

w1 w2 : v1 v2

## Test case 3 showing that specifying a dependency (y1 : x1) with another rule does work
x1 : d3
    touch x1

y1 :
    touch y1

y1 : x1

##

clean :
    rm -f {d,t,u,v,w,x,y}{1,2,3}{,.sentinel} test{1,2,3}

test1 : u1
    touch test1

test2 : w1
    touch test2

test3 : y1
    touch test3

最初のテストケースは正しいことを行い、期待される順序ですべてをビルドします

> make test1
touch d1
touch t1.sentinel      
touch t1 t2
touch u1.sentinel      
touch u1 u2
touch test1

2 番目のテストケースは、物事を間違った順序で構築することにより、アトミック ルールに対して惨めに失敗します。

> make test2
touch w1.sentinel      
touch w1 w2
touch d2
touch v1.sentinel      
touch v1 v2
touch test2

3 番目の単純なテストケースは、別のルールを使用して依存関係を指定することが機能することを証明します。

> make test3
touch d3
touch x1
touch y1
touch test3

なぜこれが起こっているのか誰でも説明できますか?さらに良いことに、test2 が test1 と同じように動作するように、誰かが回避策を思い付くことができますか? 私は本当に立ち往生しています。

ありがとう、トム

4

1 に答える 1