# 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 collections
import copy
import hashlib
import json
import multiprocessing
import os.path
import re
import signal
import subprocess
import sys
import gyp
import gyp.common
from gyp.common import OrderedSet
import gyp.msvs_emulation
import gyp.MSVSUtil as MSVSUtil
import gyp.xcode_emulation
from cStringIO import StringIO

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 = []
generator_filelist_paths = None

# 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, order_only=None):
    """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:
      assert not order_only
      return None
    if len(targets) > 1 or order_only:
      stamp = self.GypPathToUniqueOutput(name + '.stamp')
      targets = self.ninja.build(stamp, 'stamp', targets, order_only=order_only)
      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):
    """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))
    # Track if this target contains any C++ files, to decide if gcc or g++
    # should be used for linking.
    self.uses_cpp = False

    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)
      self.ninja.variable('cc_host', '$cl_' + arch)
      self.ninja.variable('cxx_host', '$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(
                OpenOutput(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 = extra_sources + spec.get('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,
          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']
    elif self.flavor == 'mac' and len(self.archs) > 1:
      link_deps = collections.defaultdict(list)


    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 = not link_deps and not mac_bundle_depends
    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, 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.HasExplicitIdlRulesOrActions(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 = []
    if self.is_mac_bundle:
      mac_bundle_resources = spec.get('mac_bundle_resources', [])[:]
    else:
      mac_bundle_resources = []
    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,
                                 mac_bundle_resources,
                                 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:
      self.WriteMacBundleResources(
          extra_mac_bundle_resources + 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.GetToolchainEnv()
    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']
      pool = 'console' if int(action.get('ninja_use_console', 0)) else None
      rule_name, _ = self.WriteNewNinjaRule(name, args, description,
                                            is_cygwin, env, pool)

      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,
                 mac_bundle_resources, extra_mac_bundle_resources):
    env = self.GetToolchainEnv()
    all_outputs = []
    for rule in rules:
      # Skip a rule with no action and no inputs.
      if 'action' not in rule and not rule.get('rule_sources', []):
        continue

      # First write out a rule for the rule action.
      name = '%s_%s' % (rule['rule_name'],
                        hashlib.md5(self.qualified_target).hexdigest())

      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)
      pool = 'console' if int(rule.get('ninja_use_console', 0)) else None
      rule_name, args = self.WriteNewNinjaRule(
          name, args, description, is_cygwin, env, pool)

      # 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

      inputs = [self.GypPathToNinja(i, env) for i in rule.get('inputs', [])]

      # If there are n source files matching the rule, and m additional rule
      # inputs, then adding 'inputs' to each build edge written below will
      # write m * n inputs. Collapsing reduces this to m + n.
      sources = rule.get('rule_sources', [])
      num_inputs = len(inputs)
      if prebuild:
        num_inputs += 1
      if num_inputs > 2 and len(sources) > 2:
        inputs = [self.WriteCollapsedDependencies(
          rule['rule_name'], inputs, order_only=prebuild)]
        prebuild = []

      # For each source file, write an edge that generates all the outputs.
      for source in 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']]

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

        was_mac_bundle_resource = source in mac_bundle_resources
        if was_mac_bundle_resource or \
            int(rule.get('process_outputs_as_mac_bundle_resources', False)):
          extra_mac_bundle_resources += outputs
          # Note: This is n_resources * n_outputs_in_rule.  Put to-be-removed
          # items in a set and remove them all in a single pass if this becomes
          # a performance issue.
          if was_mac_bundle_resource:
            mac_bundle_resources.remove(source)

        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)

        outputs = [self.GypPathToNinja(o, env) for o in outputs]
        if self.flavor == 'win':
          # WriteNewNinjaRule uses unique_name for creating an rsp file on win.
          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.GetToolchainEnv()
    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, 'preprocess_infoplist', info_plist,
          variables=[('defines',defines)])

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

    keys = self.xcode_settings.GetExtraPlistItems(self.config_name)
    keys = QuoteShellArgument(json.dumps(keys), self.flavor)
    self.ninja.build(out, 'copy_infoplist', info_plist,
                     variables=[('env', env), ('keys', keys)])
    bundle_depends.append(out)

  def WriteSources(self, ninja_file, 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')
      self.ninja.variable('ldxx', '$ldxx_host')

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

  def WriteSourcesForArch(self, ninja_file, config_name, config, sources,
                          predepends, precompiled_header, 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':
      asmflags = self.msvs_settings.GetAsmflags(config_name)
      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)
      # See comment at cc_command for why there's two .pdb files.
      pdbpath_c = pdbpath_cc = self.msvs_settings.GetCompilerPdbName(
          config_name, self.ExpandSpecial)
      if not pdbpath_c:
        obj = 'obj'
        if self.toolset != 'target':
          obj += '.' + self.toolset
        pdbpath = os.path.normpath(os.path.join(obj, self.base_dir, self.name))
        pdbpath_c = pdbpath + '.c.pdb'
        pdbpath_cc = pdbpath + '.cc.pdb'
      self.WriteVariableList(ninja_file, 'pdbname_c', [pdbpath_c])
      self.WriteVariableList(ninja_file, 'pdbname_cc', [pdbpath_cc])
      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, 'asmflags',
                             map(self.ExpandSpecial, asmflags))
      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', [])

    env = self.GetToolchainEnv()
    if self.flavor == 'win':
      include_dirs = self.msvs_settings.AdjustIncludeDirs(include_dirs,
                                                          config_name)
    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 = []
    has_rc_source = False
    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'
        self.uses_cpp = True
      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'
        self.uses_cpp = True
      elif self.flavor == 'win' and ext == 'rc':
        command = 'rc'
        obj_ext = '.res'
        has_rc_source = True
      else:
        # Ignore unhandled extensions.
        continue
      input = self.GypPathToNinja(source)
      output = self.GypPathToUniqueOutput(filename + obj_ext)
      if arch is not None:
        output = AddArch(output, arch)
      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)

    if has_rc_source:
      resource_include_dirs = config.get('resource_include_dirs', include_dirs)
      self.WriteVariableList(ninja_file, 'resource_includes',
          [QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor)
           for i in resource_include_dirs])

    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:
          new_deps = []
          if (self.flavor == 'win' and
              target.component_objs and
              self.msvs_settings.IsUseLibraryDependencyInputs(config_name)):
            new_deps = target.component_objs
          elif self.flavor == 'win' and target.import_lib:
            new_deps = [target.import_lib]
          elif target.UsesToc(self.flavor):
            solibs.add(target.binary)
            implicit_deps.add(target.binary + '.TOC')
          else:
            new_deps = [target.binary]
          for new_dep in new_deps:
            if new_dep not in extra_link_deps:
              extra_link_deps.add(new_dep)
              link_deps.append(new_dep)

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

    extra_bindings = []
    if self.uses_cpp and self.flavor != 'win':
      extra_bindings.append(('ld', '$ldxx'))

    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'
    # The ldflags config key is not used on mac or win. On those platforms
    # linker flags are set via xcode_settings and msvs_settings, respectively.
    env_ldflags = os.environ.get('LDFLAGS', '').split()
    if self.flavor == 'mac':
      ldflags = self.xcode_settings.GetLdflags(config_name,
          self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
          self.GypPathToNinja, arch)
      ldflags = env_ldflags + ldflags
    elif self.flavor == 'win':
      manifest_base_name = self.GypPathToUniqueOutput(
          self.ComputeOutputFileName(spec))
      ldflags, intermediate_manifest, manifest_files = \
          self.msvs_settings.GetLdflags(config_name, self.GypPathToNinja,
                                        self.ExpandSpecial, manifest_base_name,
                                        output, is_executable,
                                        self.toplevel_build)
      ldflags = env_ldflags + ldflags
      self.WriteVariableList(ninja_file, 'manifests', manifest_files)
      implicit_deps = implicit_deps.union(manifest_files)
      if intermediate_manifest:
        self.WriteVariableList(
            ninja_file, 'intermediatemanifest', [intermediate_manifest])
      command_suffix = _GetWinLinkRuleNameSuffix(
          self.msvs_settings.IsEmbedManifest(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 = env_ldflags + 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 = ['/LIBPATH:' + QuoteShellArgument(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, config_name)
    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':
        link_file_list = output
        if self.is_mac_bundle:
          # 'Dependency Framework.framework/Versions/A/Dependency Framework' ->
          # 'Dependency Framework.framework.rsp'
          link_file_list = self.xcode_settings.GetWrapperName()
        if arch:
          link_file_list += '.' + arch
        link_file_list += '.rsp'
        # If an rspfile contains spaces, ninja surrounds the filename with
        # quotes around it and then passes it to open(), creating a file with
        # quotes in its name (and when looking for the rsp file, the name
        # makes it through bash which strips the quotes) :-/
        link_file_list = link_file_list.replace(' ', '_')
        extra_bindings.append(
          ('link_file_list',
            gyp.common.EncodePOSIXShellArgument(link_file_list)))
      if self.flavor == 'win':
        extra_bindings.append(('binary', output))
        if '/NOENTRY' not in ldflags:
          self.target.import_lib = output + '.lib'
          extra_bindings.append(('implibflag',
                                 '/IMPLIB:%s' % self.target.import_lib))
          pdbname = self.msvs_settings.GetPDBName(
              config_name, self.ExpandSpecial, output + '.pdb')
          output = [output, self.target.import_lib]
          if pdbname:
            output.append(pdbname)
      elif not self.is_mac_bundle:
        output = [output, output + '.TOC']
      else:
        command = command + '_notoc'
    elif self.flavor == 'win':
      extra_bindings.append(('binary', output))
      pdbname = self.msvs_settings.GetPDBName(
          config_name, self.ExpandSpecial, output + '.pdb')
      if pdbname:
        output = [output, pdbname]


    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):
    extra_link_deps = any(self.target_outputs.get(dep).Linkable()
                          for dep in spec.get('dependencies', [])
                          if dep in self.target_outputs)
    if spec['type'] == 'none' or (not link_deps and not extra_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
      self.target.type = 'none'
    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 GetToolchainEnv(self, additional_settings=None):
    """Returns the variables toolchain would set for build steps."""
    env = self.GetSortedXcodeEnv(additional_settings=additional_settings)
    if self.flavor == 'win':
      env = self.GetMsvsToolchainEnv(
          additional_settings=additional_settings)
    return env

  def GetMsvsToolchainEnv(self, additional_settings=None):
    """Returns the variables Visual Studio would set for build steps."""
    return self.msvs_settings.GetVSMacroEnv('$!PRODUCT_DIR',
                                             config=self.config_name)

  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)
    postbuilds = gyp.xcode_emulation.GetSpecPostbuildCommands(spec, quiet=True)
    if output_binary is not None:
      postbuilds = self.xcode_settings.AddImplicitPostbuilds(
          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),
          postbuilds, quiet=True)

    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, pool):
    """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, pool=pool,
                    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'

    # 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', [])

    gyp.msvs_emulation.CalculateCommonVariables(default_variables, params)
  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 ComputeOutputDir(params):
  """Returns the path from the toplevel_dir to the build output directory."""
  # 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 = params.get('generator_flags', {}).get('output_dir', 'out')

  # Relative path from source root to our output files.  e.g. "out"
  return os.path.normpath(os.path.join(generator_dir, output_dir))


def CalculateGeneratorInputInfo(params):
  """Called by __init__ to initialize generator values based on params."""
  # E.g. "out/gypfiles"
  toplevel = params['options'].toplevel_dir
  qualified_out_dir = os.path.normpath(os.path.join(
      toplevel, ComputeOutputDir(params), 'gypfiles'))

  global generator_filelist_paths
  generator_filelist_paths = {
      'toplevel': toplevel,
      'qualified_out_dir': qualified_out_dir,
  }


def OpenOutput(path, mode='w'):
  """Open |path| for writing, creating directories if necessary."""
  gyp.common.EnsureDirExists(path)
  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."""
  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))

    mem_limit = max(1, stat.ullTotalPhys / (4 * (2 ** 30)))  # total / 4GB
    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 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):
  """Returns the suffix used to select an appropriate linking rule depending on
  whether the manifest embedding is enabled."""
  return '_embed' if embed_manifest else ''


def _AddWinLinkRules(master_ninja, embed_manifest):
  """Adds link rules for Windows platform to |master_ninja|."""
  def FullLinkCommand(ldcmd, out, binary_type):
    resource_name = {
      'exe': '1',
      'dll': '2',
    }[binary_type]
    return '%(python)s gyp-win-tool link-with-manifests $arch %(embed)s ' \
           '%(out)s "%(ldcmd)s" %(resname)s $mt $rc "$intermediatemanifest" ' \
           '$manifests' % {
               'python': sys.executable,
               'out': out,
               'ldcmd': ldcmd,
               'resname': resource_name,
               'embed': embed_manifest }
  rule_name_suffix = _GetWinLinkRuleNameSuffix(embed_manifest)
  use_separate_mspdbsrv = (
      int(os.environ.get('GYP_USE_SEPARATE_MSPDBSRV', '0')) != 0)
  dlldesc = 'LINK%s(DLL) $binary' % rule_name_suffix.upper()
  dllcmd = ('%s gyp-win-tool link-wrapper $arch %s '
            '$ld /nologo $implibflag /DLL /OUT:$binary '
            '@$binary.rsp' % (sys.executable, use_separate_mspdbsrv))
  dllcmd = FullLinkCommand(dllcmd, '$binary', 'dll')
  master_ninja.rule('solink' + rule_name_suffix,
                    description=dlldesc, command=dllcmd,
                    rspfile='$binary.rsp',
                    rspfile_content='$libs $in_newline $ldflags',
                    restat=True,
                    pool='link_pool')
  master_ninja.rule('solink_module' + rule_name_suffix,
                    description=dlldesc, command=dllcmd,
                    rspfile='$binary.rsp',
                    rspfile_content='$libs $in_newline $ldflags',
                    restat=True,
                    pool='link_pool')
  # 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 %s '
             '$ld /nologo /OUT:$binary @$binary.rsp' %
              (sys.executable, use_separate_mspdbsrv))
  exe_cmd = FullLinkCommand(exe_cmd, '$binary', 'exe')
  master_ninja.rule('link' + rule_name_suffix,
                    description='LINK%s $binary' % rule_name_suffix.upper(),
                    command=exe_cmd,
                    rspfile='$binary.rsp',
                    rspfile_content='$in_newline $libs $ldflags',
                    pool='link_pool')


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

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

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

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

  # 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':
    ar = 'lib.exe'
    # cc and cxx must be set to the correct architecture by overriding with one
    # of cl_x86 or cl_x64 below.
    cc = 'UNSET'
    cxx = 'UNSET'
    ld = 'link.exe'
    ld_host = '$ld'
  else:
    ar = 'ar'
    cc = 'cc'
    cxx = 'c++'
    ld = '$cc'
    ldxx = '$cxx'
    ld_host = '$cc_host'
    ldxx_host = '$cxx_host'

  ar_host = 'ar'
  cc_host = None
  cxx_host = None
  cc_host_global_setting = None
  cxx_host_global_setting = None
  clang_cl = 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 == 'AR':
      ar = os.path.join(build_to_root, value)
    if key == 'AR.host':
      ar_host = os.path.join(build_to_root, value)
    if key == 'CC':
      cc = os.path.join(build_to_root, value)
      if cc.endswith('clang-cl'):
        clang_cl = cc
    if key == 'CXX':
      cxx = 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':
      ld = os.path.join(build_to_root, 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':
    configs = [target_dicts[qualified_target]['configurations'][config_name]
               for qualified_target in target_list]
    shared_system_includes = None
    if not generator_flags.get('ninja_use_custom_environment_files', 0):
      shared_system_includes = \
          gyp.msvs_emulation.ExtractSharedMSVSSystemIncludes(
              configs, generator_flags)
    cl_paths = gyp.msvs_emulation.GenerateEnvironmentFiles(
        toplevel_build, generator_flags, shared_system_includes, OpenOutput)
    for arch, path in cl_paths.iteritems():
      if clang_cl:
        # If we have selected clang-cl, use that instead.
        path = clang_cl
      command = CommandWithWrapper('CC', wrappers,
          QuoteShellArgument(path, 'win'))
      if clang_cl:
        # Use clang-cl to cross-compile for x86 or x86_64.
        command += (' -m32' if arch == 'x86' else ' -m64')
      master_ninja.variable('cl_' + arch, command)

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

  if flavor == 'win':
    master_ninja.variable('ld', ld)
    master_ninja.variable('idl', 'midl.exe')
    master_ninja.variable('ar', ar)
    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('ldxx', CommandWithWrapper('LINK', wrappers, ldxx))
    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_host))
    cc_host = GetEnvironFallback(['CC_host'], cc_host)
    cxx_host = GetEnvironFallback(['CXX_host'], cxx_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.variable('ldxx_host', CommandWithWrapper(
          'LINK', wrappers, ldxx_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:
    # TODO(scottmg) Separate pdb names is a test to see if it works around
    # http://crbug.com/142362. It seems there's a race between the creation of
    # the .pdb by the precompiled header step for .cc and the compilation of
    # .c files. This should be handled by mspdbsrv, but rarely errors out with
    #   c1xx : fatal error C1033: cannot open program database
    # By making the rules target separate pdb files this might be avoided.
    cc_command = ('ninja -t msvc -e $arch ' +
                  '-- '
                  '$cc /nologo /showIncludes /FC '
                  '@$out.rsp /c $in /Fo$out /Fd$pdbname_c ')
    cxx_command = ('ninja -t msvc -e $arch ' +
                   '-- '
                   '$cxx /nologo /showIncludes /FC '
                   '@$out.rsp /c $in /Fo$out /Fd$pdbname_cc ')
    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 $resource_includes $rcflags /fo$out $in' %
               sys.executable))
    master_ninja.rule(
      'asm',
      description='ASM $out',
      command=('%s gyp-win-tool asm-wrapper '
               '$arch $asm $defines $includes $asmflags /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': '@$link_file_list'},
      rspfile='$link_file_list',
      rspfile_content=
          '-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': '@$link_file_list'},
      rspfile='$link_file_list',
      rspfile_content='-Wl,--start-group $in -Wl,--end-group $solibs $libs',
      pool='link_pool')
    master_ninja.rule(
      'link',
      description='LINK $out',
      command=('$ld $ldflags -o $out '
               '-Wl,--start-group $in -Wl,--end-group $solibs $libs'),
      pool='link_pool')
  elif flavor == 'win':
    master_ninja.rule(
        'alink',
        description='LIB $out',
        command=('%s gyp-win-tool link-wrapper $arch False '
                 '$ar /nologo /ignore:4221 /OUT:$out @$out.rsp' %
                 sys.executable),
        rspfile='$out.rsp',
        rspfile_content='$in_newline $libflags')
    _AddWinLinkRules(master_ninja, embed_manifest=True)
    _AddWinLinkRules(master_ninja, embed_manifest=False)
  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 %(type)s $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; }'})


    solink_suffix = '@$link_file_list$postbuilds'
    master_ninja.rule(
      'solink',
      description='SOLINK $lib, POSTBUILDS',
      restat=True,
      command=mtime_preserving_solink_base % {'suffix': solink_suffix,
                                              'type': '-shared'},
      rspfile='$link_file_list',
      rspfile_content='$in $solibs $libs',
      pool='link_pool')
    master_ninja.rule(
      'solink_notoc',
      description='SOLINK $lib, POSTBUILDS',
      restat=True,
      command=solink_base % {'suffix':solink_suffix, 'type': '-shared'},
      rspfile='$link_file_list',
      rspfile_content='$in $solibs $libs',
      pool='link_pool')

    master_ninja.rule(
      'solink_module',
      description='SOLINK(module) $lib, POSTBUILDS',
      restat=True,
      command=mtime_preserving_solink_base % {'suffix': solink_suffix,
                                              'type': '-bundle'},
      rspfile='$link_file_list',
      rspfile_content='$in $solibs $libs',
      pool='link_pool')
    master_ninja.rule(
      'solink_module_notoc',
      description='SOLINK(module) $lib, POSTBUILDS',
      restat=True,
      command=solink_base % {'suffix': solink_suffix, 'type': '-bundle'},
      rspfile='$link_file_list',
      rspfile_content='$in $solibs $libs',
      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(
      'preprocess_infoplist',
      description='PREPROCESS INFOPLIST $out',
      command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && '
               'plutil -convert xml1 $out $out'))
    master_ninja.rule(
      'copy_infoplist',
      description='COPY INFOPLIST $in',
      command='$env ./gyp-mac-tool copy-info-plist $in $out $keys')
    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. %s vs. %s" %
        (this_make_global_settings, make_global_settings))

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

    ninja_output = StringIO()
    writer = NinjaWriter(qualified_target, target_outputs, base_path, build_dir,
                         ninja_output,
                         toplevel_build, output_file,
                         flavor, toplevel_dir=options.toplevel_dir)

    target = writer.WriteSpec(spec, config_name, generator_flags)

    if ninja_output.tell() > 0:
      # Only create files for ninja files that actually have contents.
      with OpenOutput(os.path.join(toplevel_build, output_file)) as ninja_file:
        ninja_file.write(ninja_output.getvalue())
      ninja_output.close()
      master_ninja.subninja(output_file)

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

  master_ninja_file.close()


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):
  # Update target_dicts for iOS device builds.
  target_dicts = gyp.xcode_emulation.CloneConfigurationForDeviceAndEmulator(
      target_dicts)

  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)
