簡體   English   中英

如何生成多行構建命令?

[英]How can I generate multi-line build commands?

在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腳本,因為這將創建字符串轉義瘋狂。

這可能嗎?

更新:
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

感謝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())

您正在混合兩個完全不同的東西:要執行的命令,以及它在命令行中的表示。 默認情況下,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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM