2009-09-09 25 views
16

Jak uzyskać nazwę pliku Makefile w pliku Makefile?Pobieranie nazwy pliku Makefile z pliku Makefile

Dzięki.

Uwaga:

byłyby potrzebne, bo chciałbym mój makefile nazywać siebie, ale makefile nie nazywa Makefile, więc chciałbym napisać coś takiego:

target: 
    ($MAKE) -f ($MAKEFILENAME) other_target 
+0

Czy mogę zapytać, dlaczego tego potrzebujesz? – erelender

Odpowiedz

10
location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) 
WHERE_ART_THOU := $(location) 
$(warning $(WHERE_ART_THOU)) 

Wierzę również, że jest to specyficzne dla GNU, ale nie jestem zbyt pewny.

+1

To rozwiązanie nie działa, jeśli zaznaczysz nazwę pliku Makefile po dodaniu kolejnego pliku Makefile! (komentarz sklejony) –

+0

Działa, jeśli poprawisz pierwszą linię: jest to "$ (słowa" zamiast "($ words", a na końcu linii brakuje ")". , Przyjmuję odpowiedź: – hcs42

+0

"To rozwiązanie nie działa, jeśli sprawdziłeś nazwę pliku Makefile po dodaniu innego pliku Makefile!" To nie jest duży problem. Potrafię napisać dwie pierwsze linijki tego kodu na początku mój plik Makefile, który poprawnie ustawi zmienną WHERE_ART_THOU, a następnie będę mógł użyć tej zmiennej w dowolnym miejscu pliku Makefile, będzie ona zawierała poprawnie nazwę pliku Makefile – hcs42

3

Szybka wycieczka na stronę Google sugeruje, że na stronie znajduje się odpowiedź na pytanie: this.

+0

Dla GNU Make only - w ogóle nie będzie działać z wersją inną niż GNU. –

+1

To rozwiązanie nie działa, jeśli zaznaczysz nazwę pliku Makefile po dodaniu kolejnego pliku Makefile! –

7

(Jeśli masz jakiekolwiek pytania, odwołaj się do zdumiewająco napisanych GNU make manual. Pamiętaj jednak, że tak jak w przypadku Makefile, niniejszą instrukcję należy dokładnie przeczytać przed wprowadzeniem koncepcji w życie).

Nie mogłem dowiedzieć się, jak to zrobić łatwo. O ile rozumiem, będziesz musiał wykonać pracę ręczną.

Później opiszę, jak można to zrobić i pokaż skrypty wprowadzające zmienną current_makefile. Ale na początku chciałbym podkreślić ważną koncepcję.

Powinieneś zrozumieć, że gdybyśmy mieli jakąś zmienną current_makefile, która rozwinie się do obecnej nazwy pliku Makefile, to będzie musiała się zmienić podczas procesu odczytu plików Makefile. Oznacza to, że powinno ono być używane wewnątrz kontekstu "natychmiastowej" rozbudowy - tj. W obrębie poleceń, które są wykonywane podczas odczytu pliku Makefile. Większość poleceń jest jednak wykonywana po odczytaniu plików Makefile. Dlatego niektóre polecenia wypisują poprawną wartość płynnie, podczas gdy w niektórych miejscach, gdzie "odroczone" rozszerzenie będzie zawsze rozszerzyć do nazwy głównej pliku Makefile.

Jeśli chcesz użyć tej zmiennej w tekście reguły, na przykład, będziesz musiał robić sztuczki, ponieważ tekst reguły zawsze ma odroczoną ekspansję. Jeśli więc masz regułę, zawsze będzie drukować nazwę głównego pliku makefile. Zamiast tego, aby wymusić natychmiastową ekspansję, trzeba będzie utworzyć kolejną zmienną o nazwie makefile specyficzne (tj nazwy takich zmiennych powinna być różna w każdej makefile):

this_makefile_unique_name := $(current_makefile) 
rule: 
     echo In makefile $(current_makefile): 
     echo Making target [email protected] 

lub wykorzystać eval :.

define make_rule 
rule: 
     echo In makefile $(1): 
     echo Making target [email protected] 

$(eval $(call make_rule,$(current_makefile))) 

Jeśli chcesz użyć nazwy bieżącego makefile tylko w celu debugowania, należy rozważyć specjalne funkcje debugowania, takie jak ostrzeżenia lub informacji :.

$(warning We're in makefile $(current_makefile)) 

Te funkcje używają "natychmiastowego" rozszerzenia i wyświetlają poprawną wartość.


Jak zdefiniować taką $ (current_makefile)?

Musisz ręcznie utrzymywać stos plików Makefile. Po dołączeniu pliku makefile jego nazwa jest umieszczana na szczycie stosu; po powrocie z dołączonego pliku makefile do zewnętrznego, najwyższa nazwa jest wyskakiwana ze stosu. Osiąga się to poprzez umieszczenie specjalnych połączeń na początek i koniec makefile:

# Beginning of makefile 
$(eval $(makefile_names_push)) 
#... makefile text 
$(warning $(current_makefile)) 
#... 
$(eval $(makefile_names_pop)) 
#End of file 

teraz definiować funkcje na początku swojej makefile korzeniowego.

lastword=$(word $(words $(1)),$(1)) 

define makefile_names_push 
current_makefile := $$(CURDIR)/$$(call lastword,$$(MAKEFILE_LIST)) 
makefile_stack :=$$(makefile_stack) $$(current_makefile) 
endef 

define makefile_names_pop 
makefile_stack := $$(filter-out $$(current_makefile),$$(makefile_stack)) 
current_makefile := $$(call lastword,$$(makefile_stack)) 
endef 

Jeśli masz pewność, że makijaż jest dość nowy (wersja 3.81+), wymienić lastword połączenia z funkcją wbudowanego :.

#inctead of $$(call lastword,$$(MAKEFILE_LIST)) 
$$(lastword $$(MAKEFILE_LIST)) 

Czy jest przydatna?

Całkowicie bezużyteczne. Użyteczne może być tylko stworzenie 100 plików makefile, które są dowiązaniami symbolicznymi do jednego pliku makefile, reguły w tych plikach makefile zależą od ich nazw. Ale można to osiągnąć w ramach jednej makefile i techniki foreach-eval opisanej w instrukcji. Więc mój post był całkowitą stratą czasu, chociaż miałem trochę zabawy :-)

2

Chciałem zrobić coś podobnego (do echo zawartości Makefile), gdy używam Make do zarządzania prostymi powtarzalnymi zadaniami. Natknąłem się na tę stronę i stwierdziłem, że było to dokładnie to, czego szukałem i naprawdę przydatne dla mojego ograniczonego rozumienia marki.

Mój wynik po przeczytaniu tej strony:

 
    # Makefile - 'make' and 'make help' now echo the makefile. 
    help: 
     cat $(lastword $(MAKEFILE_LIST)) 
    start: 
     sudo -u www /path/to/webapp/myhttpd restart 
    stop: 
     sudo kill cat /path/to/webapp/data/httpd.pid 

Dzięki wszystkim na tej stronie.

1

G'day,

Jeśli zrobić kopię oryginalnego makefile, powiedzmy makefile_test, a następnie wpisz polecenie:

make -np -f makefile_test 2>&1 | tee output 

To oceni makefile i make środowisko, ale nie wykonać dowolne z poleceń. Przeglądając plik wyjściowy pod kątem odwołań do makefile_test pokażemy, co jest ustawione w środowisku make i gdzie ta wartość jest ustawiana.

N.B. Może to wygenerować wiele informacji! I nie dodawaj przełącznika -d (debug), który wygeneruje mnóstwo dodatkowych danych o procesie podejmowania decyzji, ale minimalnych dodatkowych informacji o env.

HTH

1

ta zwraca nazwę pierwszego pliku Makefile nazwie, czyli jeden na dole stosu wywołań:

MAKEFILE_JUSTNAME := $(firstword $(MAKEFILE_LIST)) 
MAKEFILE_COMPLETE := $(CURDIR)/$(MAKEFILE_JUSTNAME) 

gdy są stosowane w sytuacjach non-cross-rekurencyjnych (np makedepend), to jest po prostu nazwa bieżącego pliku makefile.