2011-06-29 16 views
14

Na czym polega problem z funkcją dep2 w poniższym przykładowym kodzie?Definiowanie niestandardowych funkcji tworzenia GNU

dep1 = $(eval makefile_list_$1 := $(MAKEFILE_LIST))$(eval -include $1.mk)$(eval MAKEFILE_LIST := $(makefile_list_$1)) 

define dep2 
$(eval makefile_list_$1 := $(MAKEFILE_LIST)) 
$(eval -include $1.mk) 
$(eval MAKEFILE_LIST := $(makefile_list_$1)) 
endef 

$(call dep1,test) 
$(call dep2,test) 

.DEFAULT_TARGET: all 
.PHONY: all 
all: 
    @echo [email protected] 

GNU make 3.81 i 3.82 produkować Makefile:10: *** missing separator. Stop. co wskazuje na wezwanie dep2, dep1 prowadzony jest bez błędów. Jedyna różnica między tymi dwoma wariantami to nowe linie w dep2 (i cały punkt, dla którego chciałbym zdefiniować).

Odpowiedz

6

zapomniałeś =:
określić dep2 =

EDIT:
postawić średnik na końcu każdej linii. Testowałem to i działa (w GNUMake 3.81).

define dep2 
$(eval makefile_list_$1 := $(MAKEFILE_LIST)); 
$(eval -include $1.mk); 
$(eval MAKEFILE_LIST := $(makefile_list_$1)); 
endef 

Dlaczego te średniki są konieczne, nie wiem, ale w dokumentacji define wydaje się być wykorzystywane do multi-line „zmiennych”, aby być stosowany w recepturach tylko przy określaniu sekwencji poleceń powłoki, nie Wykonywać polecenia, więc może zasady są trochę inne.

+0

Nie, '=' jest opcjonalne (i zostało wprowadzone tylko z GNU make 3.82). Dodanie go nie ma znaczenia. –

+0

@ g.b .: Czy próbowałeś tego? Zrobiłem (z GNU zrobić 3.81), i to miało znaczenie. Działa to zgodnie z oczekiwaniami, jeśli dodaję '='. – eriktous

+4

@eriktous: Tak, próbowałem z 3,82. Starsze wersje po prostu całkowicie zignorują instrukcję define, jeśli po niej następuje '=', dlatego nie otrzymasz komunikatu o błędzie. –

-1

Jest wiele rzeczy, które można poprawić w tym, co robisz. Z jednej strony naprawdę chcesz uwzględniać połączenia eval do pojedynczego połączenia na górze.

Twój szczególny problem wynika jednak z niezrozumienia, że ​​wielowierszowy łańcuch rekursywny, którego użyto do definiowania komend make, nigdy nie zawiera nowej linii lady. Najbardziej naturalnym konwencja do pisania funkcje evalable jest

zdefiniowanie Foo line1 line2

endef

Możesz zajrzeć eval ciąg widzi i zobaczyć co to robi za pomocą polecenia informacyjnym, np $ (info $ (zadzwoń do Foo, x) $ (zadzwoń do Foo, y)).

1

Pozwoliłbym przenieść wywołania $(eval ...) poza dep2. Robiąc to w ten sposób, nie ma potrzeby stosowania średników w dep2. Oznacza to podwojenie znaków niektórych rozszerzeń, aby uniknąć zbyt szybkiego rozwijania. A więc:

define dep2 
makefile_list_$1 := $$(MAKEFILE_LIST) 
-include $1.mk 
MAKEFILE_LIST := $$(makefile_list_$1) 
endef 

$(eval $(call dep2,test)) 

# Quick checks for testing, to be removed from the final code... 
$(info $(makefile_list_test)) 
$(info $(MAKEFILE_LIST)) 

.DEFAULT_TARGET: all 
.PHONY: all 
all: 
    @echo [email protected] 

Testowałem powyższy kod i działa on z Gnu Make 4.0. Spodziewam się, że wróci do Gnu Make 3.8x. Wzorzec $(eval $(call ...)) jest tym, co zawsze robię, aby wykonywać moje niestandardowe funkcje i używam go już od jakiegoś czasu.

Powiązane problemy