SCons 在任何操作失败时删除 $TARGET

SCons delete $TARGET on failure of any Action

有没有办法模仿 Make 的 .DELETE_ON_FAILURE 行为?如果我有一个构建器执行一系列操作来生成目标,我希望它们以原子方式运行。如果之前的 Action 生成了一个(不完整的)文件,而后来的 Action 无法修改它,我希望目标文件被删除,而不是保持其不完整状态。

考虑这个 SConstruct 文件:

def example(target, source, env):
    raise Exception('failure')
    # more processing that never happens...

action_list = [
    Copy('$TARGET', '$SOURCE'),
    Chmod('$TARGET', 0755),
    example,
]

Command(
    action = action_list,
    target = 'foo.out',
    source = 'foo.in',
)

如果example操作失败,foo.out仍然存在,因为前两个操作都成功了。然而,它是不完整的。

有趣的是,运行 scons 再次导致是再次重试构建 foo.out,即使它存在于文件系统中。

是的,你要找的是GetBuildFailures

扩展您的示例以包含此功能...

import atexit
import os

def delete_on_failure():
    from SCons.Script import GetBuildFailures
    for bf in GetBuildFailures():
        if os.path.isfile(bf.node.abspath):
            print 'Removing %s' % bf.node.path
            os.remove(bf.node.abspath)
atexit.register(delete_on_failure)

def example(target, source, env):
    raise Exception('failure')
    # more processing that never happens...

action_list = [
    Copy('$TARGET', '$SOURCE'),
    Chmod('$TARGET', 0755),
    example,
]

Command(
    action = action_list,
    target = 'foo.out',
    source = 'foo.in',
)

当 运行 产生以下...

>> scons --version
SCons by Steven Knight et al.:
    script: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
    engine: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
    engine path: ['/usr/lib/scons/SCons']
Copyright (c) 2001 - 2014 The SCons Foundation

>> tree 
.
├── foo.in
└── SConstruct

0 directories, 2 files

>> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Copy("foo.out", "foo.in")
Chmod("foo.out", 0755)
example(["foo.out"], ["foo.in"])
scons: *** [foo.out] Exception : failure
Traceback (most recent call last):
  File "/usr/lib/scons/SCons/Action.py", line 1065, in execute
    result = self.execfunction(target=target, source=rsources, env=env)
  File "/path/to/SConstruct", line 13, in example
    raise Exception('failure')
Exception: failure
scons: building terminated because of errors.
Removing foo.out

>> tree
.
├── foo.in
└── SConstruct

0 directories, 2 files