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

import copy
import hashlib
import multiprocessing
import os.path
import pipes
import platform
import re
import signal
import subprocess
import sys

from cobalt.build import config

import gyp
import gyp.common

# TODO: These should be replaced with calls to the abstract tool chain, when it
# is implemented on all supported platforms.
from gyp.msvs_emulation import EncodeRspFileList
from gyp.msvs_emulation import GenerateEnvironmentFiles
from gyp.msvs_emulation import MsvsSettings
import gyp.MSVSUtil as MSVSUtil
import gyp.xcode_emulation

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

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

from starboard.tools.toolchain import abstract

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_supports_multiple_toolsets = True

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

microsoft_flavors = ['win', 'win-win32', 'win-win32-lib', 'xb1', 'xb1-future']
sony_flavors = ['ps3', 'ps4']
windows_host_flavors = microsoft_flavors + sony_flavors


def GetToolchainOrNone(flavor):
  return config.GetPlatformConfig(flavor).GetToolchain()


def GetTargetToolchain(flavor):
  return config.GetPlatformConfig(flavor).GetTargetToolchain()


def GetHostToolchain(flavor):
  return config.GetPlatformConfig(flavor).GetHostToolchain()


def FindFirstInstanceOf(type, instances):
  try:
    return (instance for instance in instances
            if isinstance(instance, type)).next()
  except StopIteration:
    return None


def GetNinjaRuleName(tool, toolset):
  if tool.IsPlatformAgnostic() or toolset == 'target':
    return tool.GetRuleName()
  return '{0}_{1}'.format(tool.GetRuleName(), toolset)


def GetConfigFlags(config, toolset, keyword):
  flags = config.get(keyword, [])
  if toolset == 'host':
    flags = config.get('{0}_host'.format(keyword), flags)
  return flags


def JoinShellArguments(shell, arguments):
  return ' '.join(shell.MaybeQuoteArgument(argument) for argument in arguments)


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 GetToolchainOrNone(flavor):
    return GetToolchainOrNone(flavor).QuoteForRspFile(arg)
  elif flavor in sony_flavors:
    # Escape double quotes.
    return '"' + arg.replace('\"', '\\\"') + '"'
  return "'" + arg.replace("'", "'" + '"\'"' + "'") + "'"


def Define(d, flavor):
  """Takes a preprocessor define and returns a -D parameter that's ninja- and
  shell-escaped."""

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


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

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

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


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

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

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

  (Any of these steps can be optional.)

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

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

  This object stores those paths.  To keep things simple, member
  variables only store concrete paths to single files, while methods
  compute derived values like "the last output of the target".
  """

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

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

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

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

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

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


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


class NinjaWriter:

  def __init__(self,
               qualified_target,
               target_outputs,
               base_dir,
               build_dir,
               output_file,
               flavor,
               case_sensitive_filesystem,
               abs_build_dir=None):
    """base_dir: path from source root to directory containing this gyp file,

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

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

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

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

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

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

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

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

    return path

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

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

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

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

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

    return self.GypPathCaseCorrection(path)

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

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

    See the above discourse on path conversions."""

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

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

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

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

    return self.GypPathCaseCorrection(path)

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

    Uses a stamp file if necessary."""

    assert targets == filter(None, targets), targets
    if len(targets) == 0:
      return None
    if len(targets) == 1:
      return targets[0]

    try:
      assert FindFirstInstanceOf(abstract.Stamp, GetHostToolchain(
          self.flavor)), 'Host toolchain must provide stamp tool.'
    except NotImplementedError:
      # Fall back to the legacy toolchain.
      pass

    stamp_output = self.GypPathToUniqueOutput(name + '.stamp')
    self.ninja.build(stamp_output, 'stamp', targets)
    self.ninja.newline()
    return stamp_output

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

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

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

    self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec)
    self.xcode_settings = None
    if self.flavor == 'mac':
      self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec)
    if (self.flavor in windows_host_flavors and is_windows):
      if self.flavor in sony_flavors:
        self.msvs_settings = gyp.msvs_emulation.MsvsSettings(
            spec, generator_flags)
        arch = self.msvs_settings.GetArch(config_name)
      else:
        GetToolchainOrNone(self.flavor).InitCompilerSettings(
            spec, **{'generator_flags': generator_flags})
        arch = GetToolchainOrNone(
            self.flavor).GetCompilerSettings().GetArch(config_name)
      self.ninja.variable('arch', self.win_env[arch])
      None

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

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

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

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

    if (self.flavor in microsoft_flavors and
        self.target.type == 'static_library'):
      self.target.component_objs = link_deps

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

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

    if not output:
      return None

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

  def _WinIdlRule(self, source, prebuild, outputs):
    """Handle the implicit VS .idl rule for one source file. Fills |outputs|
    with files that are generated."""
    outdir, output, vars, flags = GetToolchainOrNone(
        self.flavor).GetCompilerSettings().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 GetToolchainOrNone(self.flavor)
    if GetToolchainOrNone(
        self.flavor).GetCompilerSettings().HasExplicitIdlRules(spec):
      return []
    outputs = []
    for source in filter(lambda x: x.endswith('.idl'), spec['sources']):
      self._WinIdlRule(source, prebuild, outputs)
    return outputs

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

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

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

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

    return stamp

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

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

  def IsCygwinRule(self, action):
    if self.flavor in sony_flavors:
      return str(action.get('msvs_cygwin_shell', 1)) != '0'
    return False

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

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

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

      self.ninja.newline()

    return all_outputs

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

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

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

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

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

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

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

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

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

        all_outputs.extend(outputs)

    return all_outputs

  def WriteCopy(self, src, dst, prebuild, env, mac_bundle_depends):
    try:
      assert FindFirstInstanceOf(abstract.Copy, GetHostToolchain(
          self.flavor)), 'Host toolchain must provide copy tool.'
    except NotImplementedError:
      # Fall back to the legacy toolchain.
      pass

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

    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 [dst]

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

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

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

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

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

    return outputs

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

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

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

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

  def WriteSources(self, config_name, config, sources, predepends,
                   precompiled_header, spec):
    """Write build rules to compile all of |sources|."""

    try:
      shell = FindFirstInstanceOf(abstract.Shell, GetHostToolchain(self.flavor))
      assert shell, 'Host toolchain must provide shell.'

      if self.toolset == 'target':
        toolchain = GetTargetToolchain(self.flavor)
      else:
        toolchain = GetHostToolchain(self.flavor)

      defines = config.get('defines', [])
      include_dirs = [
          self.GypPathToNinja(include_dir)
          for include_dir in config.get('include_dirs', [])
      ]

      # TODO: This code emulates legacy toolchain behavior. We need to migrate
      #       to single-responsibility, toolchain-independent GYP keywords as
      #       per abstract toolchain design doc.
      cflags = GetConfigFlags(config, self.toolset, 'cflags')
      cflags_c = GetConfigFlags(config, self.toolset, 'cflags_c')
      cflags_cc = GetConfigFlags(config, self.toolset, 'cflags_cc')

      c_compiler = FindFirstInstanceOf(abstract.CCompiler, toolchain)
      if c_compiler:
        c_compiler_flags = c_compiler.GetFlags(defines, include_dirs,
                                               cflags + cflags_c)
        self.ninja.variable(
            '{0}_flags'.format(GetNinjaRuleName(c_compiler, self.toolset)),
            JoinShellArguments(shell, c_compiler_flags))

      cxx_compiler = FindFirstInstanceOf(abstract.CxxCompiler, toolchain)
      if cxx_compiler:
        cxx_compiler_flags = cxx_compiler.GetFlags(defines, include_dirs,
                                                   cflags + cflags_cc)
        self.ninja.variable(
            '{0}_flags'.format(GetNinjaRuleName(cxx_compiler, self.toolset)),
            JoinShellArguments(shell, cxx_compiler_flags))

      assembler = FindFirstInstanceOf(abstract.AssemblerWithCPreprocessor,
                                      toolchain)
      if assembler:
        assembler_flags = assembler.GetFlags(defines, include_dirs,
                                             cflags + cflags_c)
        self.ninja.variable(
            '{0}_flags'.format(GetNinjaRuleName(assembler, self.toolset)),
            JoinShellArguments(shell, assembler_flags))

      self.ninja.newline()

      outputs = []
      for source in sources:
        _, extension = os.path.splitext(source)
        if extension in ['.c']:
          assert c_compiler, ('Toolchain must provide C compiler in order to '
                              'build {0} for {1} platform.').format(
                                  source, self.toolset)
          rule_name = GetNinjaRuleName(c_compiler, self.toolset)
        elif extension in ['.cc', '.cpp', '.cxx']:
          assert cxx_compiler, ('Toolchain must provide C++ compiler in order '
                                'to build {0} for {1} platform.').format(
                                    source, self.toolset)
          rule_name = GetNinjaRuleName(cxx_compiler, self.toolset)
        elif extension in ['.S', '.s']:
          assert assembler, ('Toolchain must provide assembler in order to '
                             'build {0} for {1} platform.').format(
                                 source, self.toolset)
          rule_name = GetNinjaRuleName(assembler, self.toolset)
        else:
          rule_name = None

        if rule_name:
          input = self.GypPathToNinja(source)
          output = '{0}.o'.format(self.GypPathToUniqueOutput(source))
          self.ninja.build(
              output,
              rule_name,
              input,
              implicit=None,  # TODO: Implemenet precompiled headers.
              order_only=predepends)
          outputs.append(output)

    except NotImplementedError:
      # Fall back to the legacy toolchain.

      if self.toolset == 'host':
        self.ninja.variable('ar', '$ar_host')
        self.ninja.variable('cc', '$cc_host')
        self.ninja.variable('cxx', '$cxx_host')
        self.ninja.variable('ld', '$ld_host')

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

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

      defines = config.get('defines', []) + extra_defines
      if GetToolchainOrNone(self.flavor):
        self.WriteVariableList('defines', [
            GetToolchainOrNone(self.flavor).Define(d) for d in defines
        ])
      else:
        self.WriteVariableList('defines',
                               [Define(d, self.flavor) for d in defines])
      if GetToolchainOrNone(self.flavor):
        self.WriteVariableList('rcflags', [
            QuoteShellArgument(self.ExpandSpecial(f), self.flavor)
            for f in GetToolchainOrNone(self.flavor).GetCompilerSettings()
            .GetRcFlags(config_name, self.GypPathToNinja)
        ])

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

      if GetToolchainOrNone(self.flavor):
        include_dirs = GetToolchainOrNone(
            self.flavor).GetCompilerSettings().ProcessIncludeDirs(
                include_dirs, config_name)
        self.WriteVariableList('includes', [
            '/I' + GetToolchainOrNone(self.flavor).QuoteForRspFile(
                self.GypPathToNinja(i)) for i in include_dirs
        ])
      else:
        self.WriteVariableList('includes', [
            QuoteShellArgument('-I' + self.GypPathToNinja(i), self.flavor)
            for i in include_dirs
        ])

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

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

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

      if self.flavor == 'mac':
        self.WriteVariableList('cflags_objc',
                               map(self.ExpandSpecial, cflags_objc))
        self.WriteVariableList('cflags_objcc',
                               map(self.ExpandSpecial, cflags_objcc))
      self.ninja.newline()

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

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

      self.WritePchTargets(pch_commands)

    self.ninja.newline()
    return outputs

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

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

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

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

    try:
      if self.toolset == 'target':
        toolchain = GetTargetToolchain(self.flavor)
      else:
        toolchain = GetHostToolchain(self.flavor)

      shell = FindFirstInstanceOf(abstract.Shell, GetHostToolchain(self.flavor))
      assert shell, 'Host toolchain must provide shell.'

      target_type = spec['type']
      if target_type == 'executable':
        executable_linker = FindFirstInstanceOf(abstract.ExecutableLinker,
                                                toolchain)
        assert executable_linker, ('Toolchain must provide executable linker '
                                   'for {0} platform.').format(self.toolset)

        rule_name = GetNinjaRuleName(executable_linker, self.toolset)

        # TODO: This code emulates legacy toolchain behavior. We need to migrate
        #       to single-responsibility, toolchain-independent GYP keywords as
        #       per abstract toolchain design doc.
        libraries_keyword = 'libraries{0}'.format('_host' if self.toolset ==
                                                  'host' else '')
        libraries = spec.get(libraries_keyword, []) + config.get(
            libraries_keyword, [])
        ldflags = gyp.common.uniquer(
            map(self.ExpandSpecial,
                GetConfigFlags(config, self.toolset, 'ldflags') + libraries))

        executable_linker_flags = executable_linker.GetFlags(ldflags)
        self.ninja.variable('{0}_flags'.format(rule_name),
                            JoinShellArguments(shell, executable_linker_flags))
      else:
        raise Exception('Target type {0} is not supported.'.format(target_type))

      order_only_deps = set()

      if 'dependencies' in spec:
        # Two kinds of dependencies:
        # - Linkable dependencies (like a .a or a .so): add them to the link
        #   line.
        # - Non-linkable dependencies (like a rule that generates a file
        #   and writes a stamp file): add them to implicit_deps or
        #   order_only_deps
        extra_link_deps = []
        for dep in spec['dependencies']:
          target = self.target_outputs.get(dep)
          if not target:
            continue
          linkable = target.Linkable()
          if linkable:
            extra_link_deps.append(target.binary)

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

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

        link_deps.extend(extra_link_deps)

      output = self.ComputeOutput(spec)
      self.target.binary = output

      self.ninja.build(
          output, rule_name, link_deps, order_only=list(order_only_deps))

    except NotImplementedError:
      # Fall back to the legacy toolchain.

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

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

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

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

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

        link_deps.extend(extra_link_deps)

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

      if self.flavor == 'mac':
        ldflags = self.xcode_settings.GetLdflags(
            config_name,
            self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
            self.GypPathToNinja)
      elif GetToolchainOrNone(self.flavor):
        libflags = GetToolchainOrNone(
            self.flavor).GetCompilerSettings().GetLibFlags(
                config_name, self.GypPathToNinja)
        self.WriteVariableList(
            'libflags', gyp.common.uniquer(map(self.ExpandSpecial, libflags)))
        is_executable = spec['type'] == 'executable'
        manifest_name = self.GypPathToUniqueOutput(
            self.ComputeOutputFileName(spec))
        ldflags, manifest_files = GetToolchainOrNone(
            self.flavor).GetCompilerSettings().GetLdFlags(
                config_name, **{
                    'gyp_path_to_ninja': self.GypPathToNinja,
                    'expand_special': self.ExpandSpecial,
                    'manifest_name': manifest_name,
                    'is_executable': is_executable
                })
        self.WriteVariableList('manifests', manifest_files)
      else:
        ldflags = config.get('ldflags', [])
        ldflags_host = config.get('ldflags_host', ldflags)

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

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

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

      if self.flavor == 'mac':
        libraries = self.xcode_settings.AdjustLibraries(libraries)
      elif GetToolchainOrNone(self.flavor):
        libraries = GetToolchainOrNone(
            self.flavor).GetCompilerSettings().ProcessLibraries(libraries)
      self.WriteVariableList('libs', libraries)

      self.target.binary = output

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

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

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

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

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

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

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

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

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

  def WriteTarget(self, spec, config_name, config, link_deps, compile_deps):
    if spec['type'] == 'none':
      # TODO(evan): don't call this function for 'none' target types, as
      # it doesn't do anything, and we fake out a 'binary' with a stamp file.
      self.target.binary = compile_deps
    elif spec['type'] == 'static_library':
      self.target.binary = self.ComputeOutput(spec)
      variables = []

      try:
        if self.toolset == 'target':
          toolchain = GetTargetToolchain(self.flavor)
        else:
          toolchain = GetHostToolchain(self.flavor)

        static_linker = FindFirstInstanceOf(abstract.StaticLinker, toolchain)
        if not self.is_standalone_static_library:
          static_thin_linker = FindFirstInstanceOf(abstract.StaticThinLinker,
                                                   toolchain)
          if static_thin_linker:
            static_linker = static_thin_linker
        assert static_linker, ('Toolchain must provide static linker in order '
                               'to build {0} for {1} platform.').format(
                                   self.target.binary, self.toolset)

        rule_name = GetNinjaRuleName(static_linker, self.toolset)
      except NotImplementedError:
        # Fall back to the legacy toolchain.

        if GetToolchainOrNone(self.flavor):
          libflags = GetToolchainOrNone(
              self.flavor).GetCompilerSettings().GetLibFlags(
                  config_name, self.GypPathToNinja)
          # TODO: Starboardize libflags vs libtool_flags.
          variables.append(('libflags', ' '.join(libflags)))
        postbuild = self.GetPostbuildCommand(spec, self.target.binary,
                                             self.target.binary)
        if postbuild:
          variables.append(('postbuilds', postbuild))
        if self.xcode_settings:
          variables.append(('libtool_flags',
                            self.xcode_settings.GetLibtoolflags(config_name)))
        # TODO: Starboardize.
        if (self.flavor not in (['mac'] + microsoft_flavors) and
            not self.is_standalone_static_library):
          rule_name = 'alink_thin'
        else:
          rule_name = 'alink'
        if self.toolset != 'target':
          rule_name += '_' + self.toolset

      self.ninja.build(
          self.target.binary,
          rule_name,
          link_deps,
          order_only=compile_deps,
          variables=variables)
    else:
      self.WriteLink(spec, config_name, config, link_deps)
    return self.target.binary

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

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

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

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

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

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

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

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

    default_variables = copy.copy(generator_default_variables)
    if GetToolchainOrNone(self.flavor):
      GetToolchainOrNone(
          self.flavor).SetAdditionalGypVariables(default_variables)
    else:
      CalculateVariables(default_variables, {'flavor': self.flavor})

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

    # Compute filename extension: the product extension, or a default
    # for the product type.
    DEFAULT_EXTENSION = {
        'loadable_module': default_variables['SHARED_LIB_SUFFIX'],
        'shared_library': default_variables['SHARED_LIB_SUFFIX'],
        'static_library': default_variables['STATIC_LIB_SUFFIX'],
        'executable': default_variables['EXECUTABLE_SUFFIX'],
    }
    extension = spec.get('product_extension')
    if extension:
      extension = '.' + extension
    elif self.toolset == 'host':
      # TODO: Based on a type of target, ask a corresponding
      #       tool from a toolchain to compute the file name.
      if is_windows:
        extension = '.exe'
      else:
        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, type=None):
    """Compute the path for the final output of the spec."""
    assert not self.is_mac_bundle or type

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return rule_name, args


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

    # Copy additional generator configuration data from Xcode, which is shared
    # by the Mac Ninja generator.
    import gyp.generator.xcode as xcode_generator
    generator_additional_non_configuration_keys = getattr(
        xcode_generator, 'generator_additional_non_configuration_keys', [])
    generator_additional_path_sections = getattr(
        xcode_generator, 'generator_additional_path_sections', [])
    global generator_extra_sources_for_rules
    generator_extra_sources_for_rules = getattr(
        xcode_generator, 'generator_extra_sources_for_rules', [])
  elif flavor in ['ps3']:
    if is_windows:
      # This is required for BuildCygwinBashCommandLine() to work.
      import gyp.generator.msvs as msvs_generator
      generator_additional_non_configuration_keys = getattr(
          msvs_generator, 'generator_additional_non_configuration_keys', [])
      generator_additional_path_sections = getattr(
          msvs_generator, 'generator_additional_path_sections', [])

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

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

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

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


def 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."""
  user_config = params.get('generator_flags', {}).get('config', None)
  toplevel = params['options'].toplevel_dir
  qualified_out_dir = os.path.normpath(os.path.join(
      toplevel, ComputeOutputDir(params), user_config, '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."""
  try:
    os.makedirs(os.path.dirname(path))
  except OSError:
    pass
  return open(path, mode)


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

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

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

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

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


def MaybeWritePathVariable(ninja, tool, toolset):
  if tool.GetPath():
    ninja.variable('{0}_path'.format(GetNinjaRuleName(tool, toolset)),
                   tool.GetPath())


def MaybeWriteExtraFlagsVariable(ninja, tool, toolset, shell):
  if tool.GetExtraFlags():
    ninja.variable(
        '{0}_extra_flags'.format(GetNinjaRuleName(tool, toolset)),
        JoinShellArguments(shell, tool.GetExtraFlags()))


def MaybeWritePool(ninja, tool, toolset):
  if tool.GetMaxConcurrentProcesses():
    ninja.pool(
        '{0}_pool'.format(GetNinjaRuleName(tool, toolset)),
        depth=tool.GetMaxConcurrentProcesses())


def MaybeWriteRule(ninja, tool, toolset):
  if tool.GetRuleName():
    name = GetNinjaRuleName(tool, toolset)

    path = '${0}_path'.format(name)
    extra_flags = '${0}_extra_flags'.format(name)
    flags = '${0}_flags'.format(name)
    pool = '{0}_pool'.format(name) if tool.GetMaxConcurrentProcesses() else None

    ninja.rule(
        name,
        tool.GetCommand(path, extra_flags, flags),
        description=tool.GetDescription(),
        depfile=tool.GetHeaderDependenciesFilePath(),
        deps=tool.GetHeaderDependenciesFormat(),
        pool=pool,
        rspfile=tool.GetRspFilePath(),
        rspfile_content=tool.GetRspFileContent())


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 = ninja_syntax.Writer(
      OpenOutput(os.path.join(toplevel_build, 'build.ninja')), width=120)
  case_sensitive_filesystem = True

  build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
  make_global_settings = data[build_file].get('make_global_settings', [])

  try:
    # To avoid duplication, platform-agnostic tools (such as stamp and copy)
    # will be processed only in the host toolchain.
    target_toolchain = [
        target_tool for target_tool in GetTargetToolchain(flavor)
        if not target_tool.IsPlatformAgnostic()
    ]
    host_toolchain = GetHostToolchain(flavor)

    shell = FindFirstInstanceOf(abstract.Shell, host_toolchain)
    assert shell, 'Host toolchain must provide shell.'

    for target_tool in target_toolchain:
      MaybeWritePathVariable(master_ninja, target_tool, 'target')
    for host_tool in host_toolchain:
      MaybeWritePathVariable(master_ninja, host_tool, 'host')
    master_ninja.newline()

    for target_tool in target_toolchain:
      MaybeWriteExtraFlagsVariable(master_ninja, target_tool, 'target', shell)
    for host_tool in host_toolchain:
      MaybeWriteExtraFlagsVariable(master_ninja, host_tool, 'host', shell)
    master_ninja.newline()

    for target_tool in target_toolchain:
      MaybeWritePool(master_ninja, target_tool, 'target')
    for host_tool in host_toolchain:
      MaybeWritePool(master_ninja, host_tool, 'host')
    master_ninja.newline()

    for target_tool in target_toolchain:
      MaybeWriteRule(master_ninja, target_tool, 'target')
    for host_tool in host_toolchain:
      MaybeWriteRule(master_ninja, host_tool, 'host')
    master_ninja.newline()
  except NotImplementedError:
    # Fall back to the legacy toolchain.

    # 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 in sony_flavors and is_windows):
      cc = 'cl.exe'
      cxx = 'cl.exe'
      ld = 'link.exe'
      gyp.msvs_emulation.GenerateEnvironmentFiles(toplevel_build,
                                                  generator_flags, OpenOutput)
      ld_host = '$ld'
    elif GetToolchainOrNone(flavor):
      # TODO: starboardize.
      cc = 'cl.exe'
      cxx = 'cl.exe'
      ld = 'link.exe'
      GetToolchainOrNone(flavor).GenerateEnvironmentFiles(
          toplevel_build, generator_flags, OpenOutput)
      ld_host = '$ld'
    else:
      cc = 'gcc'
      cxx = 'g++'
      ld = '$cxx'
      ld_host = '$cxx_host'

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

    build_to_root = InvertRelativePath(build_dir)
    for key, value in make_global_settings:
      if key == 'CC':
        cc = os.path.join(build_to_root, value)
      if key == 'CXX':
        cxx = os.path.join(build_to_root, value)
      if key == 'LD':
        ld = os.path.join(build_to_root, value)
      if key == 'CC.host':
        cc_host = os.path.join(build_to_root, value)
        cc_host_global_setting = value
      if key == 'CXX.host':
        cxx_host = os.path.join(build_to_root, value)
        cxx_host_global_setting = value
      if key == 'LD.host':
        ld_host = os.path.join(build_to_root, value)

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

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

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

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

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

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

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

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

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

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

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

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

      ld_cmd = '$ld'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    spec = target_dicts[qualified_target]

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

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

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

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

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

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

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

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


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


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

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


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