我编写了python函数(例如,替换字符串)并在scons脚本中调用了该函数。
def Replace(env, filename, old, new):
with open(filename,"r+") as f:
d = f.read()
d = d.replace(old, new)
f.truncate(0)
f.seek(0)
f.write(d)
f.close()
env.AddMethod(Replace,'Replace')
在SConscript中
lib = env.SharedLibrary('lib', object, extra_libs)
tmp = env.Command([],[],[env.Replace(somefile, 'A', 'b')] )
env.Depends(tmp,lib )
我期望的是在库构建后运行Replace()方法。
但是scons总是在第一个回合脚本分析短语中运行Replace()。
看来我缺少一些依赖性。
最佳答案
我相信您可能正在寻找builders that execute python functions。
棘手的一点是,SCons并不想真正按照您强制它的方式工作。构建 Action 应该是可重复且无损的,在您的代码中,您实际上是在破坏somefile
的原始内容。相反,您可以使用目标/源范例和某种模板文件来获得相同的结果。
import os
import re
def replace_action(target, source, env):
# NB. this is a pretty sloppy way to write a builder, but
# for things that are used internally or infrequently
# it should be more than sufficient
assert( len(target) == 1 )
assert( len(source) == 1 )
srcf = str(source[0])
dstf = str(target[0])
with open(srcf, "r") as f:
contents = f.read()
# In cases where this builder fails, check to make sure you
# have correctly added REPLST to your environment
for old, new in env['REPLST']:
contents = re.sub( old, new, contents )
with open( dstf, "w") as outf:
outf.write(contents)
replace_builder = Builder(action = replace_action)
env = Environment( ENV = os.environ )
env.Append( BUILDERS = {'Replace' : replace_builder } )
b = env.Replace( 'somefile', ['somefile.tmpl'], REPLST=[('A','b')] )
lib = env.SharedLibrary('lib', object + [b], extra_libs )
请注意,在我的测试中,replace函数不能很好地与多行数据配合使用,因此我只是换成了使用完整的正则表达式(
re.sub
)。这可能会比较慢,但会提供更大的灵活性。关于python - SCons:如何在scons脚本中调用自定义的python函数并建立正确的依赖关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8226026/