Jak mogę przerwać wykonanie make / makefile na podstawie zmiennej makefile, która nie została ustawiona / wyceniona?
Wymyśliłem to, ale działa tylko wtedy, gdy wywołujący nie uruchamia jawnie celu (tj. Działa make
tylko).
ifeq ($(MY_FLAG),)
abort: ## This MUST be the first target :( ugly
@echo Variable MY_FLAG not set && false
endif
all:
@echo MY_FLAG=$(MY_FLAG)
Myślę, że coś takiego byłoby dobrym pomysłem, ale nie znalazłem nic w instrukcji make:
ifndef MY_FLAG
.ABORT
endif
Odpowiedzi:
TL; DR : użyj
error
funkcji :Zwróć uwagę, że linie nie mogą być wcięte. Dokładniej, żadne tabulatory nie mogą poprzedzać tych wierszy.
Rozwiązanie ogólne
W przypadku, gdy zamierzasz przetestować wiele zmiennych, warto zdefiniować w tym celu funkcję pomocniczą:
A oto jak z niego korzystać:
Spowoduje to wyświetlenie następującego błędu:
Uwagi:
Prawdziwe sprawdzenie odbywa się tutaj:
Odzwierciedla to zachowanie
ifndef
warunku, tak że zmienna zdefiniowana jako pusta wartość jest również uważana za „nieokreśloną”. Ale dotyczy to tylko prostych zmiennych i jawnie pustych zmiennych rekurencyjnych:Jak sugeruje @VictorSergienko w komentarzach, pożądane może być nieco inne zachowanie:
I:
Kontrola specyficzna dla celu
Możliwe jest również rozszerzenie rozwiązania tak, aby wymagać zmiennej tylko w przypadku wywołania określonego celu.
$(call check_defined, ...)
od wewnątrz przepisuPo prostu przenieś czek do przepisu:
@
Znak wiodący wyłącza echo polecenia i:
jest faktycznym poleceniem, skrótem powłoki bez operacji .Wyświetlam nazwę celu
check_defined
Funkcja może poprawić również wysyłać nazwy docelowego (dostarczone przez$@
zmienną)Tak więc, teraz nieudane sprawdzenie daje ładnie sformatowany wynik:
check-defined-MY_FLAG
specjalny celOsobiście skorzystałbym z prostego i prostego rozwiązania powyżej. Jednak na przykład ta odpowiedź sugeruje użycie specjalnego celu do przeprowadzenia faktycznej kontroli. Można by spróbować uogólnić to i zdefiniować cel jako niejawną regułę wzorcową:
Stosowanie:
Zwróć uwagę, że
check-defined-BAR
jest wymieniony jako warunek wstępny dotyczący tylko zamówienia (|...
).Plusy:
Cons:
make -t
(zobacz Zamiast wykonywania receptur ) zanieczyści twój katalog główny dużą ilościącheck-defined-...
plików. Jest to smutna wada faktu, że nie można zadeklarować.PHONY
reguł wzorców .Uważam, że te ograniczenia można pokonać za pomocą
eval
magicznych i dodatkowych hacków rozszerzeń , chociaż nie jestem pewien, czy warto.źródło
make --version
jako pierwszy krok.Użyj funkcji powłoki
test
:Stosowanie:
źródło
checkforsomething
cel, który miał tylkotest
w sobie ifoo
uzależniłem się od tego, oraz 2)@if test -z "$(something)"; then echo "helpful error here"; exit 1; fi
zamiast tego zmieniłem czek na . To dało mi możliwość dodania użytecznego błędu i pozwoliło mi nieco bardziej wskazać nazwę nowego celu, co również poszło nie tak.Makefile:5: *** missing separator. Stop.
test -n "$(something) || (echo "message" ; exit 1)
aby uniknąć jawneif
.Możesz użyć IF, aby przetestować:
Wynik:
źródło
[
jest aliasem dla poleceniatest
, więc jest to ta sama odpowiedź, co @Messa powyżej. Jest to jednak bardziej kompaktowe i obejmuje generowanie komunikatów o błędach.Użyj obsługi błędów powłoki dla nieustawionych zmiennych (zwróć uwagę na podwójne
$
):Jeśli potrzebujesz niestandardowego komunikatu o błędzie, dodaj go po
?
:źródło
Dla prostoty i zwięzłości:
Z wyjściami:
źródło