Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: build/landmines.py

Issue 11293111: Revert 166085 - Selective build clobbering feature (landmines.py and android build scripts). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « build/gyp_helper.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """
7 This file holds a list of reasons why a particular build needs to be clobbered
8 (or a list of 'landmines').
9
10 This script runs every build as a hook. If it detects that the build should
11 be clobbered, it will touch the file <build_dir>/.landmine_triggered. The
12 various build scripts will then check for the presence of this file and clobber
13 accordingly. The script will also emit the reasons for the clobber to stdout.
14
15 A landmine is tripped when a builder checks out a different revision, and the
16 diff between the new landmines and the old ones is non-null. At this point, the
17 build is clobbered.
18 """
19
20 import difflib
21 import functools
22 import gyp_helper
23 import os
24 import shlex
25 import sys
26 import time
27
28 SRC_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
29
30 def memoize(default=None):
31 """This decorator caches the return value of a parameterless pure function"""
32 def memoizer(func):
33 val = []
34 @functools.wraps(func)
35 def inner():
36 if not val:
37 ret = func()
38 val.append(ret if ret is not None else default)
39 print '%s -> %r' % (func.__name__, val[0])
40 return val[0]
41 return inner
42 return memoizer
43
44
45 @memoize()
46 def IsWindows():
47 return sys.platform.startswith('win') or sys.platform == 'cygwin'
48
49
50 @memoize()
51 def IsLinux():
52 return sys.platform.startswith('linux')
53
54
55 @memoize()
56 def IsMac():
57 return sys.platform.startswith('darwin')
58
59
60 @memoize()
61 def gyp_defines():
62 """Parses and returns GYP_DEFINES env var as a dictionary."""
63 return dict(arg.split('=', 1)
64 for arg in shlex.split(os.environ.get('GYP_DEFINES', '')))
65
66
67 @memoize()
68 def distributor():
69 """
70 Returns a string which is the distributed build engine in use (if any).
71 Possible values: 'goma', 'ib', ''
72 """
73 if 'goma' in gyp_defines():
74 return 'goma'
75 elif IsWindows():
76 if 'CHROME_HEADLESS' in os.environ:
77 return 'ib' # use (win and !goma and headless) as approximation of ib
78
79
80 @memoize()
81 def platform():
82 """
83 Returns a string representing the platform this build is targetted for.
84 Possible values: 'win', 'mac', 'linux', 'ios', 'android'
85 """
86 if 'OS' in gyp_defines():
87 if 'android' in gyp_defines()['OS']:
88 return 'android'
89 else:
90 return gyp_defines()['OS']
91 elif IsWindows():
92 return 'win'
93 elif IsLinux():
94 return 'linux'
95 else:
96 return 'mac'
97
98
99 @memoize()
100 def builder():
101 """
102 Returns a string representing the build engine (not compiler) to use.
103 Possible values: 'make', 'ninja', 'xcode', 'msvs', 'scons'
104 """
105 if 'GYP_GENERATORS' in os.environ:
106 # for simplicity, only support the first explicit generator
107 generator = os.environ['GYP_GENERATORS'].split(',')[0]
108 if generator.endswith('-android'):
109 return generator.split('-')[0]
110 else:
111 return generator
112 else:
113 if platform() == 'android':
114 # Good enough for now? Do any android bots use make?
115 return 'ninja'
116 elif platform() == 'ios':
117 return 'xcode'
118 elif IsWindows():
119 return 'msvs'
120 elif IsLinux():
121 return 'make'
122 elif IsMac():
123 return 'xcode'
124 else:
125 assert False, 'Don\'t know what builder we\'re using!'
126
127
128 def get_landmines(target):
129 """
130 ALL LANDMINES ARE DEFINED HERE.
131 target is 'Release' or 'Debug'
132 """
133 landmines = []
134 add = lambda item: landmines.append(item + '\n')
135
136 if (distributor() == 'goma' and platform() == 'win32' and
137 builder() == 'ninja'):
138 add('Need to clobber winja goma due to backend cwd cache fix.')
139
140 return landmines
141
142
143 def get_target_build_dir(build_tool, target, is_iphone=False):
144 """
145 Returns output directory absolute path dependent on build and targets.
146 Examples:
147 r'c:\b\build\slave\win\build\src\out\Release'
148 '/mnt/data/b/build/slave/linux/build/src/out/Debug'
149 '/b/build/slave/ios_rel_device/build/src/xcodebuild/Release-iphoneos'
150 """
151 ret = None
152 if build_tool == 'xcode':
153 ret = os.path.join(SRC_DIR, 'xcodebuild',
154 target + ('-iphoneos' if is_iphone else ''))
155 elif build_tool == 'make':
156 ret = os.path.join(SRC_DIR, 'out', target)
157 elif build_tool == 'ninja':
158 ret = os.path.join(SRC_DIR, 'out', target)
159 elif build_tool == 'msvs':
160 ret = os.path.join(SRC_DIR, 'build', target)
161 elif build_tool == 'scons':
162 ret = os.path.join(SRC_DIR, 'sconsbuild', target)
163 else:
164 raise NotImplementedError()
165 return os.path.abspath(ret)
166
167
168 def main(argv):
169 if len(argv) > 1:
170 print('Unknown arguments %s' % argv[1:])
171 return 1
172
173 gyp_helper.apply_chromium_gyp_env()
174
175 for target in ('Debug', 'Release'):
176 out_dir = get_target_build_dir(builder(), target,
177 platform() == 'ios')
178
179 landmines_path = os.path.join(out_dir, '.landmines')
180 if not os.path.exists(out_dir):
181 os.makedirs(out_dir)
182
183 new_landmines = get_landmines(target)
184
185 if not os.path.exists(landmines_path):
186 with open(landmines_path, 'w') as f:
187 f.writelines(new_landmines)
188 else:
189 triggered = os.path.join(out_dir, '.landmines_triggered')
190 with open(landmines_path, 'r') as f:
191 old_landmines = f.readlines()
192 if old_landmines != new_landmines:
193 old_date = time.ctime(os.stat(landmines_path).st_ctime)
194 diff = difflib.unified_diff(old_landmines, new_landmines,
195 fromfile='old_landmines', tofile='new_landmines',
196 fromfiledate=old_date, tofiledate=time.ctime(), n=0)
197
198 with open(triggered, 'w') as f:
199 f.writelines(diff)
200 elif os.path.exists(triggered):
201 # Remove false triggered landmines.
202 os.remove(triggered)
203
204 return 0
205
206
207 if __name__ == '__main__':
208 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/gyp_helper.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698