# 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 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

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'))


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 == 'win':
    return gyp.msvs_emulation.QuoteForRspFile(arg)
  return "'" + arg.replace("'", "'" + '"\'"' + "'")  + "'"


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


def AddArch(output, arch):
  """Adds an arch string to an output path."""
  output, extension = os.path.splitext(output)
  return '%s.%s%s' % (output, arch, extension)


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 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.
    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 == 'win' 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, toplevel_build, output_file_name, flavor,
               toplevel_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
    toplevel_dir: path to the toplevel directory
    """

    self.qualified_target = qualified_target
    self.target_outputs = target_outputs
    self.base_dir = base_dir
    self.build_dir = build_dir
    self.ninja = ninja_syntax.Writer(output_file)
    self.toplevel_build = toplevel_build
    self.output_file_name = output_file_name

    self.flavor = flavor
    self.abs_build_dir = None
    if toplevel_dir is not None:
      self.abs_build_dir = os.path.abspath(os.path.join(toplevel_dir,
                                                        build_dir))
    self.obj_ext = '.obj' if flavor == 'win' else '.o'
    if flavor == 'win':
      # 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.
    build_to_top = gyp.common.InvertRelativePath(build_dir, toplevel_dir)
    self.build_to_base = os.path.join(build_to_top, base_dir)
    # Relative path from base dir to build dir.
    base_to_top = gyp.common.InvertRelativePath(base_dir, toplevel_dir)
    self.base_to_build = os.path.join(base_to_top, 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 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 == 'win':
        path = gyp.msvs_emulation.ExpandMacros(path, env)
    if path.startswith('$!'):
      expanded = self.ExpandSpecial(path)
      if self.flavor == 'win':
        expanded = os.path.normpath(expanded)
      return expanded
    if '$|' in path:
      path = self.ExpandSpecial(path)
    assert '$' not in path, path
    return os.path.normpath(os.path.join(self.build_to_base, 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
    return os.path.normpath(os.path.join(obj, self.base_dir, path_dir,
                                         path_basename))

  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 _SubninjaNameForArch(self, arch):
    output_file_base = os.path.splitext(self.output_file_name)[0]
    return '%s.%s.ninja' % (output_file_base, arch)

  def WriteSpec(self, spec, config_name, generator_flags,
      case_sensitive_filesystem):
    """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 == 'win':
      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])
      self.ninja.variable('cc', '$cl_' + arch)
      self.ninja.variable('cxx', '$cl_' + arch)

    if self.flavor == 'mac':
      self.archs = self.xcode_settings.GetActiveArchs(config_name)
      if len(self.archs) > 1:
        self.arch_subninjas = dict(
            (arch, ninja_syntax.Writer(
                open(os.path.join(self.toplevel_build,
                                  self._SubninjaNameForArch(arch)),
                     'w')))
            for arch in self.archs)

    # 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:
      if self.flavor == 'mac' and len(self.archs) > 1:
        # Write subninja file containing compile and link commands scoped to
        # a single arch if a fat binary is being built.
        for arch in self.archs:
          self.ninja.subninja(self._SubninjaNameForArch(arch))

      pch = None
      if self.flavor == 'win':
        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(
          self.ninja, config_name, config, sources, compile_depends_stamp, pch,
          case_sensitive_filesystem, spec)
      # Some actions/rules output 'sources' that are already object files.
      obj_outputs = [f for f in sources if f.endswith(self.obj_ext)]
      if obj_outputs:
        if self.flavor != 'mac' or len(self.archs) == 1:
          link_deps += [self.GypPathToNinja(o) for o in obj_outputs]
        else:
          print "Warning: Actions/rules writing object files don't work with " \
                "multiarch targets, dropping. (target %s)" % spec['target_name']


    if self.flavor == 'win' and self.target.type == 'static_library':
      self.target.component_objs = link_deps

    # Write out a link step, if needed.
    output = None
    is_empty_bundle = True
    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:
        is_empty_bundle = not link_deps and not mac_bundle_depends
        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, is_empty_bundle)

    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 == 'win'
    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 == 'win':
      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 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.msvs_settings.IsRuleRunUnderCygwin(action)
                   if self.flavor == 'win' else False)
      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.msvs_settings.IsRuleRunUnderCygwin(rule)
                   if self.flavor == 'win' else False)
      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', []):
        source = os.path.normpath(source)
        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':
            # '$dirname' 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.
            dirname_expanded = self.ExpandSpecial(dirname, self.base_to_build)
            extra_bindings.append(('dirname', cygwin_munge(dirname_expanded)))
          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 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)
        basename = os.path.split(path)[1]
        src = self.GypPathToNinja(path, env)
        dst = self.GypPathToNinja(os.path.join(copy['destination'], basename),
                                  env)
        outputs += 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 outputs

  def WriteMacBundleResources(self, resources, bundle_depends):
    """Writes ninja edges for 'mac_bundle_resources'."""
    for output, res in gyp.xcode_emulation.GetMacBundleResources(
        generator_default_variables['PRODUCT_DIR'],
        self.xcode_settings, map(self.GypPathToNinja, resources)):
      output = self.ExpandSpecial(output)
      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(
        generator_default_variables['PRODUCT_DIR'],
        self.xcode_settings, self.GypPathToNinja)
    if not info_plist:
      return
    out = self.ExpandSpecial(out)
    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, ninja_file, config_name, config, sources, predepends,
                   precompiled_header, case_sensitive_filesystem, 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')

    if self.flavor != 'mac' or len(self.archs) == 1:
      return self.WriteSourcesForArch(
          self.ninja, config_name, config, sources, predepends,
          precompiled_header, case_sensitive_filesystem, spec)
    else:
      return dict((arch, self.WriteSourcesForArch(
            self.arch_subninjas[arch], config_name, config, sources, predepends,
            precompiled_header, case_sensitive_filesystem, spec, arch=arch))
          for arch in self.archs)

  def WriteSourcesForArch(self, ninja_file, config_name, config, sources,
                          predepends, precompiled_header,
                          case_sensitive_filesystem, spec, arch=None):
    """Write build rules to compile all of |sources|."""

    extra_defines = []
    if self.flavor == 'mac':
      cflags = self.xcode_settings.GetCflags(config_name, arch=arch)
      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 == 'win':
      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)
      pdbpath = self.msvs_settings.GetCompilerPdbName(
          config_name, self.ExpandSpecial)
      if not pdbpath:
        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(ninja_file, 'pdbname', [pdbpath])
      self.WriteVariableList(ninja_file, 'pchprefix', [self.name])
    else:
      cflags = config.get('cflags', [])
      cflags_c = config.get('cflags_c', [])
      cflags_cc = config.get('cflags_cc', [])

    # Respect environment variables related to build, but target-specific
    # flags can still override them.
    if self.toolset == 'target':
      cflags_c = (os.environ.get('CPPFLAGS', '').split() +
                  os.environ.get('CFLAGS', '').split() + cflags_c)
      cflags_cc = (os.environ.get('CPPFLAGS', '').split() +
                   os.environ.get('CXXFLAGS', '').split() + cflags_cc)

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

    include_dirs = config.get('include_dirs', [])
    if self.flavor == 'win':
      include_dirs = self.msvs_settings.AdjustIncludeDirs(include_dirs,
                                                          config_name)
    env = self.GetSortedXcodeEnv()
    self.WriteVariableList(ninja_file, 'includes',
        [QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor)
         for i in include_dirs])

    pch_commands = precompiled_header.GetPchBuildCommands(arch)
    if self.flavor == 'mac':
      # Most targets use no precompiled headers, so only write these if needed.
      for ext, var in [('c', 'cflags_pch_c'), ('cc', 'cflags_pch_cc'),
                       ('m', 'cflags_pch_objc'), ('mm', 'cflags_pch_objcc')]:
        include = precompiled_header.GetInclude(ext, arch)
        if include: ninja_file.variable(var, include)

    self.WriteVariableList(ninja_file, 'cflags',
                           map(self.ExpandSpecial, cflags))
    self.WriteVariableList(ninja_file, 'cflags_c',
                           map(self.ExpandSpecial, cflags_c))
    self.WriteVariableList(ninja_file, 'cflags_cc',
                           map(self.ExpandSpecial, cflags_cc))
    if self.flavor == 'mac':
      self.WriteVariableList(ninja_file, 'cflags_objc',
                             map(self.ExpandSpecial, cflags_objc))
      self.WriteVariableList(ninja_file, 'cflags_objcc',
                             map(self.ExpandSpecial, cflags_objcc))
    ninja_file.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 == 'win' and ext == 'rc':
        command = 'rc'
        obj_ext = '.res'
      else:
        # Ignore unhandled extensions.
        continue
      input = self.GypPathToNinja(source)
      output = self.GypPathToUniqueOutput(filename + obj_ext)
      if arch is not None:
        output = AddArch(output, arch)
      # 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 .o filenames to lowercase on such file systems. See
      # https://github.com/martine/ninja/issues/402 for details.
      if not case_sensitive_filesystem:
        output = output.lower()
      implicit = precompiled_header.GetObjDependencies([input], [output], arch)
      variables = []
      if self.flavor == 'win':
        variables, output, implicit = precompiled_header.GetFlagsModifications(
            input, output, implicit, command, cflags_c, cflags_cc,
            self.ExpandSpecial)
      ninja_file.build(output, command, input,
                       implicit=[gch for _, _, gch in implicit],
                       order_only=predepends, variables=variables)
      outputs.append(output)

    self.WritePchTargets(ninja_file, pch_commands)

    ninja_file.newline()
    return outputs

  def WritePchTargets(self, ninja_file, 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)
      ninja_file.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. """
    if self.flavor != 'mac' or len(self.archs) == 1:
      return self.WriteLinkForArch(
          self.ninja, spec, config_name, config, link_deps)
    else:
      output = self.ComputeOutput(spec)
      inputs = [self.WriteLinkForArch(self.arch_subninjas[arch], spec,
                                      config_name, config, link_deps[arch],
                                      arch=arch)
                for arch in self.archs]
      extra_bindings = []
      if not self.is_mac_bundle:
        self.AppendPostbuildVariable(extra_bindings, spec, output, output)
      self.ninja.build(output, 'lipo', inputs, variables=extra_bindings)
      return output

  def WriteLinkForArch(self, ninja_file, spec, config_name, config,
                       link_deps, arch=None):
    """Write out a link step. Fills out target.binary. """
    command = {
      'executable':      'link',
      'loadable_module': 'solink_module',
      'shared_library':  'solink',
    }[spec['type']]
    command_suffix = ''

    implicit_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
      extra_link_deps = set()
      for dep in spec['dependencies']:
        target = self.target_outputs.get(dep)
        if not target:
          continue
        linkable = target.Linkable()
        if linkable:
          if (self.flavor == 'win' and
              target.component_objs and
              self.msvs_settings.IsUseLibraryDependencyInputs(config_name)):
            extra_link_deps |= set(target.component_objs)
          elif self.flavor == 'win' and target.import_lib:
            extra_link_deps.add(target.import_lib)
          elif target.UsesToc(self.flavor):
            solibs.add(target.binary)
            implicit_deps.add(target.binary + '.TOC')
          else:
            extra_link_deps.add(target.binary)

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

      link_deps.extend(list(extra_link_deps))

    extra_bindings = []
    output = self.ComputeOutput(spec, arch)
    if arch is None and not self.is_mac_bundle:
      self.AppendPostbuildVariable(extra_bindings, spec, output, output)

    is_executable = spec['type'] == 'executable'
    if self.flavor == 'mac':
      ldflags = self.xcode_settings.GetLdflags(config_name,
          self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
          self.GypPathToNinja, arch)
    elif self.flavor == 'win':
      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(ninja_file, 'manifests', manifest_files)
      command_suffix = _GetWinLinkRuleNameSuffix(
          self.msvs_settings.IsEmbedManifest(config_name),
          self.msvs_settings.IsLinkIncremental(config_name))
      def_file = self.msvs_settings.GetDefFile(self.GypPathToNinja)
      if def_file:
        implicit_deps.add(def_file)
    else:
      # Respect environment variables related to build, but target-specific
      # flags can still override them.
      ldflags = (os.environ.get('LDFLAGS', '').split() +
                 config.get('ldflags', []))
      if is_executable and len(solibs):
        rpath = 'lib/'
        if self.toolset != 'target':
          rpath += self.toolset
        ldflags.append('-Wl,-rpath=\$$ORIGIN/%s' % rpath)
        ldflags.append('-Wl,-rpath-link=%s' % rpath)
    self.WriteVariableList(ninja_file, 'ldflags',
                           gyp.common.uniquer(map(self.ExpandSpecial, ldflags)))

    library_dirs = config.get('library_dirs', [])
    if self.flavor == 'win':
      library_dirs = [self.msvs_settings.ConvertVSMacros(l, config_name)
                      for l in library_dirs]
      library_dirs = [QuoteShellArgument('-LIBPATH:' + self.GypPathToNinja(l),
                                         self.flavor)
                      for l in library_dirs]
    else:
      library_dirs = [QuoteShellArgument('-L' + self.GypPathToNinja(l),
                                         self.flavor)
                      for l in library_dirs]

    libraries = gyp.common.uniquer(map(self.ExpandSpecial,
                                       spec.get('libraries', [])))
    if self.flavor == 'mac':
      libraries = self.xcode_settings.AdjustLibraries(libraries)
    elif self.flavor == 'win':
      libraries = self.msvs_settings.AdjustLibraries(libraries)

    self.WriteVariableList(ninja_file, 'libs', library_dirs + libraries)

    linked_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 == 'win':
        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 not self.is_mac_bundle:
        output = [output, output + '.TOC']
      else:
        command = command + '_notoc'

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

    ninja_file.build(output, command + command_suffix, link_deps,
                     implicit=list(implicit_deps),
                     variables=extra_bindings)
    return linked_binary

  def WriteTarget(self, spec, config_name, config, link_deps, compile_deps):
    if spec['type'] == 'none' or not link_deps:
      # 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)
      if (self.flavor not in ('mac', 'openbsd', 'win') and not
          self.is_standalone_static_library):
        self.ninja.build(self.target.binary, 'alink_thin', link_deps,
                         order_only=compile_deps)
      else:
        variables = []
        if self.xcode_settings:
          libtool_flags = self.xcode_settings.GetLibtoolflags(config_name)
          if libtool_flags:
            variables.append(('libtool_flags', libtool_flags))
        if self.msvs_settings:
          libflags = self.msvs_settings.GetLibFlags(config_name,
                                                    self.GypPathToNinja)
          variables.append(('libflags', libflags))

        if self.flavor != 'mac' or len(self.archs) == 1:
          self.AppendPostbuildVariable(variables, spec,
                                       self.target.binary, self.target.binary)
          self.ninja.build(self.target.binary, 'alink', link_deps,
                           order_only=compile_deps, variables=variables)
        else:
          inputs = []
          for arch in self.archs:
            output = self.ComputeOutput(spec, arch)
            self.arch_subninjas[arch].build(output, 'alink', link_deps[arch],
                                            order_only=compile_deps,
                                            variables=variables)
            inputs.append(output)
          # TODO: It's not clear if libtool_flags should be passed to the alink
          # call that combines single-arch .a files into a fat .a file.
          self.AppendPostbuildVariable(variables, spec,
                                       self.target.binary, self.target.binary)
          self.ninja.build(self.target.binary, 'alink', inputs,
                           # FIXME: test proving order_only=compile_deps isn't
                           # needed.
                           variables=variables)
    else:
      self.target.binary = self.WriteLink(spec, config_name, config, link_deps)
    return self.target.binary

  def WriteMacBundle(self, spec, mac_bundle_depends, is_empty):
    assert self.is_mac_bundle
    package_framework = spec['type'] in ('shared_library', 'loadable_module')
    output = self.ComputeMacBundleOutput()
    if is_empty:
      output += '.stamp'
    variables = []
    self.AppendPostbuildVariable(variables, spec, output, self.target.binary,
                                 is_command_start=not package_framework)
    if package_framework and not is_empty:
      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 AppendPostbuildVariable(self, variables, spec, output, binary,
                              is_command_start=False):
    """Adds a 'postbuild' variable if there is a postbuild for |output|."""
    postbuild = self.GetPostbuildCommand(spec, output, binary, is_command_start)
    if postbuild:
      variables.append(('postbuilds', postbuild))

  def GetPostbuildCommand(self, spec, output, output_binary, is_command_start):
    """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 = []
    if output_binary is not None:
      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 + ' (' + \
        ' && '.join([ninja_syntax.escape(command) for command in postbuilds])
    command_string = (commands + '); 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 = generator_default_variables['PRODUCT_DIR']
    return self.ExpandSpecial(
        os.path.join(path, self.xcode_settings.GetWrapperName()))

  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
    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, arch=None):
    """Compute the path for the final output of the spec."""
    type = spec['type']

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

    if arch is None and 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 arch is None and '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 == 'win' and self.toolset == 'target':
      type_in_output_root += ['shared_library']

    if arch is not None:
      # Make sure partial executables don't end up in a bundle or the regular
      # output directory.
      archdir = 'arch'
      if self.toolset != 'target':
        archdir = os.path.join('arch', '%s' % self.toolset)
      return os.path.join(archdir, AddArch(filename, arch))
    elif 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, ninja_file, var, values):
    assert not isinstance(values, str)
    if values is None:
      values = []
    ninja_file.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 == 'win':
      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 == 'win':
    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
  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 CommandWithWrapper(cmd, wrappers, prog):
  wrapper = wrappers.get(cmd, '')
  if wrapper:
    return wrapper + ' ' + prog
  return prog


def GetDefaultConcurrentLinks():
  """Returns a best-guess for a number of concurrent links."""
  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))

    return max(1, stat.ullTotalPhys / (4 * (2 ** 30)))  # total / 4GB
  elif sys.platform.startswith('linux'):
    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 8Gb per link on Linux because Gold is quite memory hungry
        return max(1, int(match.group(1)) / (8 * (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 _GetWinLinkRuleNameSuffix(embed_manifest, link_incremental):
  """Returns the suffix used to select an appropriate linking rule depending on
  whether the manifest embedding and/or incremental linking is enabled."""
  suffix = ''
  if embed_manifest:
    suffix += '_embed'
    if link_incremental:
      suffix += '_inc'
  return suffix


def _AddWinLinkRules(master_ninja, embed_manifest, link_incremental):
  """Adds link rules for Windows platform to |master_ninja|."""
  def FullLinkCommand(ldcmd, out, binary_type):
    cmd = ('cmd /c %(ldcmd)s'
           ' && %(python)s gyp-win-tool manifest-wrapper $arch'
           ' cmd /c if exist %(out)s.manifest del %(out)s.manifest'
           ' && %(python)s gyp-win-tool manifest-wrapper $arch'
           ' $mt -nologo -manifest $manifests')
    if embed_manifest and not link_incremental:
      # Embed manifest into a binary. If incremental linking is enabled,
      # embedding is postponed to the re-linking stage (see below).
      cmd += ' -outputresource:%(out)s;%(resname)s'
    else:
      # Save manifest as an external file.
      cmd += ' -out:%(out)s.manifest'
    if link_incremental:
      # There is no point in generating separate rule for the case when
      # incremental linking is enabled, but manifest embedding is disabled.
      # In that case the basic rule should be used (e.g. 'link').
      # See also implementation of _GetWinLinkRuleNameSuffix().
      assert embed_manifest
      # Make .rc file out of manifest, compile it to .res file and re-link.
      cmd += (' && %(python)s gyp-win-tool manifest-to-rc $arch'
              ' %(out)s.manifest %(out)s.manifest.rc %(resname)s'
              ' && %(python)s gyp-win-tool rc-wrapper $arch $rc'
              ' %(out)s.manifest.rc'
              ' && %(ldcmd)s %(out)s.manifest.res')
    resource_name = {
      'exe': '1',
      'dll': '2',
    }[binary_type]
    return cmd % {'python': sys.executable,
                  'out': out,
                  'ldcmd': ldcmd,
                  'resname': resource_name}

  rule_name_suffix = _GetWinLinkRuleNameSuffix(embed_manifest, link_incremental)
  dlldesc = 'LINK%s(DLL) $dll' % rule_name_suffix.upper()
  dllcmd = ('%s gyp-win-tool link-wrapper $arch '
            '$ld /nologo $implibflag /DLL /OUT:$dll '
            '/PDB:$dll.pdb @$dll.rsp' % sys.executable)
  dllcmd = FullLinkCommand(dllcmd, '$dll', 'dll')
  master_ninja.rule('solink' + rule_name_suffix,
                    description=dlldesc, command=dllcmd,
                    rspfile='$dll.rsp',
                    rspfile_content='$libs $in_newline $ldflags',
                    restat=True)
  master_ninja.rule('solink_module' + rule_name_suffix,
                    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.
  exe_cmd = ('%s gyp-win-tool link-wrapper $arch '
             '$ld /nologo /OUT:$out /PDB:$out.pdb @$out.rsp' %
              sys.executable)
  exe_cmd = FullLinkCommand(exe_cmd, '$out', 'exe')
  master_ninja.rule('link' + rule_name_suffix,
                    description='LINK%s $out' % rule_name_suffix.upper(),
                    command=exe_cmd,
                    rspfile='$out.rsp',
                    rspfile_content='$in_newline $libs $ldflags')


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 = not os.path.exists(
      os.path.join(toplevel_build, 'BUILD.NINJA'))

  # 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':
    # Overridden by local arch choice in the use_deps case.
    # Chromium's ffmpeg c99conv.py currently looks for a 'cc =' line in
    # build.ninja so needs something valid here. http://crbug.com/233985
    cc = 'cl.exe'
    cxx = 'cl.exe'
    ld = 'link.exe'
    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 = gyp.common.InvertRelativePath(build_dir,
                                                options.toplevel_dir)
  wrappers = {}
  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)
    if key.endswith('_wrapper'):
      wrappers[key[:-len('_wrapper')]] = os.path.join(build_to_root, value)

  # Support wrappers from environment variables too.
  for key, value in os.environ.iteritems():
    if key.lower().endswith('_wrapper'):
      key_prefix = key[:-len('_wrapper')]
      key_prefix = re.sub(r'\.HOST$', '.host', key_prefix)
      wrappers[key_prefix] = os.path.join(build_to_root, value)

  if flavor == 'win':
    cl_paths = gyp.msvs_emulation.GenerateEnvironmentFiles(
        toplevel_build, generator_flags, OpenOutput)
    for arch, path in cl_paths.iteritems():
      master_ninja.variable(
          'cl_' + arch, CommandWithWrapper('CC', wrappers,
                                           QuoteShellArgument(path, flavor)))

  cc = GetEnvironFallback(['CC_target', 'CC'], cc)
  master_ninja.variable('cc', CommandWithWrapper('CC', wrappers, cc))
  cxx = GetEnvironFallback(['CXX_target', 'CXX'], cxx)
  master_ninja.variable('cxx', CommandWithWrapper('CXX', wrappers, cxx))
  ld = GetEnvironFallback(['LD_target', 'LD'], ld)

  if flavor == 'win':
    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')
  else:
    master_ninja.variable('ld', CommandWithWrapper('LINK', wrappers, ld))
    master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], 'ar'))

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

    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)

    # 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',
                          CommandWithWrapper('CC.host', wrappers, cc_host))
    master_ninja.variable('cxx_host',
                          CommandWithWrapper('CXX.host', wrappers, cxx_host))
    if flavor == 'win':
      master_ninja.variable('ld_host', ld_host)
    else:
      master_ninja.variable('ld_host', CommandWithWrapper(
          'LINK', wrappers, ld_host))

  master_ninja.newline()

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

  deps = 'msvc' if flavor == 'win' else 'gcc'

  if flavor != 'win':
    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'),
      depfile='$out.d',
      deps=deps)
    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'),
      depfile='$out.d',
      deps=deps)
  else:
    cc_command = ('ninja -t msvc -e $arch ' +
                  '-- '
                  '$cc /nologo /showIncludes /FC '
                  '@$out.rsp /c $in /Fo$out /Fd$pdbname ')
    cxx_command = ('ninja -t msvc -e $arch ' +
                   '-- '
                   '$cxx /nologo /showIncludes /FC '
                   '@$out.rsp /c $in /Fo$out /Fd$pdbname ')
    master_ninja.rule(
      'cc',
      description='CC $out',
      command=cc_command,
      rspfile='$out.rsp',
      rspfile_content='$defines $includes $cflags $cflags_c',
      deps=deps)
    master_ninja.rule(
      'cxx',
      description='CXX $out',
      command=cxx_command,
      rspfile='$out.rsp',
      rspfile_content='$defines $includes $cflags $cflags_cc',
      deps=deps)
    master_ninja.rule(
      'idl',
      description='IDL $in',
      command=('%s gyp-win-tool midl-wrapper $arch $outdir '
               '$tlb $h $dlldata $iid $proxy $in '
               '$idlflags' % sys.executable))
    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' %
               sys.executable))
    master_ninja.rule(
      'asm',
      description='ASM $in',
      command=('%s gyp-win-tool asm-wrapper '
               '$arch $asm $defines $includes /c /Fo $out $in' %
               sys.executable))

  if flavor != 'mac' and flavor != 'win':
    master_ninja.rule(
      'alink',
      description='AR $out',
      command='rm -f $out && $ar rcs $out $in')
    master_ninja.rule(
      'alink_thin',
      description='AR $out',
      command='rm -f $out && $ar rcsT $out $in')

    # 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 -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'}),
      pool='link_pool')
    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'}),
      pool='link_pool')
    master_ninja.rule(
      'link',
      description='LINK $out',
      command=('$ld $ldflags -o $out '
               '-Wl,--start-group $in $solibs -Wl,--end-group $libs'),
      pool='link_pool')
  elif flavor == 'win':
    master_ninja.rule(
        'alink',
        description='LIB $out',
        command=('%s gyp-win-tool link-wrapper $arch '
                 '$ar /nologo /ignore:4221 /OUT:$out @$out.rsp' %
                 sys.executable),
        rspfile='$out.rsp',
        rspfile_content='$in_newline $libflags')
    _AddWinLinkRules(master_ninja, embed_manifest=True, link_incremental=True)
    _AddWinLinkRules(master_ninja, embed_manifest=True, link_incremental=False)
    _AddWinLinkRules(master_ninja, embed_manifest=False, link_incremental=False)
    # Do not generate rules for embed_manifest=False and link_incremental=True
    # because in that case rules for (False, False) should be used (see
    # implementation of _GetWinLinkRuleNameSuffix()).
  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',
      deps=deps)
    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',
      deps=deps)
    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')
    master_ninja.rule(
      'lipo',
      description='LIPO $out, POSTBUILDS',
      command='rm -f $out && lipo -create $in -output $out$postbuilds')

    # Record the public interface of $lib in $lib.TOC. See the corresponding
    # comment in the posix section above for details.
    solink_base = '$ld -shared $ldflags -o $lib %(suffix)s'
    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': solink_base,
            '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).
    solink_suffix = '$in $solibs $libs$postbuilds'
    master_ninja.rule(
      'solink',
      description='SOLINK $lib, POSTBUILDS',
      restat=True,
      command=mtime_preserving_solink_base % {'suffix':solink_suffix},
      pool='link_pool')
    master_ninja.rule(
      'solink_notoc',
      description='SOLINK $lib, POSTBUILDS',
      restat=True,
      command=solink_base % {'suffix':solink_suffix},
      pool='link_pool')

    solink_module_suffix = '$in $solibs $libs$postbuilds'
    master_ninja.rule(
      'solink_module',
      description='SOLINK(module) $lib, POSTBUILDS',
      restat=True,
      command=mtime_preserving_solink_base % {'suffix':solink_module_suffix},
      pool='link_pool')
    master_ninja.rule(
      'solink_module_notoc',
      description='SOLINK(module) $lib, POSTBUILDS',
      restat=True,
      command=solink_base % {'suffix':solink_module_suffix},
      pool='link_pool')

    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 == 'win':
    master_ninja.rule(
      'stamp',
      description='STAMP $out',
      command='%s gyp-win-tool stamp $out' % sys.executable)
    master_ninja.rule(
      'copy',
      description='COPY $in $out',
      command='%s gyp-win-tool recursive-mirror $in $out' % sys.executable)
  else:
    master_ninja.rule(
      'stamp',
      description='STAMP $out',
      command='${postbuilds}touch $out')
    master_ninja.rule(
      'copy',
      description='COPY $in $out',
      command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)')
  master_ninja.newline()

  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 = {}
  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 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')

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

    target = writer.WriteSpec(
        spec, config_name, generator_flags, case_sensitive_filesystem)
    if target:
      if name != target.FinalOutput() and spec['toolset'] == 'target':
        target_short_names.setdefault(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))
    master_ninja.default(generator_flags.get('default_target', '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) == 'win':
    target_list, target_dicts = MSVSUtil.ShardTargets(target_list, target_dicts)
    target_list, target_dicts = MSVSUtil.InsertLargePdbShims(
        target_list, target_dicts, generator_default_variables)

  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)
