Jak przekazać argument do Makefile z linii poleceń?
Rozumiem, że mogę to zrobić
$ make action VAR="value"
$ value
z Makefile
VAR = "default"
action:
@echo $(VAR)
Jak uzyskać następujące zachowanie?
$ make action value
value
?
Co powiesz na
$make action value1 value2
value1 value2
command-line
parameters
makefile
arguments
Meng Lu
źródło
źródło
Odpowiedzi:
Prawdopodobnie nie powinieneś tego robić; łamiesz podstawowy schemat działania aplikacji Make. Ale oto jest:
EDYCJA:
Aby wyjaśnić pierwsze polecenie,
$(MAKECMDGOALS)
to lista „celów” wypisana w wierszu poleceń, np. „wartość akcji1 wartość2”.$@
to automatyczna zmienna dla nazwy celu reguły, w tym przypadku „akcja”.filter-out
to funkcja, która usuwa niektóre elementy z listy. Więc$(filter-out bar, foo bar baz)
zwracafoo baz
(może być bardziej subtelny, ale nie potrzebujemy tutaj subtelności).Połącz je razem i
$(filter-out $@,$(MAKECMDGOALS))
zwróci listę celów określonych w wierszu poleceń innych niż „akcja”, która może mieć postać „wartość1 wartość2”.źródło
$(shell echo $(MAKECMDGOALS) | sed 's!^.* $@ !!')
pominąć wszystkie wcześniejsze cele i po prostu rozważyć następujące argumenty:make target1 target2 action value1 value2
%:
i@:
nie mogę znaleźć informacji o tym, co robią te „dyrektywy” (czy jakkolwiek się nazywają). Czy mógłbyś wyjaśnić?%:
i@:
jest regułą . Nazwa celu%
oznacza, że jest to reguła, która pasuje do wszystkiego ; to znaczy, jeśli Make nie może znaleźć innego sposobu na zbudowanie rzeczy, którą każesz mu zbudować, wykona tę regułę. To@:
jest przepis ; te:
środki nie robić nic, a@
oznacza to zrobić dyskretnie.%:
była% :
to nazwa docelowa typu wieloznacznego. Nie widzę nic na tej stronie podręcznika co do@:
tego… sugeruje to, że reguła „nic nie rób” miałaby po prostu znak;
po specyfikacji celu, więc czy nie byłoby dokładniej pisać% : ;
tak, jak robi to „symbol wieloznaczny” - nic nie jest regułą?filter-out
nie działa, gdy akcja jest zależnością celu określonego w wierszu poleceń, ponieważ$@
zostanie ustawiona na nazwę zależności, a nie oryginalny argument wywoływany w wierszu poleceń. Zamiast tego przypisujęMAKECMDGOALS
do tablicy powłoki, a następnie usuwam pierwszy element:@ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
Oto ogólne działające rozwiązanie oparte na @ Beta
Używam GNU Make 4.1
SHELL=/bin/bash
na szczycie mojego pliku Makefile, więc YMMV!To pozwala nam akceptować dodatkowe argumenty (nie robiąc nic, gdy otrzymujemy zadanie, które nie pasuje, zamiast zgłaszać błąd).
A to jest makro, które pobiera argumenty za nas:
Oto praca, która może nazwać tę:
Wynik byłby taki:
Uwaga! Lepiej by było, gdybyś użył „Taskfile”, który jest wzorcem basha, który działa podobnie do make, tylko bez niuansów Maketools. Zobacz https://github.com/adriancooney/Taskfile
źródło
tab
wcześniej@echo
, a niespace
.O wiele łatwiejsze podejście. Rozważ zadanie:
Teraz, kiedy chcę to nazwać, po prostu uruchamiam coś takiego:
AT="build assets" make provision
Lub tylko:
make provision
w tym przypadkuAT
jest to pusty ciągźródło
nie próbuj tego robić
zamiast tego utwórz skrypt:
i zrób to:
aby uzyskać więcej wyjaśnień, dlaczego to robię i zastrzeżenia dotyczące hakowania plików makefile, przeczytaj moją odpowiedź na inne bardzo podobne, ale pozornie nie zduplikowane pytanie: Przekazywanie argumentów do polecenia „make run”
źródło