2017-12-06 11 views
1

私は、次のディレクトリ構造を持つプロジェクトを持っています。私はソースファイルが$tests/*/*.eで、宛先ファイルが$doc/tests/*.rstであることを指定してmakefileに問題があります。のMakefileは

私はいくつかの同様の質問を見たことがありますが、正しいmakefileの構文を練習することができませんでした。

このメイクファイルは、オブジェクトの完全なリストを使用しているとき、私はトラブルを抱えている単一のファイル例えば

SOURCES = $(wildcard $(tests)/*/*.e) 
OBJECTS = $(addprefix $(doc)/tests/,$(notdir $(SOURCES:.e=.rst))) 

# single file trial 
SRC = $(tests)/test1/test1.e 
OBJ = $(doc)/tests/test1.rst 

$(OBJ): $(SRC) 

debugvars: 
    @echo SOURCES=$(SOURCES) 
    @echo OBJECTS=$(OBJECTS) 

# define how to create any RST file from a testcase 
%.rst: 
    $(scripts)/wr_rst.py --infile $< 

# define how to create an RST file from a testcase 
%.rst: %.e 
    $(scripts)/wr_rst.py --infile $< 

.e.rst: 
    $(scripts)/wr_rst.py --infile $< 

.SUFFIXES: .e .rst 

を働き、すなわち

all: $(OBJECTS) 

$(OBJECTS): $(SOURCES) 
    $(scripts)/wr_rst.py --infile $< 

test1.rst 3回発生するとtest2,3.rstは無視されます。 $(SOURCES)$(OBJECTS)は正しいです。私は$<ここ

(SOURCES)上を反復しないと思われることは(この質問は非常にfamiliar--に見える私は基本的に同じものが求められていることはほぼ誓うだろう make -d

 No implicit rule found for `$tests/test3/test3.e'.         
Finished prerequisites of target file `$tests/test3/test3.e'.       
No need to remake target `$tests/test3/test3.e'.          
Considering target file `tests/test3.rst'. 
File `tests/test3.rst' does not exist. 
    Pruning file `$tests/test1/test1.e'. 
    Pruning file `$tests/test2/test2.e'. 
    Pruning file `$tests/test3/test3.e'. 
Finished prerequisites of target file `tests/test3.rst'. 
Must remake target `tests/test3.rst'. 
$scripts/wr_rst.py --inile $tests/test1/test1.e 
Putting child 0x00ee6420 (tests/test3.rst) PID 11720 on the chain. 
Live child 0x00ee6420 (tests/test3.rst) PID 11720 
Writing RST file $doc/tests/test1.rst 
Reaping winning child 0x00ee6420 PID 11720 
Removing child 0x00ee6420 PID 11720 from chain. 
Successfully remade target file `tests/test3.rst'. 
+0

実際、['$ <'は最初の前提条件に展開されます(https://www.gnu.org/software/make/manual/make.html#Automatic-Variables)、この場合は '$(テスト).test1.test1.e'。 – Beta

答えて

3

からの出力の一部であります回答しました)

これを段階的に実行しましょう。一度に1つずつルールを書くことができます:

$(doc)/tests/test1.rst: $(tests)/test1/test1.e 
    ... 

しかし、それは面倒です。これは、パターンルールなどのワイルドカードソリューションのために叫ぶ状況のようですが、Makeの重大な欠点の1つはワイルドカードの粗雑な取り扱いです。ワイルドカードを繰り返すパターンルール:

$(doc)/tests/%.rst: $(tests)/%/%.e 
    ... 

は許可されません。しかし、我々はevalを使用してルール記述することができます。代わりに、これらのeval文の全てを書くの

define template 
$(doc)/tests/$(1).rst: $(tests)/$(1)/$(1).e 
    use some tool to build [email protected] from $$< 
endef 

$(eval $(call template,test1)) 
$(eval $(call template,test2)) 
... 

をその後、我々はforeachにそのジョブを委任することができます。そして、

TESTS := test1 test2 ... 

$(foreach TEST,$(TESTS),$(eval $(call template,$(TEST))) 

の代わりに、テストのリストを書いて、我々はwildcardにあることを委任し、対象ファイルのリストを構築するために、同じリストを使用することができます。

TESTS := $(notdir $(wildcard $(tests)/*)) 
TARGETS := $(patsubst %,$(doc)/tests/%.rst,$(TESTS)) 

all: $(TARGETS) 

これらを一緒にまとめることは簡単ですが、この回答は長くなっています。

+0

ありがとうベータこれは完全に動作します。私の教育では、どのターゲットの.rstファイルに対しても、ソース/デスティネーションディレクトリに関係なく、同じ名前のeソース上のスクリプトを起動するように、新しいルールを作成する方法はありません。 '.e.rst: $(scripts)/wr_rst.py --infile $ <' – Damn