Muszę wykonać niektóre reguły make warunkowo, tylko jeśli zainstalowany Python jest większy niż pewna wersja (powiedzmy 2.5).
Myślałem, że mogę zrobić coś takiego:
python -c 'import sys; print int(sys.version_info >= (2,5))'
a następnie używając wyniku („1”, jeśli jest ok, „0” w przeciwnym razie) w ifeq
instrukcji make.
W prostym skrypcie powłoki bash jest to po prostu:
MY_VAR=`python -c 'import sys; print int(sys.version_info >= (2,5))'`
ale to nie działa w Makefile.
Jakieś sugestie? Aby to osiągnąć, mógłbym użyć innego rozsądnego obejścia.
Odpowiedzi:
Użyj
shell
wbudowanego Make, jak wMY_VAR=$(shell echo whatever)
źródło
$
.Zawinięcie zadania w
eval
działa dla mnie.źródło
.PHONY always make these targets
jest.Oto nieco bardziej skomplikowany przykład z orurowaniem i przypisywaniem zmiennych w przepisie:
źródło
PODNAME
nazwę wdrożenia:$(eval PODNAME=$(shell sh -c "kubectl get pod -l app=sqlproxy -o jsonpath='{.items[0].metadata.name}'"))
Piszę odpowiedź, aby zwiększyć widoczność rzeczywistej składni, która rozwiązuje problem. Niestety to, co ktoś może uznać za trywialne, może stać się bardzo dotkliwym bólem głowy dla kogoś, kto szuka prostej odpowiedzi na rozsądne pytanie.
Umieść następujący plik w pliku „Makefile”.
Zachowanie, które chciałbyś zobaczyć, jest następujące (zakładając, że masz zainstalowany najnowszy Python).
Czy skopiujesz i wkleisz powyższy tekst do pliku Makefile, czy dostaniesz to? Prawdopodobnie nie. Prawdopodobnie wystąpi błąd podobny do zgłaszanego tutaj:
makefile: 4: *** brak separatora. Zatrzymać
Dlaczego: Ponieważ chociaż osobiście użyłem oryginalnej tabulacji, przepełnienie stosu (próbując być pomocnym) konwertuje moją tabulator na kilka spacji. Ty, sfrustrowany obywatelu internetu, teraz go skopiuj, myśląc, że masz teraz ten sam tekst, którego użyłem. Komenda make odczytuje teraz spacje i stwierdza, że komenda „all” jest niepoprawnie sformatowana. Skopiuj powyższy tekst, wklej go, a następnie przekonwertuj spację przed „@echo” na kartę, a ten przykład powinien wreszcie, mam nadzieję, zadziałać.
źródło
Uważaj na takie przepisy
Robi dwie rzeczy źle. Pierwszy wiersz w przepisie jest wykonywany w osobnej instancji powłoki od drugiego wiersza. W międzyczasie zmienna została utracona. Drugą wadą jest to, że
$
nie uciekł.Oba problemy zostały naprawione i zmienna jest użyteczna. Odwrotny ukośnik łączy oba wiersze, aby działały w jednej powłoce, dlatego działa ustawienie zmiennej i odczytywanie zmiennych po słowie.
Zdaję sobie sprawę, że w pierwotnym poście powiedziano, jak uzyskać wyniki polecenia powłoki do zmiennej MAKE, a ta odpowiedź pokazuje, jak przenieść ją do zmiennej powłoki. Ale inni czytelnicy mogą skorzystać.
Ostatnia poprawka, jeśli konsument spodziewa się ustawienia „zmiennej środowiskowej”, musisz ją wyeksportować.
potrzebuje tego w pliku makefile
Mam nadzieję, że komuś pomoże. Ogólnie rzecz biorąc, należy unikać wykonywania prawdziwej pracy poza przepisami, ponieważ jeśli ktoś użyje makefile z opcją „--dry-run”, aby ZOBACZYĆ tylko, co zrobi, nie spowoduje to żadnych niepożądanych efektów ubocznych. Każde
$(shell)
połączenie jest oceniane podczas kompilacji, a niektóre prawdziwe prace mogą zostać przypadkowo wykonane. Lepiej pozostawić prawdziwą pracę, taką jak generowanie identyfikatorów, w przepisach, jeśli to możliwe.źródło
Za pomocą GNU Make możesz używać
shell
ieval
przechowywać, uruchamiać i przypisywać dane wyjściowe z dowolnych wywołań wiersza poleceń. Różnica między poniższym przykładem a tymi, które go wykorzystują,:=
polega na tym, że:=
przypisanie następuje raz (po napotkaniu) i na zawsze. Rekurencyjnie rozwinięte zmienne ustawione za pomocą=
są nieco bardziej „leniwe”; odwołania do innych zmiennych pozostają do momentu odwołania się do samej zmiennej, a kolejne rekurencyjne rozszerzanie ma miejsce za każdym razem, gdy odwołuje się do niej zmienna , co jest pożądane, aby uzyskać „spójne, wywoływalne fragmenty”. Aby uzyskać więcej informacji, zobacz instrukcję ustawiania zmiennych .źródło
$(SET_ID)
życie wewnątrz zif
klauzulą , że jest fałszywa wtedy to nadal nazywa .W poniższym przykładzie zapisałem ścieżkę folderu Makefile do,
LOCAL_PKG_DIR
a następnie używamLOCAL_PKG_DIR
zmiennej w obiektach docelowych.Makefile:
Wyjście końcowe:
źródło