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

Side by Side Diff: tools/mb/mb.py

Issue 1338123002: Make MB clobber build directories when switching between GYP and GN. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months 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
« no previous file with comments | « no previous file | tools/mb/mb_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """MB - the Meta-Build wrapper around GYP and GN 6 """MB - the Meta-Build wrapper around GYP and GN
7 7
8 MB is a wrapper script for GYP and GN that can be used to generate build files 8 MB is a wrapper script for GYP and GN that can be used to generate build files
9 for sets of canned configurations and analyze them. 9 for sets of canned configurations and analyze them.
10 """ 10 """
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 vals = self.GetConfig() 128 vals = self.GetConfig()
129 if vals['type'] == 'gn': 129 if vals['type'] == 'gn':
130 return self.RunGNAnalyze(vals) 130 return self.RunGNAnalyze(vals)
131 elif vals['type'] == 'gyp': 131 elif vals['type'] == 'gyp':
132 return self.RunGYPAnalyze(vals) 132 return self.RunGYPAnalyze(vals)
133 else: 133 else:
134 raise MBErr('Unknown meta-build type "%s"' % vals['type']) 134 raise MBErr('Unknown meta-build type "%s"' % vals['type'])
135 135
136 def CmdGen(self): 136 def CmdGen(self):
137 vals = self.GetConfig() 137 vals = self.GetConfig()
138
139 self.ClobberIfNeeded(vals)
140
138 if vals['type'] == 'gn': 141 if vals['type'] == 'gn':
139 return self.RunGNGen(vals) 142 return self.RunGNGen(vals)
140 if vals['type'] == 'gyp': 143 if vals['type'] == 'gyp':
141 return self.RunGYPGen(vals) 144 return self.RunGYPGen(vals)
142 145
143 raise MBErr('Unknown meta-build type "%s"' % vals['type']) 146 raise MBErr('Unknown meta-build type "%s"' % vals['type'])
144 147
145 def CmdLookup(self): 148 def CmdLookup(self):
146 vals = self.GetConfig() 149 vals = self.GetConfig()
147 if vals['type'] == 'gn': 150 if vals['type'] == 'gn':
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 (self.args.builder, self.args.master, self.args.config_file)) 286 (self.args.builder, self.args.master, self.args.config_file))
284 287
285 return self.masters[self.args.master][self.args.builder] 288 return self.masters[self.args.master][self.args.builder]
286 289
287 def FlattenConfig(self, config): 290 def FlattenConfig(self, config):
288 mixins = self.configs[config] 291 mixins = self.configs[config]
289 vals = { 292 vals = {
290 'type': None, 293 'type': None,
291 'gn_args': [], 294 'gn_args': [],
292 'gyp_config': [], 295 'gyp_config': [],
293 'gyp_defines': [], 296 'gyp_defines': '',
Dirk Pranke 2015/09/12 00:49:41 this was a bug caught by the new unit tests.
294 'gyp_crosscompile': False, 297 'gyp_crosscompile': False,
295 } 298 }
296 299
297 visited = [] 300 visited = []
298 self.FlattenMixins(mixins, vals, visited) 301 self.FlattenMixins(mixins, vals, visited)
299 return vals 302 return vals
300 303
301 def FlattenMixins(self, mixins, vals, visited): 304 def FlattenMixins(self, mixins, vals, visited):
302 for m in mixins: 305 for m in mixins:
303 if m not in self.mixins: 306 if m not in self.mixins:
(...skipping 17 matching lines...) Expand all
321 vals['gyp_crosscompile'] = mixin_vals['gyp_crosscompile'] 324 vals['gyp_crosscompile'] = mixin_vals['gyp_crosscompile']
322 if 'gyp_defines' in mixin_vals: 325 if 'gyp_defines' in mixin_vals:
323 if vals['gyp_defines']: 326 if vals['gyp_defines']:
324 vals['gyp_defines'] += ' ' + mixin_vals['gyp_defines'] 327 vals['gyp_defines'] += ' ' + mixin_vals['gyp_defines']
325 else: 328 else:
326 vals['gyp_defines'] = mixin_vals['gyp_defines'] 329 vals['gyp_defines'] = mixin_vals['gyp_defines']
327 if 'mixins' in mixin_vals: 330 if 'mixins' in mixin_vals:
328 self.FlattenMixins(mixin_vals['mixins'], vals, visited) 331 self.FlattenMixins(mixin_vals['mixins'], vals, visited)
329 return vals 332 return vals
330 333
334 def ClobberIfNeeded(self, vals):
335 path = self.args.path[0]
336 build_dir = self.ToAbsPath(path)
337 mb_type_path = os.path.join(build_dir, 'mb_type')
338 needs_clobber = False
339 new_mb_type = vals['type']
340 if self.Exists(build_dir):
341 if self.Exists(mb_type_path):
342 old_mb_type = self.ReadFile(mb_type_path)
343 if old_mb_type != new_mb_type:
344 self.Print("Build type mismatch: was %s, will be %s, clobbering %s" %
345 (old_mb_type, new_mb_type, path))
346 needs_clobber = True
347 else:
348 # There is no 'mb_type' file in the build directory, so this probably
349 # means that the prior build(s) were not done through mb, and we
350 # have no idea if this was a GYP build or a GN build. Clobber it
351 # to be safe.
352 self.Print("%s/mb_type missing, clobbering to be safe" % path)
353 needs_clobber = True
354
355 if needs_clobber:
356 self.RemoveDirectory(build_dir)
357
358 self.MaybeMakeDirectory(build_dir)
359 self.WriteFile(mb_type_path, new_mb_type)
360
331 def RunGNGen(self, vals): 361 def RunGNGen(self, vals):
332 path = self.args.path[0] 362 path = self.args.path[0]
333 363
334 cmd = self.GNCmd('gen', path, vals['gn_args']) 364 cmd = self.GNCmd('gen', path, vals['gn_args'])
335 365
336 swarming_targets = [] 366 swarming_targets = []
337 if self.args.swarming_targets_file: 367 if self.args.swarming_targets_file:
338 # We need GN to generate the list of runtime dependencies for 368 # We need GN to generate the list of runtime dependencies for
339 # the compile targets listed (one per line) in the file so 369 # the compile targets listed (one per line) in the file so
340 # we can run them via swarming. We use ninja_to_gn.pyl to convert 370 # we can run them via swarming. We use ninja_to_gn.pyl to convert
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 844
815 def ReadFile(self, path): 845 def ReadFile(self, path):
816 # This function largely exists so it can be overriden for testing. 846 # This function largely exists so it can be overriden for testing.
817 with open(path) as fp: 847 with open(path) as fp:
818 return fp.read() 848 return fp.read()
819 849
820 def RemoveFile(self, path): 850 def RemoveFile(self, path):
821 # This function largely exists so it can be overriden for testing. 851 # This function largely exists so it can be overriden for testing.
822 os.remove(path) 852 os.remove(path)
823 853
854 def RemoveDirectory(self, abs_path):
855 if sys.platform == 'win32':
856 # In other places in chromium, we often have to retry this command
brettw 2015/09/12 02:08:25 But doesn't shutil still work? I don't see the nee
857 # because we're worried about other processes still holding on to
858 # file handles, but when MB is invoked, it will be early enough in the
859 # build that their should be no other processes to interfere. We
860 # can change this if need be.
861 self.Run(['cmd.exe', '/c', 'rmdir', '/q', '/s', abs_path])
862 else:
863 shutil.rmtree(abs_path, ignore_errors=True)
864
824 def TempFile(self, mode='w'): 865 def TempFile(self, mode='w'):
825 # This function largely exists so it can be overriden for testing. 866 # This function largely exists so it can be overriden for testing.
826 return tempfile.NamedTemporaryFile(mode=mode, delete=False) 867 return tempfile.NamedTemporaryFile(mode=mode, delete=False)
827 868
828 def WriteFile(self, path, contents): 869 def WriteFile(self, path, contents):
829 # This function largely exists so it can be overriden for testing. 870 # This function largely exists so it can be overriden for testing.
830 if self.args.dryrun or self.args.verbose: 871 if self.args.dryrun or self.args.verbose:
831 self.Print('\nWriting """\\\n%s""" to %s.\n' % (contents, path)) 872 self.Print('\nWriting """\\\n%s""" to %s.\n' % (contents, path))
832 with open(path, 'w') as fp: 873 with open(path, 'w') as fp:
833 return fp.write(contents) 874 return fp.write(contents)
834 875
835 876
836 class MBErr(Exception): 877 class MBErr(Exception):
837 pass 878 pass
838 879
839 880
840 if __name__ == '__main__': 881 if __name__ == '__main__':
841 try: 882 try:
842 sys.exit(main(sys.argv[1:])) 883 sys.exit(main(sys.argv[1:]))
843 except MBErr as e: 884 except MBErr as e:
844 print(e) 885 print(e)
845 sys.exit(1) 886 sys.exit(1)
846 except KeyboardInterrupt: 887 except KeyboardInterrupt:
847 print("interrupted, exiting", stream=sys.stderr) 888 print("interrupted, exiting", stream=sys.stderr)
848 sys.exit(130) 889 sys.exit(130)
OLDNEW
« no previous file with comments | « no previous file | tools/mb/mb_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698