1

バックグラウンド

回帰スイートの一部としてMakefilesを使用します。デフォルトのルールがいくつかあります。

%.tmp_expect: ...
    @echo "Rule that produces results from the current tool version"

%.tmp_expect_filter: %.tmp_expect
    @echo "Take $*.tmp_expect and remove content specific to the machine/date"

%.tmp_expect_filter_sort: %.tmp_expect_filter
    @echo "Rule to sort $*.tmp_expect_filter"

次に、これらのルールはトップレベルのルールによって使用されます。

%.do: %.tmp_expect_filter_sort
    @echo "Create output using current version and diff against expected output"
    @diff $< $*.expect

%.genexpect: %.tmp_expect_filter_sort
    @echo "Generate 'goldstandard' expected output"
    @cp $< $*.expect

「genexpect」ルールはテストケースに対して1回呼び出され、テストに対して「ゴールドスタンダード」出力と呼ばれるものを生成します。開発が進むにつれて、「do」ルールは、現在のバージョンが「goldstandard」と同じ出力を生成することを確認します。

これらのルールはすべて、独自の特別なファイル「Make.Test」に保存され、回帰テストのあるディレクトリのMakefilesにそのファイルを含めます。

問題

デフォルトの%.tmp_expectで提供されるものとは少し異なる出力が必要になる場合があります。これを行うには、ローカルのMakefileに独自の%.tmp_expectルールを実装させます。これは、関心のあるすべてのプラットフォーム(Windows、Linux、Solaris)で機能します。

ただし、出力を並べ替えたくない場合は、次のようなルールを追加できると思います。

%.tmp_expect_filter_sort: %.tmp_expect_filter
    @cp $< $@

これは物事がかなり奇妙になるところです。プラットフォームに応じて、このルールが「Make.Test」ファイルを含める前または後に表示される場合は、選択されている場合とされていない場合があります。

だから私の質問は:

  1. 特定のターゲットに使用するルールをどのように決定しますか?
  2. どのルールを選択するかを制御できるように、ルールをどのように作成すればよいですか?
4

2 に答える 2

2

1)GNU Makeマニュアルから、複数のパターンルールがターゲットに一致する場合(およびそれらの一致する部分が同じ長さである場合)、Makeは最初に来るものを選択します。include Make.testしたがって、特別なルールの前にいる場合は、Make.testルールが優先されます。

プラットフォームに異なるバージョンのMakeがない限り、結果がプラットフォームに依存する理由はわかりません。

2)マニュアルは、私が「粗雑だが効果的」と呼ぶ方法を提案しています。の代わりにinclude Make.test、次のルールを追加します。

%: force
         @$(MAKE) -f Make.test $@
force: ;

つまり、特定のターゲットにローカルルールがない場合にのみ、Makeusingを再度呼び出しMake.testます。はい、これはRecursiveMakeです。いいえ、それはあなたを殺すことはありません、それはほんの少し非効率的です。

于 2012-05-01T13:56:16.897 に答える
1

最新バージョンのmake(バージョン3.81以降)を使用してこれを行う方法を発見しました。

.SECONDEXPANSIONと呼ばれる新しい特別なターゲットがあります。これは、ルールを選択するのに役立つ変数とともに使用できます。

ルールを更新して、前提条件の名前の一部として変数展開を含めることができます。

%.tmp_expect_filter: %.tmp_expect
    @echo "Take $*.tmp_expect and remove content specific to the machine/date"


.SECONDEXPANSION:
%.tmp_expect_filter_sort: %.tmp_expect_filter$$($$*_FILTER_RULE)
    @cat '$<' | sort -n -t: -k 2 -k 3 > '$@'

これについての私の大まかな理解は、ターゲットが決定された後、$ *が前提条件で置き換えられ、次に2回目に展開されるということです。

たとえば、ターゲット内のbar.tmp_expect_filter_sortは、結果として。$*に置き換えられます。実際に設定されていない限り、何も展開されず、デフォルトのルールが使用されます。bar%.tmp_expect_filter$(bar_FILTER_RULE)bar_FILTER_RULE

特別なルールを使用するために、ローカルのMakefileで変数を定義できます。

bar_FILTER_RULE=_custom
%.tmp_expect_filter_sort_custom:
    @echo My custom rule here....

2番目の拡張が結果として生じる%.tmp_expect_filter_sort_customため、カスタムルールが使用されます。

于 2012-05-03T15:22:12.610 に答える