2010-01-07 20 views
132

Ich muss einige make-Regeln bedingt ausführen, nur wenn das installierte Python größer ist als eine bestimmte Version (zB 2.5).Wie man die Ausgabe eines Befehls einer Makefile-Variablen zuweist

Ich dachte, ich so etwas wie die Ausführung tun könnte:

python -c 'import sys; print int(sys.version_info >= (2,5))' 

und dann die Ausgabe mit ('1', wenn ok, '0' sonst) in einer ifeq Make-Anweisung.

In einem einfachen Skript Bash-Shell ist es nur:

MY_VAR=`python -c 'import sys; print int(sys.version_info >= (2,5))'` 

aber das funktioniert nicht in einem Makefile.

Irgendwelche Vorschläge? Ich könnte jeden anderen vernünftigen Workaround verwenden, um dies zu erreichen.

+0

Seltsamer Zecken wieder um den Befehl Arbeit zum Ausführen von anderen Skripten für mich in einem Makefile. Könnte etwas anderes sein. –

Antwort

216

Verwenden Sie die Make shell wie gebautet in MY_VAR=$(shell echo whatever)

[email protected]:~$make 
MY_VAR IS whatever 
[email protected]:~$ cat Makefile 
MY_VAR := $(shell echo whatever) 

all: 
    @echo MY_VAR IS $(MY_VAR) 
+22

Shell ist kein Standard Erstellen Sie den Befehl "builtin". Dies ist ein GNU Make Builtin. – Dereckson

+6

http://stackoverflow.com/a/2373111/12916 fügt eine wichtige Anmerkung über das Entweichen von '$' hinzu. –

+1

Dieses einfache Beispiel funktioniert. Es funktioniert auch mit Shell-Befehlspipeline.Aber es ist wichtig, dass Sie $$ verwenden, um $ in der Shell-Befehl –

16

in einem eval die Zuordnung Verpackung ist für mich arbeiten.

set_opts: 
    $(eval DOCKER_OPTS = -v $(shell mktemp -d -p /scratch):/output) 
    @true 

Hinweis: Die @true hier verhindert Stellen aus dem Denken gibt es nothing to be done.

+5

_ "Hinweis: Die @true verhindert, dass Make denkt, dass nichts zu machen ist." _ Ähm, das ist es, wofür '.PHONY immer diese Ziele 'ist. –

+0

Vielen Dank! Dies hilft mir, "komische Bash" in Makefile zu umgehen –

1

Ich schreibe eine Antwort, um die Sichtbarkeit der tatsächlichen Syntax zu erhöhen, die das Problem löst. Unglücklicherweise kann das, was jemand als trivial ansieht, für jemanden, der nach einer einfachen Antwort auf eine vernünftige Frage sucht, ein sehr bedeutender Kopfschmerz werden.

Setzen Sie Folgendes in die Datei "Makefile".

MY_VAR := $(shell python -c 'import sys; print int(sys.version_info >= (2,5))') 

all: 
    @echo MY_VAR IS $(MY_VAR) 

Das Verhalten, das Sie sehen möchten, ist das folgende (vorausgesetzt, Sie haben kürzlich Python installiert).

Wenn Sie den obigen Text kopieren und in das Makefile einfügen, erhalten Sie das? Wahrscheinlich nicht. Sie werden wahrscheinlich einen Fehler wie bekommen, was hier berichtet wird:

makefile:4: *** missing separator. Stop

Warum: Weil obwohl ich persönlich eine echte Registerkarte Stack-Überlauf verwendet (Versuch hilfreich zu sein) wandelt meine Registerkarte in eine Anzahl von Räumen. Du, frustrierter Internet-Bürger, kopiere das jetzt und denke, dass du jetzt den gleichen Text hast, den ich benutzt habe. Der make-Befehl liest jetzt die Leerzeichen und stellt fest, dass der Befehl "all" falsch formatiert ist. Kopieren Sie also den obigen Text, fügen Sie ihn ein und konvertieren Sie dann den Leerraum vor "@echo" in einen Tab, und dieses Beispiel sollte hoffentlich endlich für Sie arbeiten.

0

Hier ist ein wenig kompliziertes Beispiel mit Rohrleitungen und variable Zuordnung innerhalb Rezepts:

getpodname: 
    # Getting pod name 
    @eval $$(minikube docker-env) ;\ 
    $(eval PODNAME=$(shell sh -c "kubectl get pods | grep profile-posts-api | grep Running" | awk '{print $$1}')) 
    echo $(PODNAME) 
Verwandte Themen