OLD | NEW |
---|---|
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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 if vals['type'] == 'gyp': | 140 if vals['type'] == 'gyp': |
141 return self.RunGYPGen(vals) | 141 return self.RunGYPGen(vals) |
142 | 142 |
143 raise MBErr('Unknown meta-build type "%s"' % vals['type']) | 143 raise MBErr('Unknown meta-build type "%s"' % vals['type']) |
144 | 144 |
145 def CmdLookup(self): | 145 def CmdLookup(self): |
146 vals = self.GetConfig() | 146 vals = self.GetConfig() |
147 if vals['type'] == 'gn': | 147 if vals['type'] == 'gn': |
148 cmd = self.GNCmd('gen', '<path>', vals['gn_args']) | 148 cmd = self.GNCmd('gen', '<path>', vals['gn_args']) |
149 elif vals['type'] == 'gyp': | 149 elif vals['type'] == 'gyp': |
150 if vals['gyp_crosscompile']: | |
151 self.Print('GYP_CROSSCOMPILE=1') | |
150 cmd = self.GYPCmd('<path>', vals['gyp_defines'], vals['gyp_config']) | 152 cmd = self.GYPCmd('<path>', vals['gyp_defines'], vals['gyp_config']) |
151 else: | 153 else: |
152 raise MBErr('Unknown meta-build type "%s"' % vals['type']) | 154 raise MBErr('Unknown meta-build type "%s"' % vals['type']) |
153 | 155 |
154 self.PrintCmd(cmd) | 156 self.PrintCmd(cmd) |
155 return 0 | 157 return 0 |
156 | 158 |
157 def CmdHelp(self): | 159 def CmdHelp(self): |
158 if self.args.subcommand: | 160 if self.args.subcommand: |
159 self.ParseArgs([self.args.subcommand, '--help']) | 161 self.ParseArgs([self.args.subcommand, '--help']) |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 | 284 |
283 return self.masters[self.args.master][self.args.builder] | 285 return self.masters[self.args.master][self.args.builder] |
284 | 286 |
285 def FlattenConfig(self, config): | 287 def FlattenConfig(self, config): |
286 mixins = self.configs[config] | 288 mixins = self.configs[config] |
287 vals = { | 289 vals = { |
288 'type': None, | 290 'type': None, |
289 'gn_args': [], | 291 'gn_args': [], |
290 'gyp_config': [], | 292 'gyp_config': [], |
291 'gyp_defines': [], | 293 'gyp_defines': [], |
294 'gyp_crosscompile': False, | |
292 } | 295 } |
293 | 296 |
294 visited = [] | 297 visited = [] |
295 self.FlattenMixins(mixins, vals, visited) | 298 self.FlattenMixins(mixins, vals, visited) |
296 return vals | 299 return vals |
297 | 300 |
298 def FlattenMixins(self, mixins, vals, visited): | 301 def FlattenMixins(self, mixins, vals, visited): |
299 for m in mixins: | 302 for m in mixins: |
300 if m not in self.mixins: | 303 if m not in self.mixins: |
301 raise MBErr('Unknown mixin "%s"' % m) | 304 raise MBErr('Unknown mixin "%s"' % m) |
302 | 305 |
303 # TODO: check for cycles in mixins. | 306 # TODO: check for cycles in mixins. |
304 | 307 |
305 visited.append(m) | 308 visited.append(m) |
306 | 309 |
307 mixin_vals = self.mixins[m] | 310 mixin_vals = self.mixins[m] |
308 if 'type' in mixin_vals: | 311 if 'type' in mixin_vals: |
309 vals['type'] = mixin_vals['type'] | 312 vals['type'] = mixin_vals['type'] |
310 if 'gn_args' in mixin_vals: | 313 if 'gn_args' in mixin_vals: |
311 if vals['gn_args']: | 314 if vals['gn_args']: |
312 vals['gn_args'] += ' ' + mixin_vals['gn_args'] | 315 vals['gn_args'] += ' ' + mixin_vals['gn_args'] |
313 else: | 316 else: |
314 vals['gn_args'] = mixin_vals['gn_args'] | 317 vals['gn_args'] = mixin_vals['gn_args'] |
315 if 'gyp_config' in mixin_vals: | 318 if 'gyp_config' in mixin_vals: |
316 vals['gyp_config'] = mixin_vals['gyp_config'] | 319 vals['gyp_config'] = mixin_vals['gyp_config'] |
320 if 'gyp_crosscompile' in mixin_vals: | |
321 vals['gyp_crosscompile'] = mixin_vals['gyp_crosscompile'] | |
317 if 'gyp_defines' in mixin_vals: | 322 if 'gyp_defines' in mixin_vals: |
318 if vals['gyp_defines']: | 323 if vals['gyp_defines']: |
319 vals['gyp_defines'] += ' ' + mixin_vals['gyp_defines'] | 324 vals['gyp_defines'] += ' ' + mixin_vals['gyp_defines'] |
320 else: | 325 else: |
321 vals['gyp_defines'] = mixin_vals['gyp_defines'] | 326 vals['gyp_defines'] = mixin_vals['gyp_defines'] |
322 if 'mixins' in mixin_vals: | 327 if 'mixins' in mixin_vals: |
323 self.FlattenMixins(mixin_vals['mixins'], vals, visited) | 328 self.FlattenMixins(mixin_vals['mixins'], vals, visited) |
324 return vals | 329 return vals |
325 | 330 |
326 def RunGNGen(self, vals): | 331 def RunGNGen(self, vals): |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 | 424 |
420 def RunGYPGen(self, vals): | 425 def RunGYPGen(self, vals): |
421 path = self.args.path[0] | 426 path = self.args.path[0] |
422 | 427 |
423 output_dir, gyp_config = self.ParseGYPConfigPath(path) | 428 output_dir, gyp_config = self.ParseGYPConfigPath(path) |
424 if gyp_config != vals['gyp_config']: | 429 if gyp_config != vals['gyp_config']: |
425 raise MBErr('The last component of the path (%s) must match the ' | 430 raise MBErr('The last component of the path (%s) must match the ' |
426 'GYP configuration specified in the config (%s), and ' | 431 'GYP configuration specified in the config (%s), and ' |
427 'it does not.' % (gyp_config, vals['gyp_config'])) | 432 'it does not.' % (gyp_config, vals['gyp_config'])) |
428 cmd = self.GYPCmd(output_dir, vals['gyp_defines'], config=gyp_config) | 433 cmd = self.GYPCmd(output_dir, vals['gyp_defines'], config=gyp_config) |
429 ret, _, _ = self.Run(cmd) | 434 env = os.environ.copy() |
435 if vals['gyp_crosscompile']: | |
436 if self.args.verbose: | |
437 self.Print('Setting GYP_CROSSCOMPILE=1 in the environment') | |
438 env['GYP_CROSSCOMPILE'] = '1' | |
Nico
2015/08/14 00:14:30
Hm, this copy-env-and-set pattern has caused me tr
Dirk Pranke
2015/08/14 00:19:17
I'm not sure why that would make a difference, but
| |
439 ret, _, _ = self.Run(cmd, env=env) | |
430 return ret | 440 return ret |
431 | 441 |
432 def RunGYPAnalyze(self, vals): | 442 def RunGYPAnalyze(self, vals): |
433 output_dir, gyp_config = self.ParseGYPConfigPath(self.args.path[0]) | 443 output_dir, gyp_config = self.ParseGYPConfigPath(self.args.path[0]) |
434 if gyp_config != vals['gyp_config']: | 444 if gyp_config != vals['gyp_config']: |
435 raise MBErr('The last component of the path (%s) must match the ' | 445 raise MBErr('The last component of the path (%s) must match the ' |
436 'GYP configuration specified in the config (%s), and ' | 446 'GYP configuration specified in the config (%s), and ' |
437 'it does not.' % (gyp_config, vals['gyp_config'])) | 447 'it does not.' % (gyp_config, vals['gyp_config'])) |
438 if self.args.verbose: | 448 if self.args.verbose: |
439 inp = self.ReadInputJSON(['files', 'targets']) | 449 inp = self.ReadInputJSON(['files', 'targets']) |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
745 cmd = ['python'] + cmd[1:] | 755 cmd = ['python'] + cmd[1:] |
746 self.Print(*[pipes.quote(c) for c in cmd]) | 756 self.Print(*[pipes.quote(c) for c in cmd]) |
747 | 757 |
748 def PrintJSON(self, obj): | 758 def PrintJSON(self, obj): |
749 self.Print(json.dumps(obj, indent=2, sort_keys=True)) | 759 self.Print(json.dumps(obj, indent=2, sort_keys=True)) |
750 | 760 |
751 def Print(self, *args, **kwargs): | 761 def Print(self, *args, **kwargs): |
752 # This function largely exists so it can be overridden for testing. | 762 # This function largely exists so it can be overridden for testing. |
753 print(*args, **kwargs) | 763 print(*args, **kwargs) |
754 | 764 |
755 def Run(self, cmd): | 765 def Run(self, cmd, env=None): |
756 # This function largely exists so it can be overridden for testing. | 766 # This function largely exists so it can be overridden for testing. |
757 if self.args.dryrun or self.args.verbose: | 767 if self.args.dryrun or self.args.verbose: |
758 self.PrintCmd(cmd) | 768 self.PrintCmd(cmd) |
759 if self.args.dryrun: | 769 if self.args.dryrun: |
760 return 0, '', '' | 770 return 0, '', '' |
761 ret, out, err = self.Call(cmd) | 771 ret, out, err = self.Call(cmd, env=env) |
762 if self.args.verbose: | 772 if self.args.verbose: |
763 if out: | 773 if out: |
764 self.Print(out, end='') | 774 self.Print(out, end='') |
765 if err: | 775 if err: |
766 self.Print(err, end='', file=sys.stderr) | 776 self.Print(err, end='', file=sys.stderr) |
767 return ret, out, err | 777 return ret, out, err |
768 | 778 |
769 def Call(self, cmd): | 779 def Call(self, cmd, env=None): |
770 p = subprocess.Popen(cmd, shell=False, cwd=self.chromium_src_dir, | 780 p = subprocess.Popen(cmd, shell=False, cwd=self.chromium_src_dir, |
771 stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 781 stdout=subprocess.PIPE, stderr=subprocess.PIPE, |
782 env=env) | |
772 out, err = p.communicate() | 783 out, err = p.communicate() |
773 return p.returncode, out, err | 784 return p.returncode, out, err |
774 | 785 |
775 def ExpandUser(self, path): | 786 def ExpandUser(self, path): |
776 # This function largely exists so it can be overridden for testing. | 787 # This function largely exists so it can be overridden for testing. |
777 return os.path.expanduser(path) | 788 return os.path.expanduser(path) |
778 | 789 |
779 def Exists(self, path): | 790 def Exists(self, path): |
780 # This function largely exists so it can be overridden for testing. | 791 # This function largely exists so it can be overridden for testing. |
781 return os.path.exists(path) | 792 return os.path.exists(path) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 | 825 |
815 if __name__ == '__main__': | 826 if __name__ == '__main__': |
816 try: | 827 try: |
817 sys.exit(main(sys.argv[1:])) | 828 sys.exit(main(sys.argv[1:])) |
818 except MBErr as e: | 829 except MBErr as e: |
819 print(e) | 830 print(e) |
820 sys.exit(1) | 831 sys.exit(1) |
821 except KeyboardInterrupt: | 832 except KeyboardInterrupt: |
822 print("interrupted, exiting", stream=sys.stderr) | 833 print("interrupted, exiting", stream=sys.stderr) |
823 sys.exit(130) | 834 sys.exit(130) |
OLD | NEW |