| OLD | NEW |
| 1 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """ | 5 """ |
| 6 Tool module for adding, to a construction environment, Chromium-specific | 6 Tool module for adding, to a construction environment, Chromium-specific |
| 7 wrappers around SCons builders. This gives us a central place for any | 7 wrappers around SCons builders. This gives us a central place for any |
| 8 customization we need to make to the different things we build. | 8 customization we need to make to the different things we build. |
| 9 """ | 9 """ |
| 10 | 10 |
| 11 import sys | 11 import sys |
| 12 | 12 |
| 13 from SCons.Script import * | 13 from SCons.Script import * |
| 14 | 14 |
| 15 import SCons.Node | |
| 16 import SCons.Util | |
| 17 | |
| 18 class Null(object): | 15 class Null(object): |
| 19 def __new__(cls, *args, **kwargs): | 16 def __new__(cls, *args, **kwargs): |
| 20 if '_inst' not in vars(cls): | 17 if '_inst' not in vars(cls): |
| 21 cls._inst = super(type, cls).__new__(cls, *args, **kwargs) | 18 cls._inst = super(type, cls).__new__(cls, *args, **kwargs) |
| 22 return cls._inst | 19 return cls._inst |
| 23 def __init__(self, *args, **kwargs): pass | 20 def __init__(self, *args, **kwargs): pass |
| 24 def __call__(self, *args, **kwargs): return self | 21 def __call__(self, *args, **kwargs): return self |
| 25 def __repr__(self): return "Null()" | 22 def __repr__(self): return "Null()" |
| 26 def __nonzero__(self): return False | 23 def __nonzero__(self): return False |
| 27 def __getattr__(self, name): return self | 24 def __getattr__(self, name): return self |
| 28 def __setattr__(self, name, val): return self | 25 def __setattr__(self, name, val): return self |
| 29 def __delattr__(self, name): return self | 26 def __delattr__(self, name): return self |
| 30 def __getitem__(self, name): return self | 27 def __getitem__(self, name): return self |
| 31 | 28 |
| 32 class FileList(object): | |
| 33 def __init__(self, entries=None): | |
| 34 if isinstance(entries, FileList): | |
| 35 entries = entries.entries | |
| 36 self.entries = entries or [] | |
| 37 def __getitem__(self, i): | |
| 38 return self.entries[i] | |
| 39 def __setitem__(self, i, item): | |
| 40 self.entries[i] = item | |
| 41 def __delitem__(self, i): | |
| 42 del self.entries[i] | |
| 43 def __add__(self, other): | |
| 44 if isinstance(other, FileList): | |
| 45 return self.__class__(self.entries + other.entries) | |
| 46 elif isinstance(other, type(self.entries)): | |
| 47 return self.__class__(self.entries + other) | |
| 48 else: | |
| 49 return self.__class__(self.entries + list(other)) | |
| 50 def __radd__(self, other): | |
| 51 if isinstance(other, FileList): | |
| 52 return self.__class__(other.entries + self.entries) | |
| 53 elif isinstance(other, type(self.entries)): | |
| 54 return self.__class__(other + self.entries) | |
| 55 else: | |
| 56 return self.__class__(list(other) + self.entries) | |
| 57 def __iadd__(self, other): | |
| 58 if isinstance(other, FileList): | |
| 59 self.entries += other.entries | |
| 60 elif isinstance(other, type(self.entries)): | |
| 61 self.entries += other | |
| 62 else: | |
| 63 self.entries += list(other) | |
| 64 return self | |
| 65 def append(self, item): | |
| 66 return self.entries.append(item) | |
| 67 def extend(self, item): | |
| 68 return self.entries.extend(item) | |
| 69 def index(self, item, *args): | |
| 70 return self.entries.index(item, *args) | |
| 71 def remove(self, item): | |
| 72 return self.entries.remove(item) | |
| 73 | |
| 74 def FileListWalk(top, topdown=True, onerror=None): | |
| 75 """ | |
| 76 """ | |
| 77 try: | |
| 78 entries = top.entries | |
| 79 except AttributeError, err: | |
| 80 if onerror is not None: | |
| 81 onerror(err) | |
| 82 return | |
| 83 | |
| 84 dirs, nondirs = [], [] | |
| 85 for entry in entries: | |
| 86 if hasattr(entry, 'entries'): | |
| 87 dirs.append(entry) | |
| 88 else: | |
| 89 nondirs.append(entry) | |
| 90 | |
| 91 if topdown: | |
| 92 yield top, dirs, nondirs | |
| 93 for entry in dirs: | |
| 94 for x in FileListWalk(entry, topdown, onerror): | |
| 95 yield x | |
| 96 if not topdown: | |
| 97 yield top, dirs, nondirs | |
| 98 | |
| 99 class ChromeFileList(FileList): | |
| 100 def Append(self, *args): | |
| 101 for element in args: | |
| 102 self.append(element) | |
| 103 def Extend(self, *args): | |
| 104 for element in args: | |
| 105 self.extend(element) | |
| 106 def Remove(self, *args): | |
| 107 for top, lists, nonlists in FileListWalk(self, topdown=False): | |
| 108 for element in args: | |
| 109 try: | |
| 110 top.remove(element) | |
| 111 except ValueError: | |
| 112 pass | |
| 113 def Replace(self, old, new): | |
| 114 for top, lists, nonlists in FileListWalk(self, topdown=False): | |
| 115 try: | |
| 116 i = top.index(old) | |
| 117 except ValueError: | |
| 118 pass | |
| 119 else: | |
| 120 if SCons.Util.is_List(new): | |
| 121 top[i:i+1] = new | |
| 122 else: | |
| 123 top[i] = new | |
| 124 | |
| 125 | |
| 126 def FilterOut(self, **kw): | |
| 127 """Removes values from existing construction variables in an Environment. | |
| 128 | |
| 129 The values to remove should be a list. For example: | |
| 130 | |
| 131 self.FilterOut(CPPDEFINES=['REMOVE_ME', 'ME_TOO']) | |
| 132 | |
| 133 Args: | |
| 134 self: Environment to alter. | |
| 135 kw: (Any other named arguments are values to remove). | |
| 136 """ | |
| 137 | |
| 138 kw = SCons.Environment.copy_non_reserved_keywords(kw) | |
| 139 for key, val in kw.items(): | |
| 140 envval = self.get(key, None) | |
| 141 if envval is None: | |
| 142 # No existing variable in the environment, so nothing to delete. | |
| 143 continue | |
| 144 | |
| 145 for vremove in val: | |
| 146 # Use while not if, so we can handle duplicates. | |
| 147 while vremove in envval: | |
| 148 envval.remove(vremove) | |
| 149 | |
| 150 self[key] = envval | |
| 151 | |
| 152 # TODO(sgk): SCons.Environment.Append() has much more logic to deal | |
| 153 # with various types of values. We should handle all those cases in here | |
| 154 # too. (If variable is a dict, etc.) | |
| 155 | |
| 156 | |
| 157 import __builtin__ | |
| 158 __builtin__.ChromeFileList = ChromeFileList | |
| 159 | |
| 160 non_compilable_suffixes = { | |
| 161 'LINUX' : set([ | |
| 162 '.bdic', | |
| 163 '.css', | |
| 164 '.dat', | |
| 165 '.fragment', | |
| 166 '.gperf', | |
| 167 '.h', | |
| 168 '.html', | |
| 169 '.hxx', | |
| 170 '.idl', | |
| 171 '.js', | |
| 172 '.mk', | |
| 173 '.rc', | |
| 174 '.sigs', | |
| 175 ]), | |
| 176 'WINDOWS' : set([ | |
| 177 '.h', | |
| 178 '.dat', | |
| 179 '.idl', | |
| 180 ]), | |
| 181 } | |
| 182 | |
| 183 def compilable(env, file): | |
| 184 base, ext = os.path.splitext(str(file)) | |
| 185 if ext in non_compilable_suffixes[env['TARGET_PLATFORM']]: | |
| 186 return False | |
| 187 return True | |
| 188 | |
| 189 def compilable_files(env, sources): | |
| 190 if not hasattr(sources, 'entries'): | |
| 191 return [x for x in sources if compilable(env, x)] | |
| 192 result = [] | |
| 193 for top, folders, nonfolders in FileListWalk(sources): | |
| 194 result.extend([x for x in nonfolders if compilable(env, x)]) | |
| 195 return result | |
| 196 | |
| 197 def ChromeProgram(env, target, source, *args, **kw): | |
| 198 source = compilable_files(env, source) | |
| 199 result = env.Program('$TOP_BUILDDIR/' + str(target), source, *args, **kw) | |
| 200 if env.get('INCREMENTAL'): | |
| 201 env.Precious(result) | |
| 202 return result | |
| 203 | |
| 204 def ChromeTestProgram(env, target, source, *args, **kw): | |
| 205 source = compilable_files(env, source) | |
| 206 result = env.Program('$TOP_BUILDDIR/' + str(target), source, *args, **kw) | |
| 207 if env.get('INCREMENTAL'): | |
| 208 env.Precious(*result) | |
| 209 return result | |
| 210 | |
| 211 def ChromeLibrary(env, target, source, *args, **kw): | |
| 212 source = compilable_files(env, source) | |
| 213 result = env.Library('$LIB_DIR/' + str(target), source, *args, **kw) | |
| 214 return result | |
| 215 | |
| 216 def ChromeLoadableModule(env, target, source, *args, **kw): | |
| 217 source = compilable_files(env, source) | |
| 218 if env.get('_GYP'): | |
| 219 result = env.LoadableModule(target, source, *args, **kw) | |
| 220 else: | |
| 221 kw['COMPONENT_STATIC'] = True | |
| 222 result = env.LoadableModule(target, source, *args, **kw) | |
| 223 return result | |
| 224 | |
| 225 def ChromeStaticLibrary(env, target, source, *args, **kw): | |
| 226 source = compilable_files(env, source) | |
| 227 if env.get('_GYP'): | |
| 228 result = env.StaticLibrary('$LIB_DIR/' + str(target), source, *args, **kw) | |
| 229 else: | |
| 230 kw['COMPONENT_STATIC'] = True | |
| 231 result = env.ComponentLibrary(target, source, *args, **kw) | |
| 232 return result | |
| 233 | |
| 234 def ChromeSharedLibrary(env, target, source, *args, **kw): | |
| 235 source = compilable_files(env, source) | |
| 236 if env.get('_GYP'): | |
| 237 result = env.SharedLibrary('$LIB_DIR/' + str(target), source, *args, **kw) | |
| 238 else: | |
| 239 kw['COMPONENT_STATIC'] = False | |
| 240 result = [env.ComponentLibrary(target, source, *args, **kw)[0]] | |
| 241 if env.get('INCREMENTAL'): | |
| 242 env.Precious(result) | |
| 243 return result | |
| 244 | |
| 245 def ChromeObject(env, *args, **kw): | |
| 246 if env.get('_GYP'): | |
| 247 result = env.Object(target, source, *args, **kw) | |
| 248 else: | |
| 249 result = env.ComponentObject(*args, **kw) | |
| 250 return result | |
| 251 | 29 |
| 252 def generate(env): | 30 def generate(env): |
| 253 env.AddMethod(ChromeProgram) | |
| 254 env.AddMethod(ChromeTestProgram) | |
| 255 env.AddMethod(ChromeLibrary) | |
| 256 env.AddMethod(ChromeLoadableModule) | |
| 257 env.AddMethod(ChromeStaticLibrary) | |
| 258 env.AddMethod(ChromeSharedLibrary) | |
| 259 env.AddMethod(ChromeObject) | |
| 260 | |
| 261 env.AddMethod(FilterOut) | |
| 262 | |
| 263 # Add the grit tool to the base environment because we use this a lot. | 31 # Add the grit tool to the base environment because we use this a lot. |
| 264 sys.path.append(env.Dir('$SRC_DIR/tools/grit').abspath) | 32 sys.path.append(env.Dir('$SRC_DIR/tools/grit').abspath) |
| 265 env.Tool('scons', toolpath=[env.Dir('$SRC_DIR/tools/grit/grit')]) | 33 env.Tool('scons', toolpath=[env.Dir('$SRC_DIR/tools/grit/grit')]) |
| 266 | 34 |
| 267 # Add the repack python script tool that we use in multiple places. | 35 # Add the repack python script tool that we use in multiple places. |
| 268 sys.path.append(env.Dir('$SRC_DIR/tools/data_pack').abspath) | 36 sys.path.append(env.Dir('$SRC_DIR/tools/data_pack').abspath) |
| 269 env.Tool('scons', toolpath=[env.Dir('$SRC_DIR/tools/data_pack/')]) | 37 env.Tool('scons', toolpath=[env.Dir('$SRC_DIR/tools/data_pack/')]) |
| 270 | 38 |
| 271 def exists(env): | 39 def exists(env): |
| 272 return True | 40 return True |
| OLD | NEW |