1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
from __future__ import print_function
import SCons.Script
import SCons.Util
import collections
import copy
import sys
# Formats message, prints to stderr, and exits with error.
def Die(env, fmt, *args):
print('error: {}\n'.format(fmt.format(*args).strip()), file=sys.stderr)
SCons.Script.Exit(1)
# Returns a deep clone of env.
# Workaround for buggy behavior of env.Clone() in recent scons.
def DeepClone(env):
cloned_env = env.Clone()
# fixup after env.Clone()
for key in env.Dictionary():
if not cloned_env[key] is env[key]:
# already copied
continue
if callable(cloned_env[key]) \
or isinstance(cloned_env[key], SCons.Util.Unbuffered):
# not copyable
continue
if isinstance(cloned_env[key], (int, float, complex, bool, str, tuple)) \
or cloned_env[key] is None:
# immutable
continue
try:
# try to do deep copy
cloned_value = copy.deepcopy(env[key])
cloned_env[key] = cloned_value
except:
pass
return cloned_env
# env.MergeFrom(other_env) merges configuration from other_env into env.
def MergeFrom(dst_env, src_env, exclude=[]):
for key, src_val in src_env.Dictionary().items():
if key in exclude:
continue
if isinstance(src_val, SCons.Util.CLVar) \
or isinstance(src_val, collections.deque) \
or isinstance(src_val, list):
if key in dst_env.Dictionary():
for item in src_val:
if item in dst_env[key]:
dst_env[key].remove(item)
if 'FLAGS' in key:
dst_env.Append(**{key: src_val})
else:
dst_env.AppendUnique(**{key: src_val})
else:
if key not in dst_env.Dictionary():
dst_env[key] = src_val
def init(env):
env.AddMethod(Die, 'Die')
env.AddMethod(DeepClone, 'DeepClone')
env.AddMethod(MergeFrom, 'MergeFrom')
|