2009-01-21 128 views
3

在SCons中,我的命令生成器创建了可笑的长命令行。我想 喜欢能够在构建日志中将多条命令拆分为 可读性。如何生成多行生成命令?

例如我有一个像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脚本,因为这会创建字符串 逃离疯狂。

这可能吗?

UPDATE:
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

-1:没有足够的信息。我不明白这个问题。不是scons文件只是普通的python文件?你打算怎么做?你可以在问题中粘贴你的scons文件的片段吗? – nosklo 2009-01-21 19:18:20

回答

3

由于cournape的有关行动与发电机尖端(和eclipse的PyDev调试器),我终于想出了我需要做的事情。你想把你的函数作为'动作'而不是'生成器'传递给'Builder'类。这将允许您直接执行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. 

另一个关键之处是要记住,从“生成”切换到“动作”是指目标您正在构建的对您传递给子流程外壳的实际字符串不再具有隐式依赖关系。您可以通过将字符串添加到环境中来重新创建此依赖项。

例如,我个人希望该解决方案是这样的:

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

您正在混合两个完全不同的东西:要执行的命令及其在命令行中的表示。默认情况下,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