2017-09-14 4 views
0

Gemäß der scons documentation wird die subst Methode rekursiv interpolieren Konstruktionsvariablen. Allerdings scheint es nicht rekursiv zu sein:Rekursive Variablensubstitution mit envst

e = Environment(CPPDEFINES = ["FOOBAR=${foobar}"]) 

e["foo"] = 1 
e["bar"] = "${foo + 1}" 
e["foobar"] = "$${foo + ${bar}}" 

# I want this to print "foobar: 3" 
print "foobar:", e.subst("${foobar}") 

e.Program("test.c") 

Drucke:

scons: Reading SConscript files ... 
foobar: ${foo + 2} 
scons: done reading SConscript files. 
scons: Building targets ... 
gcc -o test.o -c -DFOOBAR=3 test.c 
gcc -o test test.o 
scons: done building targets. 

foobar richtig während der Kompilierung als Teil CPPDEFINES, aber nicht in der Print-Anweisung ausgewertet wird. Wie kann ich subst erhalten, um foobar vollständig auszuwerten?

+0

Ich bin nicht in der Lage, es jetzt zu testen, und ich kann es nicht in den Dokumenten finden, so dass ich keine vollständige Antwort posten kann, aber ich denke, das $$ ist bis zu einem nicht bewertet $. Versuchen Sie den gleichen Code, außer mit e ["foobar"] = "$ {foo + $ {bar}}" –

Antwort

0

den Ausdruck Mit

e["foobar"] = "${foo + ${bar}}" 

, wie von Kenny Ostrom vorgeschlagen, helfen entweder nicht. Es führt zu einem Syntaxfehler, da die subst-Methode geschachtelte geschweifte Klammern nicht wirklich gut verarbeitet.

Die eigentliche Frage ist: Warum sehen wir verschiedene Ausgaben, wenn Sie subst in der SConstruct direkt verwenden, und wenn es innerhalb eines Build-Befehls verwendet wird?

Wenn wir

print "CPPDEFINES:", e.subst("$CPPDEFINES") 

zum SConstruct hinzufügen, sehen wir die gleiche Leistung ${foo + 2} für FOOBAR. Der Unterschied bei der Erstellung ist, dass die interne Variable $_CPPDEFFLAGS in Bezug auf die _defines Methode deklariert ist:

'_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}' 

(von einem print e.Dump()). Diese _defines Methode führt alle Variablen ein zweites Mal durch subst_path, so dass man Variablen in Include-Pfaden zum Beispiel verwenden kann.

So ist die subst Methode das Richtige tut, müssen Sie nur noch einmal bewerten:

print "foobar:", e.subst(e.subst("${foobar}")) 

die gleiche Leistung zu erhalten.

+0

Danke! Also ich denke, das _recursive_ Wort im Handbuch ist einfach falsch? – Andak

+0

Nun, ich würde behaupten, dass es immer noch für den einfachen * textuellen Ersatz * von Variablen gilt, was wahrscheinlich die beabsichtigte Bedeutung des Wortes * interpoliert * in diesem Zusammenhang ist. Aber das 'Eval' einzelner Python-Ausdrücke ist etwas Besonderes ...Wenn Sie Ideen haben, den Unterschied deutlicher zu machen, können Sie gerne eine Pull-Anfrage für unsere Dokumentation einreichen. – dirkbaechle

+0

Sorry, wenn das als unhöflich abkam. Was ich damit meinte, ist, dass die Verwendung von _recursive_ für mich den Hinweis gibt, dass ich beliebige komplexe Ausdrücke haben kann, die _recursivy_ durch "subst" ausgewertet werden, bis keine weiteren Substitutionen mehr vorgenommen werden müssen. Aber was du sagst, ergibt auch Sinn. Ich denke, der Schlüssel hier ist "rekursiv _interpoliert_". – Andak

0

Nur um klar zu machen, was dirkbaechle gesagt hat; Dies erreichen wir durch einfach durch Interpolation und Auswertung in zwei separaten Schritten (durch den Aufruf von subst zweimal). Dies erlaubt uns, beliebigen komplexen Ausdrücke zu haben:

# Notice how we wrap foobar in $$ 
e = Environment(CPPDEFINES = ["FOOBARBAZ=$${${foobarbaz}}"]) 

e["foo"] = 1 
e["bar"] = "($foo + 1)" 
e["foobar"] = "($foo + $bar)" 
e["foobarbaz"] = "($foobar + $foobar)" 

print "foobarbaz after substituting once:", e.subst("$${${foobarbaz}}") 
print "foobarbaz after substituting twice:", e.subst(e.subst("$${${foobarbaz}}")) 

e.Program("test.c") 

Drucke:

scons: Reading SConscript files ... 
foobarbaz after substituting once: ${((1 + (1 + 1)) + (1 + (1 + 1)))} 
foobarbaz after substituting twice: 6 
scons: done reading SConscript files. 
scons: Building targets ... 
gcc -o test.o -c -DFOOBARBAZ=6 test.c 
gcc -o test test.o 
scons: done building targets. 

Thanks again, dirkbaechle!

Verwandte Themen