在SCons中,我的命令生成器创建了可笑的长命令行。 ID 喜欢能够跨多行拆分这些命令 构建日志中的可读性。
e.g。我有一个类似的SConscipt:
import os
# create dependency
def my_cmd_generator(source, target, env, for_signature):
return r'''echo its a small world after all \
its a small world after all'''
my_cmd_builder = Builder(generator=my_cmd_generator, suffix = '.foo')
env = Environment()
env.Append( BUILDERS = {'MyCmd' : my_cmd_builder } )
my_cmd = env.MyCmd('foo.foo',os.popen('which bash').read().strip())
AlwaysBuild(my_cmd)
当它执行时,我得到:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
echo its a small world after all \
its a small world after all
its a small world after all
sh: line 1: its: command not found
scons: *** [foo.foo] Error 127
scons: building terminated because of errors.
使用os.system和os.popen在python shell中执行此操作 - 我得到一个可读的命令字符串,子shell进程将所有行解释为一个命令。
>>> import os
>>> cmd = r'''echo its a small world after all \
... its a small world after all'''
>>> print cmd
echo its a small world after all \
its a small world after all
>>> os.system( cmd)
its a small world after all its a small world after all
0
当我在SCons中执行此操作时,它一次执行一行,即 不是我想要的。
我还想避免将我的命令构建到shell脚本中 然后执行shell脚本,因为这将创建字符串 逃避疯狂。
这可能吗?
更新:
cournape,
感谢关于$ CCCOMSTR的线索。不幸的是,我没有使用SCons开箱即用的任何语言,所以我正在创建自己的命令生成器。使用生成器,我如何让SCons做:
echo its a small world after all its a small world after all'
但打印
echo its a small world after all \
its a small world after all
答案 0 :(得分:3)
感谢cournape关于动作与生成器(以及eclipse pydev调试器)的提示,我终于找到了我需要做的事情。您希望将函数作为“动作”传递给“构建器”类,而不是“生成器”。这将允许您直接执行os.system或os.popen调用。这是更新后的代码:
import os
def my_action(source, target, env):
cmd = r'''echo its a small world after all \
its a small world after all'''
print cmd
return os.system(cmd)
my_cmd_builder = Builder(
action=my_action, # <-- CRUCIAL PIECE OF SOLUTION
suffix = '.foo')
env = Environment()
env.Append( BUILDERS = {'MyCmd' : my_cmd_builder } )
my_cmd = env.MyCmd('foo.foo',os.popen('which bash').read().strip())
此SConstruct文件将生成以下输出:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
my_action(["foo.foo"], ["/bin/bash"])
echo its a small world after all \
its a small world after all
its a small world after all its a small world after all
scons: done building targets.
另一个关键部分是要记住,从'generator'切换到'action'意味着你正在构建的目标不再对你传递给子进程shell的实际字符串有一个隐式依赖。您可以通过将字符串添加到环境中来重新创建此依赖关系。
例如,我个人想要的解决方案如下:import os
cmd = r'''echo its a small world after all \
its a small world after all'''
def my_action(source, target, env):
print cmd
return os.system(cmd)
my_cmd_builder = Builder(
action=my_action,
suffix = '.foo')
env = Environment()
env['_MY_CMD'] = cmd # <-- CREATE IMPLICIT DEPENDENCY ON CMD STRING
env.Append( BUILDERS = {'MyCmd' : my_cmd_builder } )
my_cmd = env.MyCmd('foo.foo',os.popen('which bash').read().strip())
答案 1 :(得分:1)
您正在混合两个完全不同的东西:要执行的命令及其在命令行中的表示。默认情况下,scons打印命令行,但如果拆分命令行,则更改执行的命令。
现在,scons有一个改变打印命令的机制。它们是根据Action实例注册的,并且可以使用许多默认实例:
env = Environment()
env['CCCOMSTR'] = "CC $SOURCE"
env['CXXCOMSTR'] = "CXX $SOURCE"
env['LINKCOM'] = "LINK $SOURCE"
将打印,假设只有C和CXX来源:
CC foo.c
CC bla.c
CXX yo.cc
LINK yo.o bla.o foo.o