# Copyright (c) 2013 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import copy
import hashlib
import multiprocessing
import os.path
import pipes
import platform
import re
import signal
import subprocess
import sys
import gyp
import gyp.common
import gyp.msvs_emulation
import gyp.MSVSUtil as MSVSUtil
import gyp.xcode_emulation

from gyp.common import GetEnvironFallback
import gyp.ninja_syntax as ninja_syntax

if sys.platform == 'cygwin':
  import cygpath

generator_default_variables = {
  'EXECUTABLE_PREFIX': '',
  'EXECUTABLE_SUFFIX': '',
  'STATIC_LIB_PREFIX': 'lib',
  'STATIC_LIB_SUFFIX': '.a',
  'SHARED_LIB_PREFIX': 'lib',

  # Gyp expects the following variables to be expandable by the build
  # system to the appropriate locations.  Ninja prefers paths to be
  # known at gyp time.  To resolve this, introduce special
  # variables starting with $! and $| (which begin with a $ so gyp knows it
  # should be treated specially, but is otherwise an invalid
  # ninja/shell variable) that are passed to gyp here but expanded
  # before writing out into the target .ninja files; see
  # ExpandSpecial.
  # $! is used for variables that represent a path and that can only appear at
  # the start of a string, while $| is used for variables that can appear
  # anywhere in a string.
  'INTERMEDIATE_DIR': '$!INTERMEDIATE_DIR',
  'SHARED_INTERMEDIATE_DIR': '$!PRODUCT_DIR/gen',
  'PRODUCT_DIR': '$!PRODUCT_DIR',
  'CONFIGURATION_NAME': '$|CONFIGURATION_NAME',

  # Special variables that may be used by gyp 'rule' targets.
  # We generate definitions for these variables on the fly when processing a
  # rule.
  'RULE_INPUT_ROOT': '${root}',
  'RULE_INPUT_DIRNAME': '${dirname}',
  'RULE_INPUT_PATH': '${source}',
  'RULE_INPUT_EXT': '${ext}',
  'RULE_INPUT_NAME': '${name}',
}

# Placates pylint.
generator_additional_non_configuration_keys = []
generator_additional_path_sections = []
generator_extra_sources_for_rules = []

# TODO: figure out how to not build extra host objects in the non-cross-compile
# case when this is enabled, and enable unconditionally.
generator_supports_multiple_toolsets = (
  os.environ.get('GYP_CROSSCOMPILE') or
  os.environ.get('AR_host') or
  os.environ.get('CC_host') or
  os.environ.get('CXX_host') or
  os.environ.get('AR_target') or
  os.environ.get('CC_target') or
  os.environ.get('CXX_target'))

is_linux = platform.system() == 'Linux'
is_windows = platform.system() == 'Windows'

def StripPrefix(arg, prefix):
  if arg.startswith(prefix):
    return arg[len(prefix):]
  return arg


def QuoteShellArgument(arg, flavor):
  """Quote a string such that it will be interpreted as a single argument
  by the shell."""
  # Rather than attempting to enumerate the bad shell characters, just
  # whitelist common OK ones and quote anything else.
  if re.match(r'^[a-zA-Z0-9_=.\\/-]+$', arg):
    return arg  # No quoting necessary.
  if flavor in ['win', 'xb1']:
    return gyp.msvs_emulation.QuoteForRspFile(arg)
  elif flavor in ['ps3', 'ps4'] :
    # Escape double quotes.
    return '"' + arg.replace('\"', '\\\"') + '"'
  return "'" + arg.replace("'", "'" + '"\'"' + "'")  + "'"


def Define(d, flavor):
  """Takes a preprocessor define and returns a -D parameter that's ninja- and
  shell-escaped."""
  if flavor in ['win', 'xb1']:
    # cl.exe replaces literal # characters with = in preprocesor definitions for
    # some reason. Octal-encode to work around that.
    d = d.replace('#', '\\%03o' % ord('#'))
    return '/D' + gyp.msvs_emulation.QuoteForRspFile(ninja_syntax.escape(d))

  return QuoteShellArgument(ninja_syntax.escape('-D' + d), flavor)


def InvertRelativePath(path):
  """Given a relative path like foo/bar, return the inverse relative path:
  the path from the relative path back to the origin dir.

  E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path)))
  should always produce the empty string."""

  if not path:
    return path
  # Only need to handle relative paths into subdirectories for now.
  assert '..' not in path, path
  depth = len(path.split(os.path.sep))
  return os.path.sep.join(['..'] * depth)


class Target:
  """Target represents the paths used within a single gyp target.

  Conceptually, building a single target A is a series of steps:

  1) actions/rules/copies  generates source/resources/etc.
  2) compiles              generates .o files
  3) link                  generates a binary (library/executable)
  4) bundle                merges the above in a mac bundle

  (Any of these steps can be optional.)

  From a build ordering perspective, a dependent target B could just
  depend on the last output of this series of steps.

  But some dependent commands sometimes need to reach inside the box.
  For example, when linking B it needs to get the path to the static
  library generated by A.

  This object stores those paths.  To keep things simple, member
  variables only store concrete paths to single files, while methods
  compute derived values like "the last output of the target".
  """
  def __init__(self, type):
    # Gyp type ("static_library", etc.) of this target.
    self.type = type
    # File representing whether any input dependencies necessary for
    # dependent actions have completed.
    self.preaction_stamp = None
    # File representing whether any input dependencies necessary for
    # dependent compiles have completed.
    self.precompile_stamp = None
    # File representing the completion of actions/rules/copies, if any.
    self.actions_stamp = None
    # Path to the output of the link step, if any.
    self.binary = None
    # Path to the file representing the completion of building the bundle,
    # if any.
    self.bundle = None
    # On Windows, incremental linking requires linking against all the .objs
    # that compose a .lib (rather than the .lib itself). That list is stored
    # here.
    self.component_objs = None
    # Windows/PS3 only. The import .lib is the output of a build step, but
    # because dependents only link against the lib (not both the lib and the
    # dll) we keep track of the import library here.
    # For PS3, this is the "stub" library.
    self.import_lib = None

  def Linkable(self):
    """Return true if this is a target that can be linked against."""
    return self.type in ('static_library', 'shared_library')

  def UsesToc(self, flavor):
    """Return true if the target should produce a restat rule based on a TOC
    file."""
    # For bundles, the .TOC should be produced for the binary, not for
    # FinalOutput(). But the naive approach would put the TOC file into the
    # bundle, so don't do this for bundles for now.
    if flavor in ['win', 'xb1', 'ps3', 'ps4'] or self.bundle:
      return False
    return self.type in ('shared_library', 'loadable_module')

  def PreActionInput(self, flavor):
    """Return the path, if any, that should be used as a dependency of
    any dependent action step."""
    if self.UsesToc(flavor):
      return self.FinalOutput() + '.TOC'
    return self.FinalOutput() or self.preaction_stamp

  def PreCompileInput(self):
    """Return the path, if any, that should be used as a dependency of
    any dependent compile step."""
    return self.actions_stamp or self.precompile_stamp

  def FinalOutput(self):
    """Return the last output of the target, which depends on all prior
    steps."""
    return self.bundle or self.binary or self.actions_stamp


# A small discourse on paths as used within the Ninja build:
# All files we produce (both at gyp and at build time) appear in the
# build directory (e.g. out/Debug).
#
# Paths within a given .gyp file are always relative to the directory
# containing the .gyp file.  Call these "gyp paths".  This includes
# sources as well as the starting directory a given gyp rule/action
# expects to be run from.  We call the path from the source root to
# the gyp file the "base directory" within the per-.gyp-file
# NinjaWriter code.
#
# All paths as written into the .ninja files are relative to the build
# directory.  Call these paths "ninja paths".
#
# We translate between these two notions of paths with two helper
# functions:
#
# - GypPathToNinja translates a gyp path (i.e. relative to the .gyp file)
#   into the equivalent ninja path.
#
# - GypPathToUniqueOutput translates a gyp path into a ninja path to write
#   an output file; the result can be namespaced such that it is unique
#   to the input file name as well as the output target name.

class NinjaWriter:
  def __init__(self, qualified_target, target_outputs, base_dir, build_dir,
               output_file, flavor, case_sensitive_filesystem,
               abs_build_dir=None):
    """
    base_dir: path from source root to directory containing this gyp file,
              by gyp semantics, all input paths are relative to this
    build_dir: path from source root to build output
    abs_build_dir: absolute path to the build directory
    """
    self.case_sensitive_filesystem = case_sensitive_filesystem
    self.qualified_target = qualified_target
    self.target_outputs = target_outputs
    self.base_dir = base_dir
    self.build_dir = build_dir
    self.abs_build_dir = abs_build_dir
    self.ninja = ninja_syntax.Writer(output_file)
    self.flavor = flavor
    self.path_module = os.path

    self.abs_build_dir = abs_build_dir
    self.obj_ext = '.obj' if flavor == 'win' else '.o'
    if flavor in ['win', 'ps3', 'xb1', 'ps4']:
      # See docstring of msvs_emulation.GenerateEnvironmentFiles().
      self.win_env = {}
      for arch in ('x86', 'x64'):
        self.win_env[arch] = 'environment.' + arch

    # Relative path from build output dir to base dir.
    self.build_to_base = os.path.join(InvertRelativePath(build_dir), base_dir)
    # Relative path from base dir to build dir.
    self.base_to_build = os.path.join(InvertRelativePath(base_dir), build_dir)

  def ExpandSpecial(self, path, product_dir=None):
    """Expand specials like $!PRODUCT_DIR in |path|.

    If |product_dir| is None, assumes the cwd is already the product
    dir.  Otherwise, |product_dir| is the relative path to the product
    dir.
    """

    PRODUCT_DIR = '$!PRODUCT_DIR'
    if PRODUCT_DIR in path:
      if product_dir:
        path = path.replace(PRODUCT_DIR, product_dir)
      else:
        path = path.replace(PRODUCT_DIR + '/', '')
        path = path.replace(PRODUCT_DIR + '\\', '')
        path = path.replace(PRODUCT_DIR, '.')

    INTERMEDIATE_DIR = '$!INTERMEDIATE_DIR'
    if INTERMEDIATE_DIR in path:
      int_dir = self.GypPathToUniqueOutput('gen')
      # GypPathToUniqueOutput generates a path relative to the product dir,
      # so insert product_dir in front if it is provided.
      path = path.replace(INTERMEDIATE_DIR,
                          os.path.join(product_dir or '', int_dir))

    CONFIGURATION_NAME = '$|CONFIGURATION_NAME'
    path = path.replace(CONFIGURATION_NAME, self.config_name)

    return path

  def ExpandRuleVariables(self, path, root, dirname, source, ext, name):
    if self.flavor == 'win':
      path = self.msvs_settings.ConvertVSMacros(
          path, config=self.config_name)
    path = path.replace(generator_default_variables['RULE_INPUT_ROOT'], root)
    path = path.replace(generator_default_variables['RULE_INPUT_DIRNAME'],
                        dirname)
    path = path.replace(generator_default_variables['RULE_INPUT_PATH'], source)
    path = path.replace(generator_default_variables['RULE_INPUT_EXT'], ext)
    path = path.replace(generator_default_variables['RULE_INPUT_NAME'], name)
    return path

  def GypPathCaseCorrection(self, path):
    # Ninja's depfile handling gets confused when the case of a filename
    # changes on a case-insensitive file system. To work around that, always
    # convert filenames to lowercase on such file systems. See
    # https://github.com/martine/ninja/issues/402 for details.
    if self.case_sensitive_filesystem:
      return path
    else:
      return path.lower()

  def GypPathToNinja(self, path, env=None):
    """Translate a gyp path to a ninja path, optionally expanding environment
    variable references in |path| with |env|.

    See the above discourse on path conversions."""
    if env:
      if self.flavor == 'mac':
        path = gyp.xcode_emulation.ExpandEnvVars(path, env)
      elif self.flavor in ['win', 'xb1']:
        path = gyp.msvs_emulation.ExpandMacros(path, env)
    if path.startswith('$!'):
      expanded = self.ExpandSpecial(path)
      if self.flavor == 'win':
        expanded = os.path.normpath(expanded)
      else:
        expanded = self.path_module.normpath(expanded)
      return self.GypPathCaseCorrection(expanded)
    if '$|' in path:
      path =  self.ExpandSpecial(path)
    assert '$' not in path, path

    # TODO: this needs a proper fix.
    is_absolute = path.startswith('C:') or path.startswith('c:') or path.startswith('/')
    if not is_absolute:
      path = self.path_module.normpath(os.path.join(self.build_to_base, path))

    return self.GypPathCaseCorrection(path)

  def GypPathToUniqueOutput(self, path, qualified=True):
    """Translate a gyp path to a ninja path for writing output.

    If qualified is True, qualify the resulting filename with the name
    of the target.  This is necessary when e.g. compiling the same
    path twice for two separate output targets.

    See the above discourse on path conversions."""

    path = self.ExpandSpecial(path)
    assert not path.startswith('$'), path

    # Translate the path following this scheme:
    #   Input: foo/bar.gyp, target targ, references baz/out.o
    #   Output: obj/foo/baz/targ.out.o (if qualified)
    #           obj/foo/baz/out.o (otherwise)
    #     (and obj.host instead of obj for cross-compiles)
    #
    # Why this scheme and not some other one?
    # 1) for a given input, you can compute all derived outputs by matching
    #    its path, even if the input is brought via a gyp file with '..'.
    # 2) simple files like libraries and stamps have a simple filename.

    obj = 'obj'
    if self.toolset != 'target':
      obj += '.' + self.toolset

    path_dir, path_basename = os.path.split(path)
    if qualified:
      path_basename = self.name + '.' + path_basename
    path = self.path_module.normpath(os.path.join(obj, self.base_dir, path_dir,
                                         path_basename))

    return self.GypPathCaseCorrection(path)

  def WriteCollapsedDependencies(self, name, targets):
    """Given a list of targets, return a path for a single file
    representing the result of building all the targets or None.

    Uses a stamp file if necessary."""

    assert targets == filter(None, targets), targets
    if len(targets) == 0:
      return None
    if len(targets) > 1:
      stamp = self.GypPathToUniqueOutput(name + '.stamp')
      targets = self.ninja.build(stamp, 'stamp', targets)
      self.ninja.newline()
    return targets[0]

  def WriteSpec(self, spec, config_name, generator_flags):
    """The main entry point for NinjaWriter: write the build rules for a spec.

    Returns a Target object, which represents the output paths for this spec.
    Returns None if there are no outputs (e.g. a settings-only 'none' type
    target)."""

    self.config_name = config_name
    self.name = spec['target_name']
    self.toolset = spec['toolset']
    config = spec['configurations'][config_name]
    self.target = Target(spec['type'])
    self.is_standalone_static_library = bool(
        spec.get('standalone_static_library', 0))

    self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec)
    self.xcode_settings = self.msvs_settings = None
    if self.flavor == 'mac':
      self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec)
    if (self.flavor in ['win', 'ps3', 'xb1', 'ps4']
        and is_windows):
      self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec,
                                                           generator_flags)
      arch = self.msvs_settings.GetArch(config_name)
      self.ninja.variable('arch', self.win_env[arch])

    # Compute predepends for all rules.
    # actions_depends is the dependencies this target depends on before running
    # any of its action/rule/copy steps.
    # compile_depends is the dependencies this target depends on before running
    # any of its compile steps.
    actions_depends = []
    compile_depends = []
    # TODO(evan): it is rather confusing which things are lists and which
    # are strings.  Fix these.
    if 'dependencies' in spec:
      for dep in spec['dependencies']:
        if dep in self.target_outputs:
          target = self.target_outputs[dep]
          actions_depends.append(target.PreActionInput(self.flavor))
          compile_depends.append(target.PreCompileInput())
      actions_depends = filter(None, actions_depends)
      compile_depends = filter(None, compile_depends)
      actions_depends = self.WriteCollapsedDependencies('actions_depends',
                                                        actions_depends)
      compile_depends = self.WriteCollapsedDependencies('compile_depends',
                                                        compile_depends)
      self.target.preaction_stamp = actions_depends
      self.target.precompile_stamp = compile_depends

    # Write out actions, rules, and copies.  These must happen before we
    # compile any sources, so compute a list of predependencies for sources
    # while we do it.
    extra_sources = []
    mac_bundle_depends = []
    self.target.actions_stamp = self.WriteActionsRulesCopies(
        spec, extra_sources, actions_depends, mac_bundle_depends)

    # If we have actions/rules/copies, we depend directly on those, but
    # otherwise we depend on dependent target's actions/rules/copies etc.
    # We never need to explicitly depend on previous target's link steps,
    # because no compile ever depends on them.
    compile_depends_stamp = (self.target.actions_stamp or compile_depends)

    # Write out the compilation steps, if any.
    link_deps = []
    sources = spec.get('sources', []) + extra_sources
    if sources:
      pch = None
      if self.flavor in ['win', 'xb1']:
        gyp.msvs_emulation.VerifyMissingSources(
            sources, self.abs_build_dir, generator_flags, self.GypPathToNinja)
        pch = gyp.msvs_emulation.PrecompiledHeader(
            self.msvs_settings, config_name, self.GypPathToNinja,
            self.GypPathToUniqueOutput, self.obj_ext)
      else:
        pch = gyp.xcode_emulation.MacPrefixHeader(
            self.xcode_settings, self.GypPathToNinja,
            lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))
      link_deps = self.WriteSources(
          config_name, config, sources, compile_depends_stamp, pch, spec)
      # Some actions/rules output 'sources' that are already object files.
      link_deps += [self.GypPathToNinja(f)
          for f in sources if f.endswith(self.obj_ext)]

    if self.flavor in ['win', 'xb1'] and self.target.type == 'static_library':
      self.target.component_objs = link_deps

    # Write out a link step, if needed.
    output = None
    if link_deps or self.target.actions_stamp or actions_depends:
      output = self.WriteTarget(spec, config_name, config, link_deps,
                                self.target.actions_stamp or actions_depends)
      if self.is_mac_bundle:
        mac_bundle_depends.append(output)

    # Bundle all of the above together, if needed.
    if self.is_mac_bundle:
      output = self.WriteMacBundle(spec, mac_bundle_depends)

    if not output:
      return None

    assert self.target.FinalOutput(), output
    return self.target

  def _WinIdlRule(self, source, prebuild, outputs):
    """Handle the implicit VS .idl rule for one source file. Fills |outputs|
    with files that are generated."""
    outdir, output, vars, flags = self.msvs_settings.GetIdlBuildData(
        source, self.config_name)
    outdir = self.GypPathToNinja(outdir)
    def fix_path(path, rel=None):
      path = os.path.join(outdir, path)
      dirname, basename = os.path.split(source)
      root, ext = os.path.splitext(basename)
      path = self.ExpandRuleVariables(
          path, root, dirname, source, ext, basename)
      if rel:
        path = os.path.relpath(path, rel)
      return path
    vars = [(name, fix_path(value, outdir)) for name, value in vars]
    output = [fix_path(p) for p in output]
    vars.append(('outdir', outdir))
    vars.append(('idlflags', flags))
    input = self.GypPathToNinja(source)
    self.ninja.build(output, 'idl', input,
        variables=vars, order_only=prebuild)
    outputs.extend(output)

  def WriteWinIdlFiles(self, spec, prebuild):
    """Writes rules to match MSVS's implicit idl handling."""
    assert self.flavor in ('win', 'xb1')
    if self.msvs_settings.HasExplicitIdlRules(spec):
      return []
    outputs = []
    for source in filter(lambda x: x.endswith('.idl'), spec['sources']):
      self._WinIdlRule(source, prebuild, outputs)
    return outputs

  def WriteActionsRulesCopies(self, spec, extra_sources, prebuild,
                              mac_bundle_depends):
    """Write out the Actions, Rules, and Copies steps.  Return a path
    representing the outputs of these steps."""
    outputs = []
    extra_mac_bundle_resources = []

    if 'actions' in spec:
      outputs += self.WriteActions(spec['actions'], extra_sources, prebuild,
                                   extra_mac_bundle_resources)
    if 'rules' in spec:
      outputs += self.WriteRules(spec['rules'], extra_sources, prebuild,
                                 extra_mac_bundle_resources)
    if 'copies' in spec:
      outputs += self.WriteCopies(spec['copies'], prebuild, mac_bundle_depends)

    if 'sources' in spec and self.flavor in ('win', 'xb1'):
      outputs += self.WriteWinIdlFiles(spec, prebuild)

    stamp = self.WriteCollapsedDependencies('actions_rules_copies', outputs)

    if self.is_mac_bundle:
      mac_bundle_resources = spec.get('mac_bundle_resources', []) + \
                             extra_mac_bundle_resources
      self.WriteMacBundleResources(mac_bundle_resources, mac_bundle_depends)
      self.WriteMacInfoPlist(mac_bundle_depends)

    return stamp

  def GenerateDescription(self, verb, message, fallback):
    """Generate and return a description of a build step.

    |verb| is the short summary, e.g. ACTION or RULE.
    |message| is a hand-written description, or None if not available.
    |fallback| is the gyp-level name of the step, usable as a fallback.
    """
    if self.toolset != 'target':
      verb += '(%s)' % self.toolset
    if message:
      return '%s %s' % (verb, self.ExpandSpecial(message))
    else:
      return '%s %s: %s' % (verb, self.name, fallback)

  def IsCygwinRule(self, action):
    if platform.system() == 'Linux':
      return False
    elif self.flavor == 'win':
      return self.msvs_settings.IsRuleRunUnderCygwin(action)
    elif self.flavor in ['ps3', 'xb1', 'ps4'] :
      return str(action.get('msvs_cygwin_shell', 1)) != '0'
    return False

  def WriteActions(self, actions, extra_sources, prebuild,
                   extra_mac_bundle_resources):
    # Actions cd into the base directory.
    env = self.GetSortedXcodeEnv()
    if self.flavor == 'win':
      env = self.msvs_settings.GetVSMacroEnv(
          '$!PRODUCT_DIR', config=self.config_name)
    all_outputs = []
    for action in actions:
      # First write out a rule for the action.
      name = '%s_%s' % (action['action_name'],
                        hashlib.md5(self.qualified_target).hexdigest())
      description = self.GenerateDescription('ACTION',
                                             action.get('message', None),
                                             name)
      is_cygwin = self.IsCygwinRule(action)
      args = action['action']
      rule_name, _ = self.WriteNewNinjaRule(name, args, description,
                                            is_cygwin, env=env)

      inputs = [self.GypPathToNinja(i, env) for i in action['inputs']]
      if int(action.get('process_outputs_as_sources', False)):
        extra_sources += action['outputs']
      if int(action.get('process_outputs_as_mac_bundle_resources', False)):
        extra_mac_bundle_resources += action['outputs']
      outputs = [self.GypPathToNinja(o, env) for o in action['outputs']]

      # Then write out an edge using the rule.
      self.ninja.build(outputs, rule_name, inputs,
                       order_only=prebuild)
      all_outputs += outputs

      self.ninja.newline()

    return all_outputs

  def WriteRules(self, rules, extra_sources, prebuild,
                 extra_mac_bundle_resources):
    env = self.GetSortedXcodeEnv()
    all_outputs = []
    for rule in rules:
      # First write out a rule for the rule action.
      name = '%s_%s' % (rule['rule_name'],
                        hashlib.md5(self.qualified_target).hexdigest())
      # Skip a rule with no action and no inputs.
      if 'action' not in rule and not rule.get('rule_sources', []):
        continue
      args = rule['action']
      description = self.GenerateDescription(
          'RULE',
          rule.get('message', None),
          ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name)
      is_cygwin = self.IsCygwinRule(rule)
      rule_name, args = self.WriteNewNinjaRule(
          name, args, description, is_cygwin, env=env)

      # TODO: if the command references the outputs directly, we should
      # simplify it to just use $out.

      # Rules can potentially make use of some special variables which
      # must vary per source file.
      # Compute the list of variables we'll need to provide.
      special_locals = ('source', 'root', 'dirname', 'ext', 'name')
      needed_variables = set(['source'])
      for argument in args:
        for var in special_locals:
          if ('${%s}' % var) in argument:
            needed_variables.add(var)

      def cygwin_munge(path):
        if is_cygwin:
          return path.replace('\\', '/')
        return path

      # For each source file, write an edge that generates all the outputs.
      for source in rule.get('rule_sources', []):
        dirname, basename = os.path.split(source)
        root, ext = os.path.splitext(basename)

        # Gather the list of inputs and outputs, expanding $vars if possible.
        outputs = [self.ExpandRuleVariables(o, root, dirname,
                                            source, ext, basename)
                   for o in rule['outputs']]
        inputs = [self.ExpandRuleVariables(i, root, dirname,
                                           source, ext, basename)
                  for i in rule.get('inputs', [])]

        if int(rule.get('process_outputs_as_sources', False)):
          extra_sources += outputs
        if int(rule.get('process_outputs_as_mac_bundle_resources', False)):
          extra_mac_bundle_resources += outputs

        extra_bindings = []
        for var in needed_variables:
          if var == 'root':
            extra_bindings.append(('root', cygwin_munge(root)))
          elif var == 'dirname':
            extra_bindings.append(('dirname', cygwin_munge(dirname)))
          elif var == 'source':
            # '$source' is a parameter to the rule action, which means
            # it shouldn't be converted to a Ninja path.  But we don't
            # want $!PRODUCT_DIR in there either.
            source_expanded = self.ExpandSpecial(source, self.base_to_build)
            extra_bindings.append(('source', cygwin_munge(source_expanded)))
          elif var == 'ext':
            extra_bindings.append(('ext', ext))
          elif var == 'name':
            extra_bindings.append(('name', cygwin_munge(basename)))
          else:
            assert var == None, repr(var)

        inputs = [self.GypPathToNinja(i, env) for i in inputs]
        outputs = [self.GypPathToNinja(o, env) for o in outputs]
        extra_bindings.append(('unique_name',
            hashlib.md5(outputs[0]).hexdigest()))
        self.ninja.build(outputs, rule_name, self.GypPathToNinja(source),
                         implicit=inputs,
                         order_only=prebuild,
                         variables=extra_bindings)

        all_outputs.extend(outputs)

    return all_outputs

  def WriteCopy(self, src, dst, prebuild, env, mac_bundle_depends):
    dst = self.GypPathToNinja(dst, env)
    # Renormalize with the separator character of the os on which ninja will run
    dst = self.path_module.normpath(dst)

    output = self.ninja.build(dst, 'copy', src, order_only=prebuild)
    if self.is_mac_bundle:
      # gyp has mac_bundle_resources to copy things into a bundle's
      # Resources folder, but there's no built-in way to copy files to other
      # places in the bundle. Hence, some targets use copies for this. Check
      # if this file is copied into the current bundle, and if so add it to
      # the bundle depends so that dependent targets get rebuilt if the copy
      # input changes.
      if dst.startswith(self.xcode_settings.GetBundleContentsFolderPath()):
        mac_bundle_depends.append(dst)
    return output

  def WriteCopies(self, copies, prebuild, mac_bundle_depends):
    outputs = []
    env = self.GetSortedXcodeEnv()
    for copy in copies:
      for path in copy['files']:
        # Normalize the path so trailing slashes don't confuse us.
        path = os.path.normpath(path)
        destination = copy['destination']
        basename = os.path.split(path)[1]

        # call GypPathToNinja() to resolve any special GYP $ tokens in src.
        # And figure out where this directory actually is on disk.
        ninja_path = self.GypPathToNinja(path)
        joined_path = os.path.join(self.abs_build_dir, ninja_path)
        joined_path = os.path.normpath(joined_path)

        # If src is a directory, expand it recursively,
        # so we have a build rule for every file.
        if os.path.isdir(joined_path):
          for root, dirs, files in os.walk(joined_path):
            rel_root = os.path.relpath(root, self.abs_build_dir)

            for f in files:
              src = self.GypPathToNinja(os.path.join(rel_root, f), env)
              common_prefix = os.path.commonprefix([joined_path, root])
              subdir = root[len(common_prefix)+1:]

              dst = os.path.join(destination, basename, subdir, f)
              outputs += self.WriteCopy(src, dst,
                prebuild, env, mac_bundle_depends)
        else:
          src = self.GypPathToNinja(path, env)
          dst = os.path.join(destination, basename)
          outputs += self.WriteCopy(src, dst,
            prebuild, env, mac_bundle_depends)

    return outputs

  def WriteMacBundleResources(self, resources, bundle_depends):
    """Writes ninja edges for 'mac_bundle_resources'."""
    for output, res in gyp.xcode_emulation.GetMacBundleResources(
        self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
        self.xcode_settings, map(self.GypPathToNinja, resources)):
      self.ninja.build(output, 'mac_tool', res,
                       variables=[('mactool_cmd', 'copy-bundle-resource')])
      bundle_depends.append(output)

  def WriteMacInfoPlist(self, bundle_depends):
    """Write build rules for bundle Info.plist files."""
    info_plist, out, defines, extra_env = gyp.xcode_emulation.GetMacInfoPlist(
        self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
        self.xcode_settings, self.GypPathToNinja)
    if not info_plist:
      return
    if defines:
      # Create an intermediate file to store preprocessed results.
      intermediate_plist = self.GypPathToUniqueOutput(
          os.path.basename(info_plist))
      defines = ' '.join([Define(d, self.flavor) for d in defines])
      info_plist = self.ninja.build(intermediate_plist, 'infoplist', info_plist,
                                    variables=[('defines',defines)])

    env = self.GetSortedXcodeEnv(additional_settings=extra_env)
    env = self.ComputeExportEnvString(env)

    self.ninja.build(out, 'mac_tool', info_plist,
                     variables=[('mactool_cmd', 'copy-info-plist'),
                                ('env', env)])
    bundle_depends.append(out)

  def WriteSources(self, config_name, config, sources, predepends,
                   precompiled_header, spec):
    """Write build rules to compile all of |sources|."""
    if self.toolset == 'host':
      self.ninja.variable('ar', '$ar_host')
      self.ninja.variable('cc', '$cc_host')
      self.ninja.variable('cxx', '$cxx_host')
      self.ninja.variable('ld', '$ld_host')

    extra_defines = []
    if self.flavor == 'mac':
      cflags = self.xcode_settings.GetCflags(config_name)
      cflags_c = self.xcode_settings.GetCflagsC(config_name)
      cflags_cc = self.xcode_settings.GetCflagsCC(config_name)
      cflags_objc = ['$cflags_c'] + \
                    self.xcode_settings.GetCflagsObjC(config_name)
      cflags_objcc = ['$cflags_cc'] + \
                     self.xcode_settings.GetCflagsObjCC(config_name)
    elif self.flavor in ['win', 'xb1']:
      cflags = self.msvs_settings.GetCflags(config_name)
      cflags_c = self.msvs_settings.GetCflagsC(config_name)
      cflags_cc = self.msvs_settings.GetCflagsCC(config_name)
      extra_defines = self.msvs_settings.GetComputedDefines(config_name)
      obj = 'obj'
      if self.toolset != 'target':
        obj += '.' + self.toolset
      pdbpath = os.path.normpath(os.path.join(obj, self.base_dir,
                                              self.name + '.pdb'))
      self.WriteVariableList('pdbname', [pdbpath])
      self.WriteVariableList('pchprefix', [self.name])
    else:
      cflags = config.get('cflags', [])
      cflags_c = config.get('cflags_c', [])
      cflags_cc = config.get('cflags_cc', [])

    cflags_host = config.get('cflags_host', cflags)
    cflags_c_host = config.get('cflags_c_host', cflags_c)
    cflags_cc_host = config.get('cflags_cc_host', cflags_cc)

    defines = config.get('defines', []) + extra_defines
    self.WriteVariableList('defines', [Define(d, self.flavor) for d in defines])
    if self.flavor in ['win', 'xb1']:
      self.WriteVariableList('rcflags',
          [QuoteShellArgument(self.ExpandSpecial(f), self.flavor)
           for f in self.msvs_settings.GetRcflags(config_name,
                                                  self.GypPathToNinja)])

    include_dirs = config.get('include_dirs', [])
    include_dirs += config.get('include_dirs_' + self.toolset, [])

    if self.flavor in ['win', 'xb1']:
      include_dirs = self.msvs_settings.AdjustIncludeDirs(include_dirs,
                                                          config_name)
      self.WriteVariableList('includes',
        ['/I' + gyp.msvs_emulation.QuoteForRspFile(self.GypPathToNinja(i))
         for i in include_dirs])
    else:
      self.WriteVariableList('includes',
          [QuoteShellArgument('-I' + self.GypPathToNinja(i), self.flavor)
           for i in include_dirs])

    pch_commands = precompiled_header.GetPchBuildCommands()
    if self.flavor == 'mac':
      self.WriteVariableList('cflags_pch_c',
                             [precompiled_header.GetInclude('c')])
      self.WriteVariableList('cflags_pch_cc',
                             [precompiled_header.GetInclude('cc')])
      self.WriteVariableList('cflags_pch_objc',
                             [precompiled_header.GetInclude('m')])
      self.WriteVariableList('cflags_pch_objcc',
                             [precompiled_header.GetInclude('mm')])

    self.WriteVariableList('cflags', map(self.ExpandSpecial, cflags))
    self.WriteVariableList('cflags_c', map(self.ExpandSpecial, cflags_c))
    self.WriteVariableList('cflags_cc', map(self.ExpandSpecial, cflags_cc))

    self.WriteVariableList('cflags_host', map(self.ExpandSpecial, cflags_host))
    self.WriteVariableList('cflags_c_host', map(self.ExpandSpecial, cflags_c_host))
    self.WriteVariableList('cflags_cc_host', map(self.ExpandSpecial, cflags_cc_host))

    if self.flavor == 'mac':
      self.WriteVariableList('cflags_objc', map(self.ExpandSpecial,
                                                cflags_objc))
      self.WriteVariableList('cflags_objcc', map(self.ExpandSpecial,
                                                 cflags_objcc))
    self.ninja.newline()
    outputs = []
    for source in sources:
      filename, ext = os.path.splitext(source)
      ext = ext[1:]
      obj_ext = self.obj_ext
      if ext in ('cc', 'cpp', 'cxx'):
        command = 'cxx'
      elif ext == 'c' or (ext == 'S' and self.flavor != 'win'):
        command = 'cc'
      elif ext == 's' and self.flavor != 'win':  # Doesn't generate .o.d files.
        command = 'cc_s'
      elif (self.flavor == 'win' and ext == 'asm' and
            self.msvs_settings.GetArch(config_name) == 'x86' and
            not self.msvs_settings.HasExplicitAsmRules(spec)):
        # Asm files only get auto assembled for x86 (not x64).
        command = 'asm'
        # Add the _asm suffix as msvs is capable of handling .cc and
        # .asm files of the same name without collision.
        obj_ext = '_asm.obj'
      elif self.flavor == 'mac' and ext == 'm':
        command = 'objc'
      elif self.flavor == 'mac' and ext == 'mm':
        command = 'objcxx'
      elif self.flavor in ['win', 'xb1'] and ext == 'rc':
        command = 'rc'
        obj_ext = '.res'
      else:
        # Ignore unhandled extensions.
        continue
      if self.toolset != 'target':
        command += '_' + self.toolset

      input = self.GypPathToNinja(source)
      output = self.GypPathToUniqueOutput(filename + obj_ext)
      implicit = precompiled_header.GetObjDependencies([input], [output])
      variables = []
      if self.flavor in ['win', 'xb1']:
        variables, output, implicit = precompiled_header.GetFlagsModifications(
            input, output, implicit, command, cflags_c, cflags_cc,
            self.ExpandSpecial)
      self.ninja.build(output, command, input,
                       implicit=[gch for _, _, gch in implicit],
                       order_only=predepends, variables=variables)
      outputs.append(output)

    self.WritePchTargets(pch_commands)

    self.ninja.newline()
    return outputs

  def WritePchTargets(self, pch_commands):
    """Writes ninja rules to compile prefix headers."""
    if not pch_commands:
      return

    for gch, lang_flag, lang, input in pch_commands:
      var_name = {
        'c': 'cflags_pch_c',
        'cc': 'cflags_pch_cc',
        'm': 'cflags_pch_objc',
        'mm': 'cflags_pch_objcc',
      }[lang]

      map = { 'c': 'cc', 'cc': 'cxx', 'm': 'objc', 'mm': 'objcxx', }
      cmd = map.get(lang)
      self.ninja.build(gch, cmd, input, variables=[(var_name, lang_flag)])

  def WriteLink(self, spec, config_name, config, link_deps):
    """Write out a link step. Fills out target.binary. """

    command = {
      'executable':      'link',
      'loadable_module': 'solink_module',
      'shared_library':  'solink',
    }[spec['type']]

    implicit_deps = set()
    order_only_deps = set()
    solibs = set()

    if 'dependencies' in spec:
      # Two kinds of dependencies:
      # - Linkable dependencies (like a .a or a .so): add them to the link line.
      # - Non-linkable dependencies (like a rule that generates a file
      #   and writes a stamp file): add them to implicit_deps or order_only_deps
      extra_link_deps = []
      for dep in spec['dependencies']:
        target = self.target_outputs.get(dep)
        if not target:
          continue
        linkable = target.Linkable()
        if linkable:
          if (self.flavor in ['win', 'xb1'] and target.component_objs and
              self.msvs_settings.IsUseLibraryDependencyInputs(config_name)):
            extra_link_deps.extend(target.component_objs)
          elif (self.flavor in ['win', 'xb1', 'ps3'] and
                target.import_lib):
            extra_link_deps.append(target.import_lib)
          elif target.UsesToc(self.flavor):
            solibs.add(target.binary)
            implicit_deps.add(target.binary + '.TOC')
          else:
            extra_link_deps.append(target.binary)

        final_output = target.FinalOutput()
        if not linkable or final_output != target.binary:
          order_only_deps.add(final_output)

      # dedup the extra link deps while preserving order
      seen = set()
      extra_link_deps = [ x for x in extra_link_deps if x not in seen and not seen.add(x) ]

      link_deps.extend(extra_link_deps)

    extra_bindings = []
    if self.is_mac_bundle:
      output = self.ComputeMacBundleBinaryOutput()
    else:
      output = self.ComputeOutput(spec)
      extra_bindings.append(('postbuilds',
                             self.GetPostbuildCommand(spec, output, output)))

    if self.flavor == 'mac':
      ldflags = self.xcode_settings.GetLdflags(config_name,
          self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
          self.GypPathToNinja)
    elif self.flavor in ['win', 'xb1']:
      libflags = self.msvs_settings.GetLibFlags(config_name,
                                                self.GypPathToNinja)
      self.WriteVariableList(
          'libflags', gyp.common.uniquer(map(self.ExpandSpecial, libflags)))
      is_executable = spec['type'] == 'executable'
      manifest_name = self.GypPathToUniqueOutput(
          self.ComputeOutputFileName(spec))
      ldflags, manifest_files = self.msvs_settings.GetLdflags(config_name,
          self.GypPathToNinja, self.ExpandSpecial, manifest_name, is_executable)
      self.WriteVariableList('manifests', manifest_files)
    else:
      ldflags = config.get('ldflags', [])
      ldflags_host = config.get('ldflags_host', ldflags)

    self.WriteVariableList('ldflags',
                           gyp.common.uniquer(map(self.ExpandSpecial,
                                                  ldflags)))
    if ('ldflags_host' in locals()):
      self.WriteVariableList('ldflags_host',
                             gyp.common.uniquer(map(self.ExpandSpecial,
                                                    ldflags_host)))

    if self.toolset == 'host':
      libs = spec.get('libraries_host', [])
      libs.extend(config.get('libraries_host', []))
    else:
      libs = spec.get('libraries', [])
      libs.extend(config.get('libraries', []))

    libraries = gyp.common.uniquer(map(self.ExpandSpecial, libs))

    if self.flavor == 'mac':
      libraries = self.xcode_settings.AdjustLibraries(libraries)
    elif self.flavor in ['win', 'xb1']:
      libraries = self.msvs_settings.AdjustLibraries(libraries)
    self.WriteVariableList('libs', libraries)

    self.target.binary = output

    if command in ('solink', 'solink_module'):
      extra_bindings.append(('soname', os.path.split(output)[1]))
      extra_bindings.append(('lib',
                            gyp.common.EncodePOSIXShellArgument(output)))
      if self.flavor in ['win', 'xb1']:
        extra_bindings.append(('dll', output))
        if '/NOENTRY' not in ldflags:
          self.target.import_lib = output + '.lib'
          extra_bindings.append(('implibflag',
                                 '/IMPLIB:%s' % self.target.import_lib))
          output = [output, self.target.import_lib]
      elif self.flavor == 'ps3':
        # Tell Ninja we'll be generating a .sprx and a stub library.
        # Bind the variable '$prx' to our output binary so we can
        # refer to it in the linker rules.
        prx_output = output
        prx_output_base, prx_output_ext = os.path.splitext(prx_output)
        assert prx_output_ext == '.sprx'

        extra_bindings.append(('prx', output))
        # TODO: Figure out how to suppress the "removal" warning
        # generated from the prx generator when we remove a function.
        # For now, we'll just delete the 'verlog.txt' file before linking.
        # Bind it here so we can refer to it as $verlog in the PS3 solink rule.
        verlog = output.replace(prx_output_ext, '_verlog.txt')
        extra_bindings.append(('verlog', verlog))
        self.target.import_lib = output.replace(prx_output_ext, '_stub.a')
        output = [prx_output, self.target.import_lib]

        # For PRXs, we need to convert any c++ exports into C. This is done
        # with an "export pickup" step that runs over the object files
        # and produces a new .c file. That .c file should be compiled and linked
        # into the PRX.
        gen_files_dir = os.path.join(self.ExpandSpecial(
            generator_default_variables['SHARED_INTERMEDIATE_DIR']), 'prx')

        export_pickup_output = os.path.join(
            gen_files_dir, os.path.basename(prx_output_base) + '.prx_export.c')
        prx_export_obj_file = export_pickup_output[:-2] + '.o'
        self.ninja.build(export_pickup_output,
                         'prx_export_pickup',
                         link_deps,
                         implicit=list(implicit_deps),
                         order_only=list(order_only_deps))

        self.ninja.build(prx_export_obj_file, 'cc', export_pickup_output)
        link_deps.append(prx_export_obj_file)

      else:
        output = [output, output + '.TOC']

    if len(solibs):
      extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs)))

    if self.toolset != 'target':
      command += '_' + self.toolset

    self.ninja.build(output, command, link_deps,
                     implicit=list(implicit_deps),
                     order_only=list(order_only_deps),
                     variables=extra_bindings)

  def WriteTarget(self, spec, config_name, config, link_deps, compile_deps):
    if spec['type'] == 'none':
      # TODO(evan): don't call this function for 'none' target types, as
      # it doesn't do anything, and we fake out a 'binary' with a stamp file.
      self.target.binary = compile_deps
    elif spec['type'] == 'static_library':
      self.target.binary = self.ComputeOutput(spec)
      variables = []
      if self.flavor in ('win', 'xb1'):
        libflags = self.msvs_settings.GetLibFlags(config_name,
                                                  self.GypPathToNinja)
        variables.append(('libflags', ' '.join(libflags)))
      postbuild = self.GetPostbuildCommand(
          spec, self.target.binary, self.target.binary)
      if postbuild:
        variables.append(('postbuilds', postbuild))
      if self.xcode_settings:
        variables.append(('libtool_flags',
                          self.xcode_settings.GetLibtoolflags(config_name)))
      if (self.flavor not in ('mac', 'win', 'xb1') and not
          self.is_standalone_static_library):
        command = 'alink_thin'
      else:
        command = 'alink'
      if self.toolset != 'target':
        command += '_' + self.toolset
      self.ninja.build(self.target.binary, command, link_deps,
                       order_only=compile_deps, variables=variables)
    else:
      self.WriteLink(spec, config_name, config, link_deps)
    return self.target.binary

  def WriteMacBundle(self, spec, mac_bundle_depends):
    assert self.is_mac_bundle
    package_framework = spec['type'] in ('shared_library', 'loadable_module')
    output = self.ComputeMacBundleOutput()
    postbuild = self.GetPostbuildCommand(spec, output, self.target.binary,
                                         is_command_start=not package_framework)
    variables = []
    if postbuild:
      variables.append(('postbuilds', postbuild))
    if package_framework:
      variables.append(('version', self.xcode_settings.GetFrameworkVersion()))
      self.ninja.build(output, 'package_framework', mac_bundle_depends,
                       variables=variables)
    else:
      self.ninja.build(output, 'stamp', mac_bundle_depends,
                       variables=variables)
    self.target.bundle = output
    return output

  def GetSortedXcodeEnv(self, additional_settings=None):
    """Returns the variables Xcode would set for build steps."""
    assert self.abs_build_dir
    abs_build_dir = self.abs_build_dir
    return gyp.xcode_emulation.GetSortedXcodeEnv(
        self.xcode_settings, abs_build_dir,
        os.path.join(abs_build_dir, self.build_to_base), self.config_name,
        additional_settings)

  def GetSortedXcodePostbuildEnv(self):
    """Returns the variables Xcode would set for postbuild steps."""
    postbuild_settings = {}
    # CHROMIUM_STRIP_SAVE_FILE is a chromium-specific hack.
    # TODO(thakis): It would be nice to have some general mechanism instead.
    strip_save_file = self.xcode_settings.GetPerTargetSetting(
        'CHROMIUM_STRIP_SAVE_FILE')
    if strip_save_file:
      postbuild_settings['CHROMIUM_STRIP_SAVE_FILE'] = strip_save_file
    return self.GetSortedXcodeEnv(additional_settings=postbuild_settings)

  def GetPostbuildCommand(self, spec, output, output_binary,
                          is_command_start=False):
    """Returns a shell command that runs all the postbuilds, and removes
    |output| if any of them fails. If |is_command_start| is False, then the
    returned string will start with ' && '."""
    if not self.xcode_settings or spec['type'] == 'none' or not output:
      return ''
    output = QuoteShellArgument(output, self.flavor)
    target_postbuilds = self.xcode_settings.GetTargetPostbuilds(
        self.config_name,
        os.path.normpath(os.path.join(self.base_to_build, output)),
        QuoteShellArgument(
            os.path.normpath(os.path.join(self.base_to_build, output_binary)),
            self.flavor),
        quiet=True)
    postbuilds = gyp.xcode_emulation.GetSpecPostbuildCommands(spec, quiet=True)
    postbuilds = target_postbuilds + postbuilds
    if not postbuilds:
      return ''
    # Postbuilds expect to be run in the gyp file's directory, so insert an
    # implicit postbuild to cd to there.
    postbuilds.insert(0, gyp.common.EncodePOSIXShellList(
        ['cd', self.build_to_base]))
    env = self.ComputeExportEnvString(self.GetSortedXcodePostbuildEnv())
    # G will be non-null if any postbuild fails. Run all postbuilds in a
    # subshell.
    commands = env + ' (F=0; ' + \
        ' '.join([ninja_syntax.escape(command) + ' || F=$$?;'
                                 for command in postbuilds])
    command_string = (commands + ' exit $$F); G=$$?; '
                      # Remove the final output if any postbuild failed.
                      '((exit $$G) || rm -rf %s) ' % output + '&& exit $$G)')
    if is_command_start:
      return '(' + command_string + ' && '
    else:
      return '$ && (' + command_string

  def ComputeExportEnvString(self, env):
    """Given an environment, returns a string looking like
        'export FOO=foo; export BAR="${FOO} bar;'
    that exports |env| to the shell."""
    export_str = []
    for k, v in env:
      export_str.append('export %s=%s;' %
          (k, ninja_syntax.escape(gyp.common.EncodePOSIXShellArgument(v))))
    return ' '.join(export_str)

  def ComputeMacBundleOutput(self):
    """Return the 'output' (full output path) to a bundle output directory."""
    assert self.is_mac_bundle
    path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR'])
    return os.path.join(path, self.xcode_settings.GetWrapperName())

  def ComputeMacBundleBinaryOutput(self):
    """Return the 'output' (full output path) to the binary in a bundle."""
    assert self.is_mac_bundle
    path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR'])
    return os.path.join(path, self.xcode_settings.GetExecutablePath())

  def ComputeOutputFileName(self, spec, type=None):
    """Compute the filename of the final output for the current target."""
    if not type:
      type = spec['type']

    default_variables = copy.copy(generator_default_variables)
    CalculateVariables(default_variables, {'flavor': self.flavor})

    # Compute filename prefix: the product prefix, or a default for
    # the product type.
    DEFAULT_PREFIX = {
      'loadable_module': default_variables['SHARED_LIB_PREFIX'],
      'shared_library': default_variables['SHARED_LIB_PREFIX'],
      'static_library': default_variables['STATIC_LIB_PREFIX'],
      'executable': default_variables['EXECUTABLE_PREFIX'],
      }
    prefix = spec.get('product_prefix', DEFAULT_PREFIX.get(type, ''))

    # Compute filename extension: the product extension, or a default
    # for the product type.
    DEFAULT_EXTENSION = {
        'loadable_module': default_variables['SHARED_LIB_SUFFIX'],
        'shared_library': default_variables['SHARED_LIB_SUFFIX'],
        'static_library': default_variables['STATIC_LIB_SUFFIX'],
        'executable': default_variables['EXECUTABLE_SUFFIX'],
      }
    extension = spec.get('product_extension')
    if extension:
      extension = '.' + extension
    elif self.toolset == 'host':
      if is_linux:
        extension = ''
      elif is_windows:
        extension = '.exe'
    else:
      extension = DEFAULT_EXTENSION.get(type, '')

    if 'product_name' in spec:
      # If we were given an explicit name, use that.
      target = spec['product_name']
    else:
      # Otherwise, derive a name from the target name.
      target = spec['target_name']
      if prefix == 'lib':
        # Snip out an extra 'lib' from libs if appropriate.
        target = StripPrefix(target, 'lib')

    if type in ('static_library', 'loadable_module', 'shared_library',
                        'executable'):
      return '%s%s%s' % (prefix, target, extension)
    elif type == 'none':
      return '%s.stamp' % target
    else:
      raise Exception('Unhandled output type %s' % type)

  def ComputeOutput(self, spec, type=None):
    """Compute the path for the final output of the spec."""
    assert not self.is_mac_bundle or type

    if not type:
      type = spec['type']

    if self.flavor == 'win':
      override = self.msvs_settings.GetOutputName(self.config_name,
                                                  self.ExpandSpecial)
      if override:
        return override

    if self.flavor == 'mac' and type in (
        'static_library', 'executable', 'shared_library', 'loadable_module'):
      filename = self.xcode_settings.GetExecutablePath()
    else:
      filename = self.ComputeOutputFileName(spec, type)

    if 'product_dir' in spec:
      path = os.path.join(spec['product_dir'], filename)
      return self.ExpandSpecial(path)

    # Some products go into the output root, libraries go into shared library
    # dir, and everything else goes into the normal place.
    type_in_output_root = ['executable', 'loadable_module']
    if self.flavor == 'mac' and self.toolset == 'target':
      type_in_output_root += ['shared_library', 'static_library']
    elif self.flavor in ['win', 'ps3'] and self.toolset == 'target':
      type_in_output_root += ['shared_library']

    if type in type_in_output_root or self.is_standalone_static_library:
      return filename
    elif type == 'shared_library':
      libdir = 'lib'
      if self.toolset != 'target':
        libdir = os.path.join('lib', '%s' % self.toolset)
      return os.path.join(libdir, filename)
    else:
      return self.GypPathToUniqueOutput(filename, qualified=False)

  def WriteVariableList(self, var, values):
    assert not isinstance(values, str)
    if values is None:
      values = []
    self.ninja.variable(var, ' '.join(values))

  def WriteNewNinjaRule(self, name, args, description, is_cygwin, env):
    """Write out a new ninja "rule" statement for a given command.

    Returns the name of the new rule, and a copy of |args| with variables
    expanded."""

    if self.flavor == 'win':
      args = [self.msvs_settings.ConvertVSMacros(
                  arg, self.base_to_build, config=self.config_name)
              for arg in args]
      description = self.msvs_settings.ConvertVSMacros(
          description, config=self.config_name)
    elif self.flavor == 'mac':
      # |env| is an empty list on non-mac.
      args = [gyp.xcode_emulation.ExpandEnvVars(arg, env) for arg in args]
      description = gyp.xcode_emulation.ExpandEnvVars(description, env)

    # TODO: we shouldn't need to qualify names; we do it because
    # currently the ninja rule namespace is global, but it really
    # should be scoped to the subninja.
    rule_name = self.name
    if self.toolset == 'target':
      rule_name += '.' + self.toolset
    rule_name += '.' + name
    rule_name = re.sub('[^a-zA-Z0-9_]', '_', rule_name)

    # Remove variable references, but not if they refer to the magic rule
    # variables.  This is not quite right, as it also protects these for
    # actions, not just for rules where they are valid. Good enough.
    protect = [ '${root}', '${dirname}', '${source}', '${ext}', '${name}' ]
    protect = '(?!' + '|'.join(map(re.escape, protect)) + ')'
    description = re.sub(protect + r'\$', '_', description)

    # gyp dictates that commands are run from the base directory.
    # cd into the directory before running, and adjust paths in
    # the arguments to point to the proper locations.
    rspfile = None
    rspfile_content = None
    args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args]
    if (self.flavor in ['win', 'ps3', 'xb1', 'ps4']
        and is_windows):
      rspfile = rule_name + '.$unique_name.rsp'
      # The cygwin case handles this inside the bash sub-shell.
      run_in = '' if is_cygwin else ' ' + self.build_to_base
      if is_cygwin:
        rspfile_content = self.msvs_settings.BuildCygwinBashCommandLine(
            args, self.build_to_base)
      else:
        rspfile_content = gyp.msvs_emulation.EncodeRspFileList(args)

      command = ('%s gyp-win-tool action-wrapper $arch ' % sys.executable +
                 rspfile + run_in)
    else:
      env = self.ComputeExportEnvString(env)
      command = gyp.common.EncodePOSIXShellList(args)
      command = 'cd %s; ' % self.build_to_base + env + command

    # GYP rules/actions express being no-ops by not touching their outputs.
    # Avoid executing downstream dependencies in this case by specifying
    # restat=1 to ninja.
    self.ninja.rule(rule_name, command, description, restat=True,
                    rspfile=rspfile, rspfile_content=rspfile_content)
    self.ninja.newline()

    return rule_name, args


def CalculateVariables(default_variables, params):
  """Calculate additional variables for use in the build (called by gyp)."""
  global generator_additional_non_configuration_keys
  global generator_additional_path_sections
  flavor = gyp.common.GetFlavor(params)
  if flavor == 'mac':
    default_variables.setdefault('OS', 'mac')
    default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib')
    default_variables.setdefault('SHARED_LIB_DIR',
                                 generator_default_variables['PRODUCT_DIR'])
    default_variables.setdefault('LIB_DIR',
                                 generator_default_variables['PRODUCT_DIR'])

    # Copy additional generator configuration data from Xcode, which is shared
    # by the Mac Ninja generator.
    import gyp.generator.xcode as xcode_generator
    generator_additional_non_configuration_keys = getattr(xcode_generator,
        'generator_additional_non_configuration_keys', [])
    generator_additional_path_sections = getattr(xcode_generator,
        'generator_additional_path_sections', [])
    global generator_extra_sources_for_rules
    generator_extra_sources_for_rules = getattr(xcode_generator,
        'generator_extra_sources_for_rules', [])
  elif flavor in ['win', 'xb1']:
    default_variables.setdefault('OS', 'win')
    default_variables['EXECUTABLE_SUFFIX'] = '.exe'
    default_variables['STATIC_LIB_PREFIX'] = ''
    default_variables['STATIC_LIB_SUFFIX'] = '.lib'
    default_variables['SHARED_LIB_PREFIX'] = ''
    default_variables['SHARED_LIB_SUFFIX'] = '.dll'
    generator_flags = params.get('generator_flags', {})

    # Copy additional generator configuration data from VS, which is shared
    # by the Windows Ninja generator.
    import gyp.generator.msvs as msvs_generator
    generator_additional_non_configuration_keys = getattr(msvs_generator,
        'generator_additional_non_configuration_keys', [])
    generator_additional_path_sections = getattr(msvs_generator,
        'generator_additional_path_sections', [])

    # Set a variable so conditions can be based on msvs_version.
    msvs_version = gyp.msvs_emulation.GetVSVersion(generator_flags)
    default_variables['MSVS_VERSION'] = msvs_version.ShortName()

    # To determine processor word size on Windows, in addition to checking
    # PROCESSOR_ARCHITECTURE (which reflects the word size of the current
    # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which
    # contains the actual word size of the system when running thru WOW64).
    if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or
        '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')):
      default_variables['MSVS_OS_BITS'] = 64
    else:
      default_variables['MSVS_OS_BITS'] = 32
  elif flavor == 'ps3':
    if is_windows:
      # This is required for BuildCygwinBashCommandLine() to work.
      import gyp.generator.msvs as msvs_generator
      generator_additional_non_configuration_keys = getattr(msvs_generator,
          'generator_additional_non_configuration_keys', [])
      generator_additional_path_sections = getattr(msvs_generator,
          'generator_additional_path_sections', [])

    default_variables['SHARED_LIB_PREFIX'] = ''
    default_variables['SHARED_LIB_SUFFIX'] = '.sprx'
    generator_flags = params.get('generator_flags', {})

  elif flavor == 'ps4':
    if is_windows:
      # This is required for BuildCygwinBashCommandLine() to work.
      import gyp.generator.msvs as msvs_generator
      generator_additional_non_configuration_keys = getattr(msvs_generator,
          'generator_additional_non_configuration_keys', [])
      generator_additional_path_sections = getattr(msvs_generator,
          'generator_additional_path_sections', [])

    default_variables['EXECUTABLE_SUFFIX'] = '.elf'
    default_variables['SHARED_LIB_PREFIX'] = 'lib'
    default_variables['SHARED_LIB_SUFFIX'] = '.so'

    # Copy additional generator configuration data from VS, which is shared
    # by the Windows Ninja generator.
    import gyp.generator.msvs as msvs_generator
    generator_additional_non_configuration_keys = getattr(msvs_generator,
        'generator_additional_non_configuration_keys', [])
    generator_additional_path_sections = getattr(msvs_generator,
        'generator_additional_path_sections', [])
  else:
    operating_system = flavor
    if flavor == 'android':
      operating_system = 'linux'  # Keep this legacy behavior for now.
    default_variables.setdefault('OS', operating_system)
    default_variables.setdefault('SHARED_LIB_SUFFIX', '.so')
    default_variables.setdefault('SHARED_LIB_DIR',
                                 os.path.join('$!PRODUCT_DIR', 'lib'))
    default_variables.setdefault('LIB_DIR',
                                 os.path.join('$!PRODUCT_DIR', 'obj'))


def OpenOutput(path, mode='w'):
  """Open |path| for writing, creating directories if necessary."""
  try:
    os.makedirs(os.path.dirname(path))
  except OSError:
    pass
  return open(path, mode)


def GetDefaultConcurrentLinks():
  """Returns a best-guess for a number of concurrent links."""
  pool_size = int(os.getenv('GYP_LINK_CONCURRENCY', 0))
  if pool_size:
    return pool_size

  if sys.platform in ('win32', 'cygwin'):
    import ctypes

    class MEMORYSTATUSEX(ctypes.Structure):
      _fields_ = [
        ("dwLength", ctypes.c_ulong),
        ("dwMemoryLoad", ctypes.c_ulong),
        ("ullTotalPhys", ctypes.c_ulonglong),
        ("ullAvailPhys", ctypes.c_ulonglong),
        ("ullTotalPageFile", ctypes.c_ulonglong),
        ("ullAvailPageFile", ctypes.c_ulonglong),
        ("ullTotalVirtual", ctypes.c_ulonglong),
        ("ullAvailVirtual", ctypes.c_ulonglong),
        ("sullAvailExtendedVirtual", ctypes.c_ulonglong),
      ]

    stat = MEMORYSTATUSEX()
    stat.dwLength = ctypes.sizeof(stat)
    ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat))

    # VS 2015 uses 20% more working set than VS 2013 and can consume all RAM
    # on a 64 GB machine.
    mem_limit = max(1, stat.ullTotalPhys / (5 * (2 ** 30)))  # total / 5GB
    hard_cap = max(1, int(os.getenv('GYP_LINK_CONCURRENCY_MAX', 2**32)))
    return min(mem_limit, hard_cap)
  elif sys.platform.startswith('linux'):
    if os.path.exists("/proc/meminfo"):
      with open("/proc/meminfo") as meminfo:
        memtotal_re = re.compile(r'^MemTotal:\s*(\d*)\s*kB')
        for line in meminfo:
          match = memtotal_re.match(line)
          if not match:
            continue
          # Allow 6Gb per link on Linux because Gold is quite memory hungry
          return max(1, int(match.group(1)) / (6 * (2 ** 20)))
    return 1
  elif sys.platform == 'darwin':
    try:
      avail_bytes = int(subprocess.check_output(['sysctl', '-n', 'hw.memsize']))
      # A static library debug build of Chromium's unit_tests takes ~2.7GB, so
      # 4GB per ld process allows for some more bloat.
      return max(1, avail_bytes / (4 * (2 ** 30)))  # total / 4GB
    except:
      return 1
  else:
    # TODO(scottmg): Implement this for other platforms.
    return 1


def GenerateOutputForConfig(target_list, target_dicts, data, params,
                            config_name):
  options = params['options']
  flavor = gyp.common.GetFlavor(params)

  generator_flags = params.get('generator_flags', {})

  # generator_dir: relative path from pwd to where make puts build files.
  # Makes migrating from make to ninja easier, ninja doesn't put anything here.
  generator_dir = os.path.relpath(params['options'].generator_output or '.')

  # output_dir: relative path from generator_dir to the build directory.
  output_dir = generator_flags.get('output_dir', 'out')

  # build_dir: relative path from source root to our output files.
  # e.g. "out/Debug"
  build_dir = os.path.normpath(os.path.join(generator_dir,
                                            output_dir,
                                            config_name))

  toplevel_build = os.path.join(options.toplevel_dir, build_dir)

  master_ninja = ninja_syntax.Writer(
      OpenOutput(os.path.join(toplevel_build, 'build.ninja')),
      width=120)
  case_sensitive_filesystem = True

  # Put build-time support tools in out/{config_name}.
  gyp.common.CopyTool(flavor, toplevel_build)

  # Grab make settings for CC/CXX.
  # The rules are
  # - The priority from low to high is gcc/g++, the 'make_global_settings' in
  #   gyp, the environment variable.
  # - If there is no 'make_global_settings' for CC.host/CXX.host or
  #   'CC_host'/'CXX_host' enviroment variable, cc_host/cxx_host should be set
  #   to cc/cxx.
  if (flavor == 'win' or (flavor in ['ps3', 'ps4'] and is_windows)):
    cc = 'cl.exe'
    cxx = 'cl.exe'
    ld = 'link.exe'
    gyp.msvs_emulation.GenerateEnvironmentFiles(
        toplevel_build, generator_flags, OpenOutput)
    ld_host = '$ld'
  elif flavor == 'xb1':
    cc = 'cl.exe'
    cxx = 'cl.exe'
    ld = 'link.exe'
    gyp.msvs_emulation.GenerateXB1EnvironmentFiles(
        toplevel_build, generator_flags, OpenOutput)
    ld_host = '$ld'
  else:
    cc = 'gcc'
    cxx = 'g++'
    ld = '$cxx'
    ld_host = '$cxx_host'

  cc_host = None
  cxx_host = None
  cc_host_global_setting = None
  cxx_host_global_setting = None

  build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
  make_global_settings = data[build_file].get('make_global_settings', [])
  build_to_root = InvertRelativePath(build_dir)
  for key, value in make_global_settings:
    if key == 'CC':
      cc = os.path.join(build_to_root, value)
    if key == 'CXX':
      cxx = os.path.join(build_to_root, value)
    if key == 'LD':
      ld = os.path.join(build_to_root, value)
    if key == 'CC.host':
      cc_host = os.path.join(build_to_root, value)
      cc_host_global_setting = value
    if key == 'CXX.host':
      cxx_host = os.path.join(build_to_root, value)
      cxx_host_global_setting = value
    if key == 'LD.host':
      ld_host = os.path.join(build_to_root, value)

  flock = 'flock'
  if flavor == 'mac':
    flock = './gyp-mac-tool flock'
  cc = GetEnvironFallback(['CC_target', 'CC'], cc)
  master_ninja.variable('cc', cc)
  cxx = GetEnvironFallback(['CXX_target', 'CXX'], cxx)
  master_ninja.variable('cxx', cxx)
  ld = GetEnvironFallback(['LD_target', 'LD'], ld)

  if not cc_host:
    cc_host = cc
  if not cxx_host:
    cxx_host = cxx

  # gyp-win-tool wrappers have a winpython only flock implementation.
  if sys.platform == 'cygwin':
    python_exec = '$python'
  else:
    python_exec = sys.executable

  ar_flags = ''
  if flavor in ['win', 'xb1']:
    master_ninja.variable('ld', ld)
    master_ninja.variable('idl', 'midl.exe')
    master_ninja.variable('ar', 'lib.exe')
    master_ninja.variable('rc', 'rc.exe')
    master_ninja.variable('asm', 'ml.exe')
    master_ninja.variable('mt', 'mt.exe')
    master_ninja.variable('use_dep_database', '1')
  elif flavor in ['ps3', 'ps4']:
    # Require LD to be set.
    master_ninja.variable('ld', os.environ.get('LD'))
    master_ninja.variable('ar', os.environ.get('AR', 'ar'))
    if flavor =='ps3':
      master_ninja.variable('prx_export_pickup', os.environ['PRX_EXPORT_PICKUP'])
    ar_flags = os.environ.get('ARFLAGS', 'rcs')
    master_ninja.variable('arFlags', ar_flags)
    # On the PS3, when we use ps3snarl.exe with a response file, we cannot
    # pass it flags (like 'rcs'), so ARFLAGS is likely set to '' for this
    # platform.  In that case, do not append the thin archive 'T' flag
    # to the flags string.
    # Likewise for PS4, but using orbis-snarl.exe
    thin_flag_to_add = ''
    if len(ar_flags) >= 1 and ar_flags.find('T') == -1:
      thin_flag_to_add = 'T'
    master_ninja.variable('arThinFlags', ar_flags + thin_flag_to_add)

  else:
    master_ninja.variable('ld', ld)
    master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], 'ar'))
    ar_flags = os.environ.get('ARFLAGS', 'rcs')
    master_ninja.variable('arFlags', ar_flags)
    thin_flag_to_add = ''
    if ar_flags.find('T') == -1:
      thin_flag_to_add = 'T'
    master_ninja.variable('arThinFlags', ar_flags + thin_flag_to_add)
  master_ninja.variable('ar_host', GetEnvironFallback(['AR_host'], 'ar'))
  cc_host = GetEnvironFallback(['CC_host'], cc_host)
  cxx_host = GetEnvironFallback(['CXX_host'], cxx_host)
  ld_host = GetEnvironFallback(['LD_host'], ld_host)
  arflags_host = GetEnvironFallback(['ARFLAGS_host'], ar_flags)
  arthinflags_host = GetEnvironFallback(['ARTHINFLAGS_host'], arflags_host)

  # The environment variable could be used in 'make_global_settings', like
  # ['CC.host', '$(CC)'] or ['CXX.host', '$(CXX)'], transform them here.
  if '$(CC)' in cc_host and cc_host_global_setting:
    cc_host = cc_host_global_setting.replace('$(CC)', cc)
  if '$(CXX)' in cxx_host and cxx_host_global_setting:
    cxx_host = cxx_host_global_setting.replace('$(CXX)', cxx)
  master_ninja.variable('cc_host', cc_host)
  master_ninja.variable('cxx_host', cxx_host)
  master_ninja.variable('arFlags_host', arflags_host)
  master_ninja.variable('arThinFlags_host', arthinflags_host)
  master_ninja.variable('ld_host', ld_host)

  if sys.platform == 'cygwin':
    python_path = cygpath.to_nt('/cygdrive/c/python_27_amd64/files/python.exe')
  else:
    python_path = 'python'
  master_ninja.variable('python', python_path)
  master_ninja.newline()

  master_ninja.pool('link_pool', depth=GetDefaultConcurrentLinks())
  master_ninja.newline()

  if flavor not in ['win', 'xb1']:
    if flavor in ['ps3', 'ps4'] :
      # uca := Unnamed Console A
      dep_format = 'snc' if (flavor == 'ps3') else 'uca'
      master_ninja.rule(
        'cc',
        description='CC $out',
        command=('$cc @$out.rsp'),
        rspfile='$out.rsp',
        rspfile_content=('-c $in -o $out '
                         '-MMD $defines $includes $cflags $cflags_c '
                        '$cflags_pch_c'),
        depfile='$out_no_ext.d',
        deps='gcc',
        depformat=dep_format)
      master_ninja.rule(
        'cxx',
        description='CXX $out',
        command=('$cxx @$out.rsp'),
        rspfile='$out.rsp',
        rspfile_content=('-c $in -o $out '
                         '-MMD $defines $includes $cflags $cflags_cc '
                        '$cflags_pch_cc'),
        depfile='$out_no_ext.d',
        deps='gcc',
        depformat=dep_format)
    else:
      master_ninja.rule(
        'cc',
        description='CC $out',
        command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c '
                '$cflags_pch_c -c $in -o $out'),
        deps='gcc',
        depfile='$out.d')
      master_ninja.rule(
        'cc_s',
        description='CC $out',
        command=('$cc $defines $includes $cflags $cflags_c '
                '$cflags_pch_c -c $in -o $out'))
      master_ninja.rule(
        'cxx',
        description='CXX $out',
        command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc '
                '$cflags_pch_cc -c $in -o $out'),
        deps='gcc',
        depfile='$out.d')

  else:
    cc_command = ('$cc /nologo /showIncludes /FC '
                  '@$out.rsp /c $in /Fo$out /Fd$pdbname ')
    cxx_command = ('$cxx /nologo /showIncludes /FC '
                   '@$out.rsp /c $in /Fo$out /Fd$pdbname ')
    master_ninja.rule(
      'cc',
      description='CC $out',
      command=cc_command,
      deps='msvc',
      rspfile='$out.rsp',
      rspfile_content='$defines $includes $cflags $cflags_c')
    master_ninja.rule(
      'cxx',
      description='CXX $out',
      command=cxx_command,
      deps='msvc',
      rspfile='$out.rsp',
      rspfile_content='$defines $includes $cflags $cflags_cc')

    master_ninja.rule(
      'idl',
      description='IDL $in',
      command=('%s gyp-win-tool midl-wrapper $arch $outdir '
               '$tlb $h $dlldata $iid $proxy $in '
               '$idlflags' % python_exec))
    master_ninja.rule(
      'rc',
      description='RC $in',
      # Note: $in must be last otherwise rc.exe complains.
      command=('%s gyp-win-tool rc-wrapper '
               '$arch $rc $defines $includes $rcflags /fo$out $in' %
               python_exec))
    master_ninja.rule(
      'asm',
      description='ASM $in',
      command=('%s gyp-win-tool asm-wrapper '
               '$arch $asm $defines $includes /c /Fo $out $in' %
               python_exec))

  if flavor not in ['mac', 'win', 'xb1']:
    alink_command = 'rm -f $out && $ar $arFlags $out @$out.rsp'
    # TODO: Use rcsT on Linux only.
    alink_thin_command = 'rm -f $out && $ar $arThinFlags $out @$out.rsp'

    ld_cmd = '$ld'

    if flavor in ['ps3', 'ps4'] and is_windows:
      alink_command = 'cmd.exe /c ' + alink_command
      alink_thin_command = 'cmd.exe /c ' + alink_thin_command
      ld_cmd = '%s gyp-win-tool link-wrapper $arch $ld' % python_exec

    master_ninja.rule(
      'alink',
      description='AR $out',
      command=alink_command,
      rspfile='$out.rsp',
      rspfile_content='$in_newline')
    master_ninja.rule(
      'alink_thin',
      description='AR $out',
      command=alink_thin_command,
      rspfile='$out.rsp',
      rspfile_content='$in_newline')

    if flavor == 'ps3':
      # TODO: Can we suppress the warnings from verlog.txt rather than
      # rm'ing it?
      ld_cmd = 'rm -f $verlog && ' + ld_cmd
      if is_windows:
        ld_cmd = 'cmd.exe /c ' + ld_cmd

      prx_flags = '--oformat=fsprx --prx-with-runtime --zgenprx -zgenstub'
      master_ninja.rule(
        'solink',
        description='LINK(PRX) $lib',
        restat=True,
        command=ld_cmd + ' @$prx.rsp',
        rspfile='$prx.rsp',
        rspfile_content='$ldflags %s -o $prx $in $libs' % prx_flags,
        pool='link_pool'
      )
      master_ninja.rule(
        'prx_export_pickup',
        description='PRX-EXPORT-PICKUP $out',
        command='$prx_export_pickup --output-src=$out $in')

    else:  # Assume it is a Linux platform
      # This allows targets that only need to depend on $lib's API to declare an
      # order-only dependency on $lib.TOC and avoid relinking such downstream
      # dependencies when $lib changes only in non-public ways.
      # The resulting string leaves an uninterpolated %{suffix} which
      # is used in the final substitution below.
      mtime_preserving_solink_base = (
          'if [ ! -e $lib -o ! -e ${lib}.TOC ]; then '
          '%(solink)s && %(extract_toc)s > ${lib}.TOC; else '
          '%(solink)s && %(extract_toc)s > ${lib}.tmp && '
          'if ! cmp -s ${lib}.tmp ${lib}.TOC; then mv ${lib}.tmp ${lib}.TOC ; '
          'fi; fi'
          % { 'solink':
                (ld_cmd +
                 ' -shared $ldflags -o $lib -Wl,-soname=$soname %(suffix)s'),
              'extract_toc':
                ('{ readelf -d ${lib} | grep SONAME ; '
                 'nm -gD -f p ${lib} | cut -f1-2 -d\' \'; }')})

      master_ninja.rule(
        'solink',
        description='SOLINK $lib',
        restat=True,
        command=(mtime_preserving_solink_base % {
            'suffix': '-Wl,--whole-archive $in $solibs -Wl,--no-whole-archive '
            '$libs'}))
      master_ninja.rule(
        'solink_module',
        description='SOLINK(module) $lib',
        restat=True,
        command=(mtime_preserving_solink_base % {
            'suffix': '-Wl,--start-group $in $solibs -Wl,--end-group $libs'}))

    if flavor in ['ps3', 'ps4']:
      # PS3 and PS4 linkers don't know about rpath.
      rpath = ''
    else:
      rpath = r'-Wl,-rpath=\$$ORIGIN/lib'

    master_ninja.rule(
      'link',
      description='LINK $out',
      command=(ld_cmd +' @$out.rsp'),
      rspfile='$out.rsp',
      rspfile_content=('$ldflags -o $out %s -Wl,--start-group $in $solibs '
                       '-Wl,--end-group $libs' % rpath),
      pool='link_pool')
  elif flavor in ['win', 'xb1']:
    master_ninja.rule(
        'alink',
        description='LIB $out',
        command=('%s gyp-win-tool link-wrapper $arch '
                 '$ar /nologo /ignore:4221 /OUT:$out @$out.rsp' %
                 python_exec),
        rspfile='$out.rsp',
        rspfile_content='$in_newline $libflags')
    dlldesc = 'LINK(DLL) $dll'
    dllcmd = ('%s gyp-win-tool link-wrapper $arch '
              '$ld /nologo $implibflag /DLL /OUT:$dll '
              '/PDB:$dll.pdb @$dll.rsp' % python_exec)
    if flavor != 'xb1':
      # XB1 doesn't need a manifest.
      dllcmd += (' && %s gyp-win-tool manifest-wrapper $arch '
                 '$mt -nologo -manifest $manifests -out:$dll.manifest' %
                 python_exec)
    master_ninja.rule('solink', description=dlldesc, command=dllcmd,
                      rspfile='$dll.rsp',
                      rspfile_content='$libs $in_newline $ldflags',
                      restat=True)
    master_ninja.rule('solink_module', description=dlldesc, command=dllcmd,
                      rspfile='$dll.rsp',
                      rspfile_content='$libs $in_newline $ldflags',
                      restat=True)
    # Note that ldflags goes at the end so that it has the option of
    # overriding default settings earlier in the command line.
    if flavor == 'win':
      link_command=('%s gyp-win-tool link-wrapper $arch '
                   '$ld /nologo /OUT:$out /PDB:$out.pdb @$out.rsp && '
                   '%s gyp-win-tool manifest-wrapper $arch '
                   '$mt -nologo -manifest $manifests -out:$out.manifest' %
                   (python_exec, python_exec))
    else:
      assert flavor == 'xb1'
      # XB1 doesn't need a manifest.
      link_command=('%s gyp-win-tool link-wrapper $arch '
                   '$ld /nologo /OUT:$out /PDB:$out.pdb @$out.rsp' %
                   (python_exec))

    master_ninja.rule(
        'link',
        description='LINK $out',
        command=link_command,
        rspfile='$out.rsp',
        rspfile_content='$in_newline $libs $ldflags',
        pool='link_pool')
  else:
    master_ninja.rule(
      'objc',
      description='OBJC $out',
      command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc '
               '$cflags_pch_objc -c $in -o $out'),
      depfile='$out.d')
    master_ninja.rule(
      'objcxx',
      description='OBJCXX $out',
      command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc '
               '$cflags_pch_objcc -c $in -o $out'),
      depfile='$out.d')
    master_ninja.rule(
      'alink',
      description='LIBTOOL-STATIC $out, POSTBUILDS',
      command='rm -f $out && '
              './gyp-mac-tool filter-libtool libtool $libtool_flags '
              '-static -o $out $in'
              '$postbuilds')

    # Record the public interface of $lib in $lib.TOC. See the corresponding
    # comment in the posix section above for details.
    mtime_preserving_solink_base = (
        'if [ ! -e $lib -o ! -e ${lib}.TOC ] || '
             # Always force dependent targets to relink if this library
             # reexports something. Handling this correctly would require
             # recursive TOC dumping but this is rare in practice, so punt.
             'otool -l $lib | grep -q LC_REEXPORT_DYLIB ; then '
          '%(solink)s && %(extract_toc)s > ${lib}.TOC; '
        'else '
          '%(solink)s && %(extract_toc)s > ${lib}.tmp && '
          'if ! cmp -s ${lib}.tmp ${lib}.TOC; then '
            'mv ${lib}.tmp ${lib}.TOC ; '
          'fi; '
        'fi'
        % { 'solink': '$ld -shared $ldflags -o $lib %(suffix)s',
            'extract_toc':
              '{ otool -l $lib | grep LC_ID_DYLIB -A 5; '
              'nm -gP $lib | cut -f1-2 -d\' \' | grep -v U$$; true; }'})

    # TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass
    # -bundle -single_module here (for osmesa.so).
    master_ninja.rule(
      'solink',
      description='SOLINK $lib, POSTBUILDS',
      restat=True,
      command=(mtime_preserving_solink_base % {
          'suffix': '$in $solibs $libs$postbuilds'}))
    master_ninja.rule(
      'solink_module',
      description='SOLINK(module) $lib, POSTBUILDS',
      restat=True,
      command=(mtime_preserving_solink_base % {
          'suffix': '$in $solibs $libs$postbuilds'}))

    master_ninja.rule(
      'link',
      description='LINK $out, POSTBUILDS',
      command=('$ld $ldflags -o $out '
               '$in $solibs $libs$postbuilds'),
      pool='link_pool')
    master_ninja.rule(
      'infoplist',
      description='INFOPLIST $out',
      command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && '
               'plutil -convert xml1 $out $out'))
    master_ninja.rule(
      'mac_tool',
      description='MACTOOL $mactool_cmd $in',
      command='$env ./gyp-mac-tool $mactool_cmd $in $out')
    master_ninja.rule(
      'package_framework',
      description='PACKAGE FRAMEWORK $out, POSTBUILDS',
      command='./gyp-mac-tool package-framework $out $version$postbuilds '
              '&& touch $out')
  if flavor in ['win', 'xb1']:
    master_ninja.rule(
      'stamp',
      description='STAMP $out',
      command='%s gyp-win-tool stamp $out' % python_exec)
    master_ninja.rule(
      'copy',
      description='COPY $in $out',
      command='%s gyp-win-tool recursive-mirror $in $out' % python_exec)
  elif sys.platform in ['cygwin', 'win32']:
    master_ninja.rule(
      'stamp',
      description='STAMP $out',
      command='$python gyp-win-tool stamp $out')
    master_ninja.rule(
      'copy',
      description='COPY $in $out',
      command='$python gyp-win-tool recursive-mirror $in $out')
  else:
    master_ninja.rule(
      'stamp',
      description='STAMP $out',
      command='${postbuilds}touch $out')
    master_ninja.rule(
      'copy',
      description='COPY $in $out',
      command='rm -rf $out && cp -af $in $out')
  master_ninja.newline()

  # Output host building rules
  if is_windows:
    cc_command = ('$cc /nologo /showIncludes /FC '
                  '@$out.rsp /c $in /Fo$out /Fd$pdbname ')
    cxx_command = ('$cxx /nologo /showIncludes /FC '
                   '@$out.rsp /c $in /Fo$out /Fd$pdbname ')
    master_ninja.rule(
      'cc_host',
      description='CC_HOST $out',
      command=cc_command,
      deps='msvc',
      rspfile='$out.rsp',
      rspfile_content='$defines $includes $cflags_host $cflags_c_host')
    master_ninja.rule(
      'cxx_host',
      description='CXX_HOST $out',
      command=cxx_command,
      deps='msvc',
      rspfile='$out.rsp',
      rspfile_content='$defines $includes $cflags_host $cflags_cc_host')

    master_ninja.rule(
        'alink_host',
        description='LIB_HOST $out',
        command=('%s gyp-win-tool link-wrapper $arch '
                 '$ar /nologo /ignore:4221 /OUT:$out @$out.rsp' %
                 python_exec),
        rspfile='$out.rsp',
        rspfile_content='$in_newline $libflags_host')

    master_ninja.rule(
        'alink_thin_host',
        description='LIB_HOST $out',
        command=('%s gyp-win-tool link-wrapper $arch '
                 '$ar /nologo /ignore:4221 /OUT:$out @$out.rsp' %
                 python_exec),
        rspfile='$out.rsp',
        rspfile_content='$in_newline $libflags_host')

    link_command=('%s gyp-win-tool link-wrapper $arch '
                 '$ld /nologo /OUT:$out /PDB:$out.pdb @$out.rsp' %
                 (python_exec))

    master_ninja.rule(
        'link_host',
        description='LINK_HOST $out',
        command=link_command,
        rspfile='$out.rsp',
        rspfile_content='$in_newline $libs $ldflags',
        pool='link_pool')
  else:
    cc_command = 'bash -c "$cc_host @$out.rsp"'
    cxx_command = 'bash -c "$cxx_host @$out.rsp"'
    master_ninja.rule(
      'cc_host',
      description='CC_HOST $out',
      command=cc_command,
      rspfile='$out.rsp',
      rspfile_content=('-MMD -MF $out.d $defines $includes $cflags_host '
                       '$cflags_c_host $cflags_pch_c -c $in -o $out'),
      depfile='$out.d')
    master_ninja.rule(
      'cxx_host',
      description='CXX_HOST $out',
      command=cxx_command,
      rspfile='$out.rsp',
      rspfile_content=('-MMD -MF $out.d $defines $includes $cflags_host '
                       '$cflags_cc_host $cflags_pch_cc -c $in -o $out'),
      depfile='$out.d')

    alink_command = 'rm -f $out && $ar_host $arFlags_host $out @$out.rsp'
    alink_thin_command = ('rm -f $out && $ar_host $arThinFlags_host $out '
                          '@$out.rsp')

    master_ninja.rule(
      'alink_host',
      description='AR_HOST $out',
      command='bash -c "' + alink_command + '"',
      rspfile='$out.rsp',
      rspfile_content='$in_newline')
    master_ninja.rule(
      'alink_thin_host',
      description='AR_HOST $out',
      command='bash -c "' + alink_thin_command + '"',
      rspfile='$out.rsp',
      rspfile_content='$in_newline')
    beginlinkinlibs = ''
    endlinkinlibs = ''
    if is_linux:
      beginlinkinlibs = '-Wl,--start-group'
      endlinkinlibs = '-Wl,--end-group'
    rpath = '-Wl,-rpath=\$$ORIGIN/lib'
    master_ninja.rule(
      'link_host',
      description='LINK_HOST $out',
      command=('bash -c "$ld_host $ldflags_host -o $out %s '
               '%s $in $solibs %s $libs"' % (rpath,
                                             beginlinkinlibs, endlinkinlibs)))

  all_targets = set()
  for build_file in params['build_files']:
    for target in gyp.common.AllTargets(target_list,
                                        target_dicts,
                                        os.path.normpath(build_file)):
      all_targets.add(target)
  all_outputs = set()

  # target_outputs is a map from qualified target name to a Target object.
  target_outputs = {}
  # target_short_names is a map from target short name to a list of Target
  # objects.
  target_short_names = {}
  default_project = None
  for qualified_target in target_list:
    # qualified_target is like: third_party/icu/icu.gyp:icui18n#target
    build_file, name, toolset = \
        gyp.common.ParseQualifiedTarget(qualified_target)

    this_make_global_settings = data[build_file].get('make_global_settings', [])
    assert make_global_settings == this_make_global_settings, (
        "make_global_settings needs to be the same for all targets.")

    spec = target_dicts[qualified_target]

    if spec.get('default_project', 0):
      if default_project is None or default_project == name:
        default_project = name
      else:
        raise Exception('More than one default_project specified.'
          'First in {0} and now in {1}'.format(default_project, name))

    if flavor == 'mac':
      gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec)

    build_file = gyp.common.RelativePath(build_file, options.toplevel_dir)

    base_path = os.path.dirname(build_file)
    obj = 'obj'
    if toolset != 'target':
      obj += '.' + toolset
    output_file = os.path.join(obj, base_path, name + '.ninja')

    abs_build_dir = os.path.abspath(toplevel_build)
    writer = NinjaWriter(qualified_target, target_outputs, base_path, build_dir,
                         OpenOutput(os.path.join(toplevel_build, output_file)),
                         flavor, case_sensitive_filesystem,
                         abs_build_dir=abs_build_dir)
    master_ninja.subninja(output_file)

    target = writer.WriteSpec(
        spec, config_name, generator_flags)
    if target:
      if name != target.FinalOutput():
        out_name = name
        if toolset != 'target':
          out_name = out_name + '.' + toolset
        target_short_names.setdefault(out_name, []).append(target)
      target_outputs[qualified_target] = target
      if qualified_target in all_targets:
        all_outputs.add(target.FinalOutput())

  if target_short_names:
    # Write a short name to build this target.  This benefits both the
    # "build chrome" case as well as the gyp tests, which expect to be
    # able to run actions and build libraries by their short name.
    master_ninja.newline()
    master_ninja.comment('Short names for targets.')
    for short_name in target_short_names:
      master_ninja.build(short_name, 'phony', [x.FinalOutput() for x in
                                               target_short_names[short_name]])

  if all_outputs:
    master_ninja.newline()
    master_ninja.build('all', 'phony', list(all_outputs))
    if default_project:
      master_ninja.default(default_project)
    else:
      master_ninja.default('all')


def PerformBuild(data, configurations, params):
  options = params['options']
  for config in configurations:
    builddir = os.path.join(options.toplevel_dir, 'out', config)
    arguments = ['ninja', '-C', builddir]
    print 'Building [%s]: %s' % (config, arguments)
    subprocess.check_call(arguments)


def CallGenerateOutputForConfig(arglist):
  # Ignore the interrupt signal so that the parent process catches it and
  # kills all multiprocessing children.
  signal.signal(signal.SIGINT, signal.SIG_IGN)

  (target_list, target_dicts, data, params, config_name) = arglist
  GenerateOutputForConfig(target_list, target_dicts, data, params, config_name)


def GenerateOutput(target_list, target_dicts, data, params):
  user_config = params.get('generator_flags', {}).get('config', None)
  if gyp.common.GetFlavor(params) in ['win', 'xb1']:
    target_list, target_dicts = MSVSUtil.ShardTargets(target_list, target_dicts)
  if user_config:
    GenerateOutputForConfig(target_list, target_dicts, data, params,
                            user_config)
  else:
    config_names = target_dicts[target_list[0]]['configurations'].keys()
    if params['parallel']:
      try:
        pool = multiprocessing.Pool(len(config_names))
        arglists = []
        for config_name in config_names:
          arglists.append(
              (target_list, target_dicts, data, params, config_name))
          pool.map(CallGenerateOutputForConfig, arglists)
      except KeyboardInterrupt, e:
        pool.terminate()
        raise e
    else:
      for config_name in config_names:
        GenerateOutputForConfig(target_list, target_dicts, data, params,
                                config_name)
