根据scons documentation,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 :(得分:0)
使用表达式
e["foobar"] = "${foo + ${bar}}"
,正如肯尼奥斯特罗姆所建议的那样,也没有任何帮助。它会产生语法错误,因为subst
方法并不能很好地处理嵌套大括号。
实际问题是:为什么在subst
直接使用SConstruct
时,以及在构建命令中使用它时,我们会看到不同的输出?
如果我们添加
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}"))
获得相同的输出。
答案 1 :(得分: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!