Chromium Code Reviews| 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 |