OLD | NEW |
---|---|
1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import copy | 5 import copy |
6 import gyp | 6 import gyp |
7 import gyp.common | 7 import gyp.common |
8 import gyp.msvs_emulation | 8 import gyp.msvs_emulation |
9 import gyp.MSVSVersion | 9 import gyp.MSVSVersion |
10 import gyp.system_test | 10 import gyp.system_test |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 # All paths as written into the .ninja files are relative to the build | 178 # All paths as written into the .ninja files are relative to the build |
179 # directory. Call these paths "ninja paths". | 179 # directory. Call these paths "ninja paths". |
180 # | 180 # |
181 # We translate between these two notions of paths with two helper | 181 # We translate between these two notions of paths with two helper |
182 # functions: | 182 # functions: |
183 # | 183 # |
184 # - GypPathToNinja translates a gyp path (i.e. relative to the .gyp file) | 184 # - GypPathToNinja translates a gyp path (i.e. relative to the .gyp file) |
185 # into the equivalent ninja path. | 185 # into the equivalent ninja path. |
186 # | 186 # |
187 # - GypPathToUniqueOutput translates a gyp path into a ninja path to write | 187 # - GypPathToUniqueOutput translates a gyp path into a ninja path to write |
188 # an output file; the result can be namespaced such that is unique | 188 # an output file; the result can be namespaced such that it is unique |
189 # to the input file name as well as the output target name. | 189 # to the input file name as well as the output target name. |
190 | 190 |
191 class NinjaWriter: | 191 class NinjaWriter: |
192 def __init__(self, target_outputs, base_dir, build_dir, output_file, flavor, | 192 def __init__(self, qualified_target, target_outputs, base_dir, build_dir, |
193 abs_build_dir=None): | 193 output_file, flavor, abs_build_dir=None): |
194 """ | 194 """ |
195 base_dir: path from source root to directory containing this gyp file, | 195 base_dir: path from source root to directory containing this gyp file, |
196 by gyp semantics, all input paths are relative to this | 196 by gyp semantics, all input paths are relative to this |
197 build_dir: path from source root to build output | 197 build_dir: path from source root to build output |
198 abs_build_dir: absolute path to the build directory | 198 abs_build_dir: absolute path to the build directory |
199 """ | 199 """ |
200 | 200 |
201 self.qualified_target = qualified_target | |
201 self.target_outputs = target_outputs | 202 self.target_outputs = target_outputs |
202 self.base_dir = base_dir | 203 self.base_dir = base_dir |
203 self.build_dir = build_dir | 204 self.build_dir = build_dir |
204 self.ninja = ninja_syntax.Writer(output_file) | 205 self.ninja = ninja_syntax.Writer(output_file) |
205 self.flavor = flavor | 206 self.flavor = flavor |
206 self.abs_build_dir = abs_build_dir | 207 self.abs_build_dir = abs_build_dir |
207 self.obj_ext = '.obj' if flavor == 'win' else '.o' | 208 self.obj_ext = '.obj' if flavor == 'win' else '.o' |
208 | 209 |
209 # Relative path from build output dir to base dir. | 210 # Relative path from build output dir to base dir. |
210 self.build_to_base = os.path.join(InvertRelativePath(build_dir), base_dir) | 211 self.build_to_base = os.path.join(InvertRelativePath(build_dir), base_dir) |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
397 if self.is_mac_bundle: | 398 if self.is_mac_bundle: |
398 mac_bundle_depends.append(output) | 399 mac_bundle_depends.append(output) |
399 | 400 |
400 # Bundle all of the above together, if needed. | 401 # Bundle all of the above together, if needed. |
401 if self.is_mac_bundle: | 402 if self.is_mac_bundle: |
402 output = self.WriteMacBundle(spec, mac_bundle_depends) | 403 output = self.WriteMacBundle(spec, mac_bundle_depends) |
403 | 404 |
404 if not output: | 405 if not output: |
405 return None | 406 return None |
406 | 407 |
407 if self.name != output and self.toolset == 'target': | |
408 # Write a short name to build this target. This benefits both the | |
409 # "build chrome" case as well as the gyp tests, which expect to be | |
410 # able to run actions and build libraries by their short name. | |
411 self.ninja.build(self.name, 'phony', output) | |
412 | |
413 assert self.target.FinalOutput(), output | 408 assert self.target.FinalOutput(), output |
414 return self.target | 409 return self.target |
415 | 410 |
416 def _WinIdlRule(self, source, prebuild, outputs): | 411 def _WinIdlRule(self, source, prebuild, outputs): |
417 """Handle the implicit VS .idl rule for one source file. Fills |outputs| | 412 """Handle the implicit VS .idl rule for one source file. Fills |outputs| |
418 with files that are generated.""" | 413 with files that are generated.""" |
419 outdir, output, vars, flags = self.msvs_settings.GetIdlBuildData( | 414 outdir, output, vars, flags = self.msvs_settings.GetIdlBuildData( |
420 source, self.config_name) | 415 source, self.config_name) |
421 outdir = self.GypPathToNinja(outdir) | 416 outdir = self.GypPathToNinja(outdir) |
422 def fix_path(path, rel=None): | 417 def fix_path(path, rel=None): |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
492 | 487 |
493 def WriteActions(self, actions, extra_sources, prebuild, | 488 def WriteActions(self, actions, extra_sources, prebuild, |
494 extra_mac_bundle_resources): | 489 extra_mac_bundle_resources): |
495 # Actions cd into the base directory. | 490 # Actions cd into the base directory. |
496 env = self.GetXcodeEnv() | 491 env = self.GetXcodeEnv() |
497 if self.flavor == 'win': | 492 if self.flavor == 'win': |
498 env = self.msvs_settings.GetVSMacroEnv('$!PRODUCT_DIR') | 493 env = self.msvs_settings.GetVSMacroEnv('$!PRODUCT_DIR') |
499 all_outputs = [] | 494 all_outputs = [] |
500 for action in actions: | 495 for action in actions: |
501 # First write out a rule for the action. | 496 # First write out a rule for the action. |
502 name = re.sub(r'[ {}$]', '_', action['action_name']) | 497 name = re.sub(r'[^a-zA-Z0-9_]', '_', '%s_%s' % (self.qualified_target, |
Nico
2012/06/04 23:10:20
nit: indent looks weird
Steve Block
2012/06/07 10:17:40
Done.
| |
498 action['action_name'])) | |
503 description = self.GenerateDescription('ACTION', | 499 description = self.GenerateDescription('ACTION', |
504 action.get('message', None), | 500 action.get('message', None), |
505 name) | 501 name) |
506 is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action) | 502 is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action) |
507 if self.flavor == 'win' else False) | 503 if self.flavor == 'win' else False) |
508 args = action['action'] | 504 args = action['action'] |
509 args = [self.msvs_settings.ConvertVSMacros(arg, self.base_to_build) | 505 args = [self.msvs_settings.ConvertVSMacros(arg, self.base_to_build) |
510 for arg in args] if self.flavor == 'win' else args | 506 for arg in args] if self.flavor == 'win' else args |
511 rule_name = self.WriteNewNinjaRule(name, args, description, | 507 rule_name = self.WriteNewNinjaRule(name, args, description, |
512 is_cygwin, env=env) | 508 is_cygwin, env=env) |
(...skipping 12 matching lines...) Expand all Loading... | |
525 | 521 |
526 self.ninja.newline() | 522 self.ninja.newline() |
527 | 523 |
528 return all_outputs | 524 return all_outputs |
529 | 525 |
530 def WriteRules(self, rules, extra_sources, prebuild, | 526 def WriteRules(self, rules, extra_sources, prebuild, |
531 extra_mac_bundle_resources): | 527 extra_mac_bundle_resources): |
532 all_outputs = [] | 528 all_outputs = [] |
533 for rule in rules: | 529 for rule in rules: |
534 # First write out a rule for the rule action. | 530 # First write out a rule for the rule action. |
535 name = rule['rule_name'] | 531 name = '%s_%s' % (self.qualified_target, rule['rule_name']) |
536 args = rule['action'] | 532 args = rule['action'] |
537 description = self.GenerateDescription( | 533 description = self.GenerateDescription( |
538 'RULE', | 534 'RULE', |
539 rule.get('message', None), | 535 rule.get('message', None), |
540 ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name) | 536 ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name) |
541 is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule) | 537 is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule) |
542 if self.flavor == 'win' else False) | 538 if self.flavor == 'win' else False) |
543 args = [self.msvs_settings.ConvertVSMacros(arg, self.base_to_build) | 539 args = [self.msvs_settings.ConvertVSMacros(arg, self.base_to_build) |
544 for arg in args] if self.flavor == 'win' else args | 540 for arg in args] if self.flavor == 'win' else args |
545 rule_name = self.WriteNewNinjaRule(name, args, description, is_cygwin) | 541 rule_name = self.WriteNewNinjaRule(name, args, description, is_cygwin) |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1443 all_targets = set() | 1439 all_targets = set() |
1444 for build_file in params['build_files']: | 1440 for build_file in params['build_files']: |
1445 for target in gyp.common.AllTargets(target_list, | 1441 for target in gyp.common.AllTargets(target_list, |
1446 target_dicts, | 1442 target_dicts, |
1447 os.path.normpath(build_file)): | 1443 os.path.normpath(build_file)): |
1448 all_targets.add(target) | 1444 all_targets.add(target) |
1449 all_outputs = set() | 1445 all_outputs = set() |
1450 | 1446 |
1451 # target_outputs is a map from qualified target name to a Target object. | 1447 # target_outputs is a map from qualified target name to a Target object. |
1452 target_outputs = {} | 1448 target_outputs = {} |
1449 # target_short_names is a map from target short name to a list of Target | |
1450 # objects. | |
1451 target_short_names = {} | |
1453 for qualified_target in target_list: | 1452 for qualified_target in target_list: |
1454 # qualified_target is like: third_party/icu/icu.gyp:icui18n#target | 1453 # qualified_target is like: third_party/icu/icu.gyp:icui18n#target |
1455 build_file, name, toolset = \ | 1454 build_file, name, toolset = \ |
1456 gyp.common.ParseQualifiedTarget(qualified_target) | 1455 gyp.common.ParseQualifiedTarget(qualified_target) |
1457 | 1456 |
1458 this_make_global_settings = data[build_file].get('make_global_settings', []) | 1457 this_make_global_settings = data[build_file].get('make_global_settings', []) |
1459 assert make_global_settings == this_make_global_settings, ( | 1458 assert make_global_settings == this_make_global_settings, ( |
1460 "make_global_settings needs to be the same for all targets.") | 1459 "make_global_settings needs to be the same for all targets.") |
1461 | 1460 |
1462 spec = target_dicts[qualified_target] | 1461 spec = target_dicts[qualified_target] |
1463 if flavor == 'mac': | 1462 if flavor == 'mac': |
1464 gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec) | 1463 gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec) |
1465 | 1464 |
1466 build_file = gyp.common.RelativePath(build_file, options.toplevel_dir) | 1465 build_file = gyp.common.RelativePath(build_file, options.toplevel_dir) |
1467 | 1466 |
1468 base_path = os.path.dirname(build_file) | 1467 base_path = os.path.dirname(build_file) |
1469 obj = 'obj' | 1468 obj = 'obj' |
1470 if toolset != 'target': | 1469 if toolset != 'target': |
1471 obj += '.' + toolset | 1470 obj += '.' + toolset |
1472 output_file = os.path.join(obj, base_path, name + '.ninja') | 1471 output_file = os.path.join(obj, base_path, name + '.ninja') |
1473 | 1472 |
1474 abs_build_dir = os.path.abspath(toplevel_build) | 1473 abs_build_dir = os.path.abspath(toplevel_build) |
1475 writer = NinjaWriter(target_outputs, base_path, build_dir, | 1474 writer = NinjaWriter(qualified_target, target_outputs, base_path, build_dir, |
1476 OpenOutput(os.path.join(toplevel_build, output_file)), | 1475 OpenOutput(os.path.join(toplevel_build, output_file)), |
1477 flavor, abs_build_dir=abs_build_dir) | 1476 flavor, abs_build_dir=abs_build_dir) |
1478 master_ninja.subninja(output_file) | 1477 master_ninja.subninja(output_file) |
1479 | 1478 |
1480 target = writer.WriteSpec(spec, config_name, generator_flags) | 1479 target = writer.WriteSpec(spec, config_name, generator_flags) |
1481 if target: | 1480 if target: |
1481 if name != target.FinalOutput() and spec['toolset'] == 'target': | |
1482 target_short_names.setdefault(name, []).append(target) | |
1482 target_outputs[qualified_target] = target | 1483 target_outputs[qualified_target] = target |
1483 if qualified_target in all_targets: | 1484 if qualified_target in all_targets: |
1484 all_outputs.add(target.FinalOutput()) | 1485 all_outputs.add(target.FinalOutput()) |
1485 | 1486 |
1487 if target_short_names: | |
1488 # Write a short name to build this target. This benefits both the | |
1489 # "build chrome" case as well as the gyp tests, which expect to be | |
1490 # able to run actions and build libraries by their short name. | |
1491 master_ninja.newline() | |
1492 master_ninja.comment('Short names for targets.') | |
1493 for short_name in target_short_names: | |
1494 master_ninja.build(short_name, 'phony', [x.FinalOutput() for x in | |
1495 target_short_names[short_name]]) | |
1496 | |
1486 if all_outputs: | 1497 if all_outputs: |
1487 master_ninja.newline() | 1498 master_ninja.newline() |
1488 master_ninja.build('all', 'phony', list(all_outputs)) | 1499 master_ninja.build('all', 'phony', list(all_outputs)) |
1489 master_ninja.default('all') | 1500 master_ninja.default('all') |
1490 | 1501 |
1491 | 1502 |
1492 def GenerateOutput(target_list, target_dicts, data, params): | 1503 def GenerateOutput(target_list, target_dicts, data, params): |
1493 if params['options'].generator_output: | 1504 if params['options'].generator_output: |
1494 raise NotImplementedError, "--generator_output not implemented for ninja" | 1505 raise NotImplementedError, "--generator_output not implemented for ninja" |
1495 | 1506 |
1496 user_config = params.get('generator_flags', {}).get('config', None) | 1507 user_config = params.get('generator_flags', {}).get('config', None) |
1497 if user_config: | 1508 if user_config: |
1498 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1509 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1499 user_config) | 1510 user_config) |
1500 else: | 1511 else: |
1501 config_names = target_dicts[target_list[0]]['configurations'].keys() | 1512 config_names = target_dicts[target_list[0]]['configurations'].keys() |
1502 for config_name in config_names: | 1513 for config_name in config_names: |
1503 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1514 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1504 config_name) | 1515 config_name) |
OLD | NEW |