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