2009-08-27 17 views
13

Próbuję napisać plik Make Make Make GNU, który ma mnóstwo podobnych celów, gdzie polecenia kompilacji różnią się nieznacznie między nimi. Próbuję użyć target-specific variables do reprezentowania tych odmian. Niektóre z tych wartości zmiennych odnoszą się do plików, które chcę użyć jako wymagań wstępnych. Na przykład:Zmienne specyficzne dla celu jako warunki wstępne w pliku Makefile

target_1:special_filename=target1_prereq 
target_2:special_filename=target2_prereq 

target_1 target_2: common_filename $(special_filename) 
    do_something common_filename --a-weird-option=$(special_filename) 

Kiedy ja nazywam 'make target_1', chcę to zrobić target1_prereq jeśli nie istnieje. W tej chwili nie wydaje się, aby użyć parametru target1_prereq jako warunku wstępnego, mimo że polecenie build (do_something) jest wywoływane z odpowiednim parametrem.

Używam GNU Make 3.80.


Edytuj: Jeszcze kilka komplikacji z prawdziwego systemu. Niektóre zmienne są oparte na wartościach innych zmiennych. Ręczne określanie wymagań wstępnych nie będzie skalowane. Nieco bardziej skomplikowany przykład:

target_1:special_filename_base=target1_prereq 
target_2:special_filename_base=target2_prereq 

some_filename_a = $(special_filename_base).exta 
some_filename_b = $(special_filename_base).extb 

target_1 target_2: common_filename $(special_filename_b) $(special_filename_a) 
    do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b) 

Odpowiedz

3

Zmienna specyficzna dla celu jest zdefiniowana tylko w poleceniach celu (lub w innych zadaniach specyficznych dla celu); nie może być używany jako jeden z wymagań wstępnych celu. Nie sądzę, że to czysty sposób robić to, co chcesz w marki, ale istnieje kilka kludgey podejścia, takie jak:

 
EXTENSIONS = .exta .extb 
target_1: $(addprefix target1_prereq,$(EXTENSIONS)) 
target_2: $(addprefix target2_prereq,$(EXTENSIONS)) 

target_1 target_2: common_filename 
    do_something common_filename --a-weird-option=$(filter %.exta,$^) --second=$(filter %.extb,$^) 
+4

Wskrzeszanie tego wątku z korzyścią dla każdego, kto się na nim natknie. A [bardziej eleganckie rozwiązanie] (http://stackoverflow.com/questions/9311743/make-using-target-specific-variables-in-prerequisites) używa rozszerzenia wtórnego. – Seth

+0

@Seth, Zgadzam się: 'target_1 cel_2: nazwa_pliku wspólnego $$ (nazwa_pliku_nazwa_profilu) .exta $$ (nazwa_pliku_nazwa_profilu) .extb ...' – Beta

2

Jako prosty obejścia:

 
target_1:special_filename=target1_prereq 
target_1:target1_prereq 
target_2:special_filename=target2_prereq 
target_2:target2_prereq 

target_1 target_2: common_filename $(special_filename) 
    do_something common_filename --a-weird-option=$(special_filename) 

Istnieje pewna redundancja, ale jest ona zlokalizowana, więc nie jest tak źle.

+0

Myślę, że rozwiązuje konkretny przypadek, który napisałem, ale miałem nadzieję na bardziej ogólne rozwiązanie. Będę edytować z bardziej skomplikowanym przykładem. –

2

Znalazłem dość czystej drodze side-stepping to ograniczenie . Byłoby iść tak:

target_1:export special_filename_base=target1_prereq 
target_2:export special_filename_base=target2_prereq 

some_filename_a = $(special_filename_base).exta 
some_filename_b = $(special_filename_base).extb 

target_1 target_2: 
    $(MAKE) -f $(firstword $(MAKEFILE_LIST)) target-proxy 

target-proxy: common_filename $(special_filename_b) $(special_filename_a) 
    do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b) 

dwa ważne punkty:

  1. export zmiennych docelowych, dzięki czemu będą one dostępne, kiedy ponownie uruchomić Makefile.
  2. Utwórz cel proxy, który ma wszystkie oryginalne wymagania wstępne: target_1 target_2, a następnie w target_1 target_2 ponownie wywołaj plik Makefile z tym celem proxy. Ponieważ cel konkretne zmienne będą miały wartości przez to (my w recepturze przez ten czas) i zostali export ed, że będzie dostępny w target-proxy - voila :)

Minusem podejście to polega na tym, że tworzymy kolejny proces - jeśli jest to po prostu inny, to prawdopodobnie jest w porządku, ale YMMV, więc bądź bardzo ostrożny.

Powiązane problemy