2017-09-14 261 views
0

根據scons documentationsubst方法將遞歸插值構造變量。然而,這似乎並沒有遞歸:遞歸變量替換env.subst

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") 

打印:

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編譯爲CPPDEFINES的一部分時被正確評估,而不是在print語句。我怎樣才能讓subst完全評估foobar?

+0

我目前無法對其進行測試,並且我無法在文檔中找到它,因此我無法發佈完整答案,但我認爲$$已被轉移到非易失性存儲器中,評估$。嘗試使用相同的代碼,但使用e [「foobar」] =「$ {foo + $ {bar}}」 –

回答

0

使用表達

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

,由肯尼·奧斯特羅姆建議,也沒有幫助。它會產生語法錯誤,因爲subst方法並沒有真正處理嵌套大括號。

實際的問題是:爲什麼我們直接在SConstruct中使用subst,以及何時在構建命令中使用它時,會看到不同的輸出?

如果再加

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

SConstruct,我們看到了相同的輸出${foo + 2}FOOBAR。在生成時不同的是,該內部變量$_CPPDEFFLAGS_defines方法方面宣稱:

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

(從print e.Dump())。例如,這個_defines方法第二次通過subst_path運行所有變量,例如,可以在包含路徑中使用變量。

所以subst方法做正確的事,你就必須重新評估:

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

得到相同的輸出。

+0

謝謝!所以我想手冊中的_recursive_單詞是錯的? – Andak

+0

那麼,我認爲它仍然適用於變量的簡單*文本替換*,這可能是在這種情況下單詞* interpolated *的預期含義。但是單個Python表達式的'eval'有點特別......如果您有關於使差異更明顯的想法,請隨時提交我們文檔的拉取請求。 – dirkbaechle

+0

很抱歉,如果這是粗魯的。我的意思是,對我來說,使用_recursive_提示我可以有任意的複雜表達式,它將通過'subst'進行_recursively_求值,直到不再有替換。但是你說什麼也是有道理的。我猜這裏的關鍵是「遞歸_interpolates_」。 – Andak

0

只是爲了說清楚dirkbaechle說了些什麼;我們可以通過 來實現這一點,只需在兩個單獨的步驟中進行插值和評估(通過調用subst兩次)。這讓我們不得不任意複雜的表達式:

# 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") 

打印:

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. 

再次感謝,dirkbaechle!