2017-12-06 8 views
1

나는 다음과 같은 디렉토리 구조의 프로젝트를 가지고있다. 소스 파일이 $tests/*/*.e이고 대상 파일이 $doc/tests/*.rst 인 것을 지정하는 makefile에 문제점이 있습니다.메이크

몇 가지 비슷한 질문을했지만 올바른 makefile 구문을 연습 할 수 없었습니다.

이 메이크

all: $(OBJECTS) 

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

test1.rst 3 번 생성되고 test2,3.rst는 무시됩니다 즉 개체의 전체 목록을 사용할 때이 문제가있어 하나의 파일 예

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 

작동합니다. $(SOURCES)$(OBJECTS)은 정확합니다. 내가 $<(SOURCES)

를 반복하지 않는 것으로 의심 여기

 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

make -d의 출력의 일부 (이 질문은 매우 familiar-- 나는 거의 본질적으로 동일한 요청을받은 것을 맹세했던 보이는 것입니다 대답했습니다.)

단계별로 살펴 보겠습니다. 한 번에 하나씩 규칙을 작성할 수 있습니다.

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

그러나 이것은 지겹습니다. 이것은 패턴 규칙과 같은 와일드 카드 솔루션을 요구하는 종류의 상황이지만 Make의 심각한 단점 중 하나는 와일드 카드의 조잡한 처리입니다. 와일드 카드가 반복되는 패턴 규칙 :

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

은 허용되지 않습니다. 그러나 우리는 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)) 
... 

을 그리고 대신 그 eval의 모든 문장을 작성, 우리가 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