0

そのため、いくつかのファイル (*.in) を C++ プログラムへの入力として受け取り、それらの出力 (result.out) を特定の正しい出力 (*.out) と比較するメイクファイルを作成しています。具体的には、ファイル t01.in、t02.in、t03.in、t04.in、および t05.in があります。$TESTIN = t01.in t02.in t03.in t04.in t05.in であることを確認しました。問題は、これらのファイルのうち 1、3、4 の 3 つのファイルに対してのみ %.in: %.out ブロックを実行しているように見えることです。

OUTPUT = chart
COMPILER = g++
SOURCES = chart.cpp
HEADERS = 
OBJS = $(SOURCES:.cpp=.o)
TESTIN = tests/*.in


all: $(OUTPUT)

$(OUTPUT): $(OBJS)
    $(COMPILER) *.o -o $(OUTPUT)

%.o: %.cpp
    clear
    $(COMPILER) -c $< -o $@


test: $(TESTIN)

%.in: %.out
    ./$(OUTPUT) < $@ > tests/results.out
    printf "\n"
ifeq ($(diff $< tests/results.out), ) 
    printf "\tTest of "$@" succeeded for stdout.\n"
else
    printf "\tTest of "$@" FAILED for stdout!\n"
endif

さらに、私がやろうとしていることを達成するためのより良い方法、またはこのメイクファイルに加えることができるその他の改善がある場合 (私はかなり新しいので)、提案をいただければ幸いです。

編集: ブロック (%.in: %.out %.err) に 2 番目の依存関係を追加すると、5 つのファイルすべてに対してブロックが実行されます。なぜこのように機能するのかはまだわかりませんが、以前の方法では機能しません。

4

1 に答える 1

1

まず、TESTINどのように正しいかわかりません。この行:

TESTIN = tests/*.in

Make では有効なワイルドカード ステートメントではありません。TESTIN変数に値を与える必要がありますtests/*.in。しかし、これらのファイルが実際にある場所の値がt01.in t02.in t03.in t04.in t05.inorであるとしましょう。tests/t01.in tests/t02.in tests/t03.in tests/t04.in tests/t05.in

次に、 @OliCharlesworth が指摘するように、このルールは次のとおりです。

%.in: %.out
    ...

*.in ファイルを作成するための規則ですが、これは意図したものではありません。いくつかのテストを実行し、他のテストを実行しない理由については、私の理論は次のとおりです。

のタイムスタンプは のタイムスタンプt01.outよりも遅いt01.inため、Make は を「再構築」する必要があると判断しt01.inます。同様t03.inに とt04.in. しかし、 のタイムスタンプは のタイムスタンプt02.outよりも古いt02.inため、Make は を「再構築」しようとしませんt02.in。同様t05.inに。とのタイムスタンプはそれぞれt02.errとのタイムスタンプt05.errよりも遅いため、前提条件を追加するとt02.in、Make はすべてのテストを実行します。タイムスタンプをチェックして を試すことで、この理論をテストできます。t05.in%.errtouch

とにかく書き直しましょう。新しいルールには新しいターゲットが必要です:

TESTS := $(patsubst %.in,test_%,$(TESTIN)) # test_t01 test_t02 ...

.PHONY: $(TESTS) # because there will be no files called test_t01, test_t02,...

$(TESTS): test_%: %.in %.out
    ./$(OUTPUT) < $< > tests/results.out

今、条件のために。試行された条件は Make 構文にあります。Make はルールを実行する前にそれを評価するためtests/result.out、まだ存在せず、変数のようなもの$<はまだ定義されていません。シェル構文で、コマンド内に条件を配置する必要があります。

$(TESTS): test_%: %.in %.out
    ./$(OUTPUT) < $< > tests/results.out
    if diff $*.out tests/results.out >/dev/null; then \
  echo Test of $* succeeded for stdout.; \
  else echo Test of $* FAILED for stdout!; \
  fi

(条件の最初の行のみが TAB で始まる必要があることに注意してください。)

于 2013-08-11T01:20:50.033 に答える