2009-01-21 149 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