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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 subp.add_argument('path', nargs=1, | 113 subp.add_argument('path', nargs=1, |
114 help='path build was generated into.') | 114 help='path build was generated into.') |
115 subp.add_argument('input_path', nargs=1, | 115 subp.add_argument('input_path', nargs=1, |
116 help='path to a file containing the input arguments ' | 116 help='path to a file containing the input arguments ' |
117 'as a JSON object.') | 117 'as a JSON object.') |
118 subp.add_argument('output_path', nargs=1, | 118 subp.add_argument('output_path', nargs=1, |
119 help='path to a file containing the output arguments ' | 119 help='path to a file containing the output arguments ' |
120 'as a JSON object.') | 120 'as a JSON object.') |
121 subp.set_defaults(func=self.CmdAnalyze) | 121 subp.set_defaults(func=self.CmdAnalyze) |
122 | 122 |
| 123 subp = subps.add_parser('export', |
| 124 help='print out the expanded configuration for' |
| 125 'each builder as a JSON object') |
| 126 subp.add_argument('-f', '--config-file', metavar='PATH', |
| 127 default=self.default_config, |
| 128 help='path to config file ' |
| 129 '(default is //tools/mb/mb_config.pyl)') |
| 130 subp.add_argument('-g', '--goma-dir', |
| 131 help='path to goma directory') |
| 132 subp.set_defaults(func=self.CmdExport) |
| 133 |
123 subp = subps.add_parser('gen', | 134 subp = subps.add_parser('gen', |
124 help='generate a new set of build files') | 135 help='generate a new set of build files') |
125 AddCommonOptions(subp) | 136 AddCommonOptions(subp) |
126 subp.add_argument('--swarming-targets-file', | 137 subp.add_argument('--swarming-targets-file', |
127 help='save runtime dependencies for targets listed ' | 138 help='save runtime dependencies for targets listed ' |
128 'in file.') | 139 'in file.') |
129 subp.add_argument('path', nargs=1, | 140 subp.add_argument('path', nargs=1, |
130 help='path to generate build into') | 141 help='path to generate build into') |
131 subp.set_defaults(func=self.CmdGen) | 142 subp.set_defaults(func=self.CmdGen) |
132 | 143 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 '--swarming-targets-file', self.args.swarming_targets_file) | 253 '--swarming-targets-file', self.args.swarming_targets_file) |
243 | 254 |
244 def CmdAnalyze(self): | 255 def CmdAnalyze(self): |
245 vals = self.Lookup() | 256 vals = self.Lookup() |
246 self.ClobberIfNeeded(vals) | 257 self.ClobberIfNeeded(vals) |
247 if vals['type'] == 'gn': | 258 if vals['type'] == 'gn': |
248 return self.RunGNAnalyze(vals) | 259 return self.RunGNAnalyze(vals) |
249 else: | 260 else: |
250 return self.RunGYPAnalyze(vals) | 261 return self.RunGYPAnalyze(vals) |
251 | 262 |
| 263 def CmdExport(self): |
| 264 self.ReadConfigFile() |
| 265 obj = {} |
| 266 for master, builders in self.masters.items(): |
| 267 obj[master] = {} |
| 268 for builder in builders: |
| 269 config = self.masters[master][builder] |
| 270 if not config: |
| 271 continue |
| 272 |
| 273 if isinstance(config, list): |
| 274 args = [self.FlattenConfig(c)['gn_args'] for c in config] |
| 275 elif config.startswith('//'): |
| 276 args = config |
| 277 else: |
| 278 args = self.FlattenConfig(config)['gn_args'] |
| 279 if 'error' in args: |
| 280 continue |
| 281 |
| 282 obj[master][builder] = args |
| 283 |
| 284 # Dump object and trim trailing whitespace. |
| 285 s = '\n'.join(l.rstrip() for l in |
| 286 json.dumps(obj, sort_keys=True, indent=2).splitlines()) |
| 287 self.Print(s) |
| 288 return 0 |
| 289 |
252 def CmdGen(self): | 290 def CmdGen(self): |
253 vals = self.Lookup() | 291 vals = self.Lookup() |
254 self.ClobberIfNeeded(vals) | 292 self.ClobberIfNeeded(vals) |
255 if vals['type'] == 'gn': | 293 if vals['type'] == 'gn': |
256 return self.RunGNGen(vals) | 294 return self.RunGNGen(vals) |
257 else: | 295 else: |
258 return self.RunGYPGen(vals) | 296 return self.RunGYPGen(vals) |
259 | 297 |
260 def CmdHelp(self): | 298 def CmdHelp(self): |
261 if self.args.subcommand: | 299 if self.args.subcommand: |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 'type': 'gn', | 629 'type': 'gn', |
592 } | 630 } |
593 else: | 631 else: |
594 if not config in self.configs: | 632 if not config in self.configs: |
595 raise MBErr('Config "%s" not found in %s' % | 633 raise MBErr('Config "%s" not found in %s' % |
596 (config, self.args.config_file)) | 634 (config, self.args.config_file)) |
597 vals = self.FlattenConfig(config) | 635 vals = self.FlattenConfig(config) |
598 | 636 |
599 # Do some basic sanity checking on the config so that we | 637 # Do some basic sanity checking on the config so that we |
600 # don't have to do this in every caller. | 638 # don't have to do this in every caller. |
601 assert 'type' in vals, 'No meta-build type specified in the config' | 639 if 'type' not in vals: |
| 640 vals['type'] = 'gn' |
602 assert vals['type'] in ('gn', 'gyp'), ( | 641 assert vals['type'] in ('gn', 'gyp'), ( |
603 'Unknown meta-build type "%s"' % vals['gn_args']) | 642 'Unknown meta-build type "%s"' % vals['gn_args']) |
604 | 643 |
605 return vals | 644 return vals |
606 | 645 |
607 def ReadBotConfig(self): | 646 def ReadBotConfig(self): |
608 if not self.args.master or not self.args.builder: | 647 if not self.args.master or not self.args.builder: |
609 return {} | 648 return {} |
610 path = self.PathJoin(self.chromium_src_dir, 'ios', 'build', 'bots', | 649 path = self.PathJoin(self.chromium_src_dir, 'ios', 'build', 'bots', |
611 self.args.master, self.args.builder + '.json') | 650 self.args.master, self.args.builder + '.json') |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 if self.args.phase is not None: | 720 if self.args.phase is not None: |
682 raise MBErr('Must not specify a build --phase for %s on %s' % | 721 raise MBErr('Must not specify a build --phase for %s on %s' % |
683 (self.args.builder, self.args.master)) | 722 (self.args.builder, self.args.master)) |
684 return config | 723 return config |
685 | 724 |
686 def FlattenConfig(self, config): | 725 def FlattenConfig(self, config): |
687 mixins = self.configs[config] | 726 mixins = self.configs[config] |
688 vals = { | 727 vals = { |
689 'args_file': '', | 728 'args_file': '', |
690 'cros_passthrough': False, | 729 'cros_passthrough': False, |
691 'gn_args': [], | 730 'gn_args': '', |
692 'gyp_defines': '', | 731 'gyp_defines': '', |
693 'gyp_crosscompile': False, | 732 'gyp_crosscompile': False, |
694 'type': None, | 733 'type': None, |
695 } | 734 } |
696 | 735 |
697 visited = [] | 736 visited = [] |
698 self.FlattenMixins(mixins, vals, visited) | 737 self.FlattenMixins(mixins, vals, visited) |
699 return vals | 738 return vals |
700 | 739 |
701 def FlattenMixins(self, mixins, vals, visited): | 740 def FlattenMixins(self, mixins, vals, visited): |
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1523 # Then check to see if the arg contains any metacharacters other than | 1562 # Then check to see if the arg contains any metacharacters other than |
1524 # double quotes; if it does, quote everything (including the double | 1563 # double quotes; if it does, quote everything (including the double |
1525 # quotes) for safety. | 1564 # quotes) for safety. |
1526 if any(a in UNSAFE_FOR_CMD for a in arg): | 1565 if any(a in UNSAFE_FOR_CMD for a in arg): |
1527 arg = ''.join('^' + a if a in ALL_META_CHARS else a for a in arg) | 1566 arg = ''.join('^' + a if a in ALL_META_CHARS else a for a in arg) |
1528 return arg | 1567 return arg |
1529 | 1568 |
1530 | 1569 |
1531 if __name__ == '__main__': | 1570 if __name__ == '__main__': |
1532 sys.exit(main(sys.argv[1:])) | 1571 sys.exit(main(sys.argv[1:])) |
OLD | NEW |