Is there a way to emulate Make's .DELETE_ON_FAILURE behavior? If I have a builder that executes a series of Actions to produce a target, I would expect them to operate atomically. If an earlier Action produces an (incomplete) file, and a later action fails to modify it, I would like the target file to be deleted, instead of remaining in its incomplete state.
Consider this SConstruct file:
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',
)
If the example action fails, foo.out still exists, because the first two actions were successful. However, it is incomplete.
Interestingly, running scons again causes is to again retry to build foo.out, even though it exists in the filesystem.
Yes, what you are looking for is GetBuildFailures.
Expanding on your example to include this feature...
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',
)
Which when run produces the following...
>> 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With