# Copyright (c) 2011 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 gyp
import gyp.common
import gyp.system_test
import os.path
import pprint
import subprocess
import sys

import gyp.ninja_syntax as ninja_syntax

generator_default_variables = {
  'OS': 'linux',

  'EXECUTABLE_PREFIX': '',
  'EXECUTABLE_SUFFIX': '',
  'STATIC_LIB_PREFIX': '',
  'STATIC_LIB_SUFFIX': '.a',
  'SHARED_LIB_PREFIX': 'lib',
  'SHARED_LIB_SUFFIX': '.so',

  # Gyp expects the following variables to be expandable by the build
  # system to the appropriate locations.  Ninja prefers paths to be
  # known at compile time.  To resolve this, introduce special
  # variables starting with $! (which begin with a $ so gyp knows it
  # should be treated as a path, 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.
  'INTERMEDIATE_DIR': '$!INTERMEDIATE_DIR',
  'SHARED_INTERMEDIATE_DIR': '$!PRODUCT_DIR/gen',
  'PRODUCT_DIR': '$!PRODUCT_DIR',
  'SHARED_LIB_DIR': '$!PRODUCT_DIR/lib',
  'LIB_DIR': '',

  # 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}',
}

# TODO: enable cross compiling once we figure out:
# - how to not build extra host objects in the non-cross-compile case.
# - how to decide what the host compiler is (should not just be $cc).
# - need ld_host as well.
generator_supports_multiple_toolsets = False


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


def QuoteShellArgument(arg):
  return "'" + arg.replace("'", "'" + '"\'"' + "'")  + "'"


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('/'))
  return '/'.join(['..'] * depth)


# 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 is unique
#   to the input file name as well as the output target name.

class NinjaWriter:
  def __init__(self, target_outputs, base_dir, build_dir, output_file):
    """
    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
    """

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

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

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

    return path

  def ExpandRuleVariables(self, path, root, dirname, source, ext, name):
    path = path.replace(generator_default_variables['RULE_INPUT_ROOT'], root)
    path = path.replace(generator_default_variables['RULE_INPUT_DIRNAME'],
                        dirname)
    path = path.replace(generator_default_variables['RULE_INPUT_PATH'], source)
    path = path.replace(generator_default_variables['RULE_INPUT_EXT'], ext)
    path = path.replace(generator_default_variables['RULE_INPUT_NAME'], name)
    return path

  def GypPathToNinja(self, path):
    """Translate a gyp path to a ninja path.

    See the above discourse on path conversions."""
    if path.startswith('$!'):
      return self.ExpandSpecial(path)
    assert '$' not in path, path
    return os.path.normpath(os.path.join(self.build_to_base, path))

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

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

    See the above discourse on path conversions."""

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

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

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

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

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

    Uses a stamp file if necessary."""

    if len(targets) > 1:
      stamp = self.GypPathToUniqueOutput(name + '.stamp')
      targets = self.ninja.build(stamp, 'stamp', targets)
      self.ninja.newline()
    return targets

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

    Returns the path to the build output, or None, and a list of targets for
    dependencies of its compile steps."""

    self.name = spec['target_name']
    self.toolset = spec['toolset']

    if spec['type'] == 'settings':
      # TODO: 'settings' is not actually part of gyp; it was
      # accidentally introduced somehow into just the Linux build files.
      # Remove this (or make it an error) once all the users are fixed.
      print ("WARNING: %s uses invalid type 'settings'.  " % self.name +
             "Please fix the source gyp file to use type 'none'.")
      print "See http://code.google.com/p/chromium/issues/detail?id=96629 ."
      spec['type'] = '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 = []
    if 'dependencies' in spec:
      for dep in spec['dependencies']:
        if dep in self.target_outputs:
          input, precompile_input, linkable = self.target_outputs[dep]
          actions_depends.append(input)
          compile_depends.extend(precompile_input)
      actions_depends = self.WriteCollapsedDependencies('actions_depends',
                                                        actions_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 = []
    sources_depends = self.WriteActionsRulesCopies(spec, extra_sources,
                                                   actions_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 = self.WriteCollapsedDependencies('compile_depends',
        sources_depends or compile_depends)

    # Write out the compilation steps, if any.
    link_deps = []
    sources = spec.get('sources', []) + extra_sources
    if sources:
      link_deps = self.WriteSources(config, sources, compile_depends)
      # Some actions/rules output 'sources' that are already object files.
      link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')]

    # The final output of our target depends on the last output of the
    # above steps.
    output = None
    final_deps = link_deps or sources_depends or actions_depends
    if final_deps:
      output = self.WriteTarget(spec, config, final_deps,
                                order_only=actions_depends)
      if self.name != output and self.toolset == 'target':
        # 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.
        self.ninja.build(self.name, 'phony', output)
    return output, compile_depends

  def WriteActionsRulesCopies(self, spec, extra_sources, prebuild):
    """Write out the Actions, Rules, and Copies steps.  Return any outputs
    of these steps (or a stamp file if there are lots of outputs)."""
    outputs = []

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

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

    return outputs

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

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

  def WriteActions(self, actions, extra_sources, prebuild):
    all_outputs = []
    for action in actions:
      # First write out a rule for the action.
      name = action['action_name']
      description = self.GenerateDescription('ACTION',
                                             action.get('message', None),
                                             name)
      rule_name = self.WriteNewNinjaRule(name, action['action'], description)

      inputs = [self.GypPathToNinja(i) for i in action['inputs']]
      if int(action.get('process_outputs_as_sources', False)):
        extra_sources += action['outputs']
      outputs = [self.GypPathToNinja(o) 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):
    all_outputs = []
    for rule in rules:
      # First write out a rule for the rule action.
      name = rule['rule_name']
      args = rule['action']
      description = self.GenerateDescription(
          'RULE',
          rule.get('message', None),
          ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name)
      rule_name = self.WriteNewNinjaRule(name, args, description)

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

      # 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 outputs, expanding $vars if possible.
        outputs = []
        for output in rule['outputs']:
          outputs.append(self.ExpandRuleVariables(output, root, dirname,
                                                  source, ext, basename))

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

        extra_bindings = []
        for var in needed_variables:
          if var == 'root':
            extra_bindings.append(('root', root))
          elif var == 'dirname':
            extra_bindings.append(('dirname', 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', source_expanded))
          elif var == 'ext':
            extra_bindings.append(('ext', ext))
          elif var == 'name':
            extra_bindings.append(('name', basename))
          else:
            assert var == None, repr(var)

        inputs = map(self.GypPathToNinja, rule.get('inputs', []))
        outputs = map(self.GypPathToNinja, outputs)
        self.ninja.build(outputs, rule_name, self.GypPathToNinja(source),
                         implicit=inputs,
                         order_only=prebuild,
                         variables=extra_bindings)

        all_outputs.extend(outputs)

    return all_outputs

  def WriteCopies(self, copies, prebuild):
    outputs = []
    for copy in copies:
      for path in copy['files']:
        # Normalize the path so trailing slashes don't confuse us.
        path = os.path.normpath(path)
        basename = os.path.split(path)[1]
        src = self.GypPathToNinja(path)
        dst = self.GypPathToNinja(os.path.join(copy['destination'], basename))
        outputs += self.ninja.build(dst, 'copy', src,
                                    order_only=prebuild)

    return outputs

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

    self.WriteVariableList('defines',
        [QuoteShellArgument(ninja_syntax.escape('-D' + d))
         for d in config.get('defines', [])])
    self.WriteVariableList('includes',
                           ['-I' + self.GypPathToNinja(i)
                            for i in config.get('include_dirs', [])])
    self.WriteVariableList('cflags', map(self.ExpandSpecial,
                                         config.get('cflags', [])))
    self.WriteVariableList('cflags_c', map(self.ExpandSpecial,
                                           config.get('cflags_c', [])))
    self.WriteVariableList('cflags_cc', map(self.ExpandSpecial,
                                            config.get('cflags_cc', [])))
    self.ninja.newline()
    outputs = []
    for source in sources:
      filename, ext = os.path.splitext(source)
      ext = ext[1:]
      if ext in ('cc', 'cpp', 'cxx'):
        command = 'cxx'
      elif ext in ('c', 's', 'S'):
        command = 'cc'
      else:
        # TODO: should we assert here on unexpected extensions?
        continue
      input = self.GypPathToNinja(source)
      output = self.GypPathToUniqueOutput(filename + '.o')
      self.ninja.build(output, command, input,
                       order_only=predepends)
      outputs.append(output)
    self.ninja.newline()
    return outputs

  def WriteTarget(self, spec, config, final_deps, order_only):
    if spec['type'] == 'none':
      # This target doesn't have any explicit final output, but is instead
      # used for its effects before the final output (e.g. copies steps).
      # Reuse the existing output if it's easy.
      if len(final_deps) == 1:
        return final_deps[0]
      # Otherwise, fall through to writing out a stamp file.

    output = self.ComputeOutput(spec)

    output_uses_linker = spec['type'] in ('executable', 'loadable_module',
                                          'shared_library')

    implicit_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
      if output_uses_linker:
        extra_deps = set()
        for dep in spec['dependencies']:
          input, _, linkable = self.target_outputs.get(dep, (None, [], False))
          if not input:
            continue
          if linkable:
            extra_deps.add(input)
          else:
            # TODO: Chrome-specific HACK.  Chrome runs this lastchange rule on
            # every build, but we don't want to rebuild when it runs.
            if 'lastchange' not in input:
              implicit_deps.add(input)
        final_deps.extend(list(extra_deps))
    command_map = {
      'executable':      'link',
      'static_library':  'alink',
      'loadable_module': 'solink_module',
      'shared_library':  'solink',
      'none':            'stamp',
    }
    command = command_map[spec['type']]

    if output_uses_linker:
      self.WriteVariableList('ldflags',
                             gyp.common.uniquer(map(self.ExpandSpecial,
                                                    config.get('ldflags', []))))
      self.WriteVariableList('libs',
                             gyp.common.uniquer(map(self.ExpandSpecial,
                                                    spec.get('libraries', []))))

    extra_bindings = []
    if command in ('solink', 'solink_module'):
      extra_bindings.append(('soname', os.path.split(output)[1]))

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

    return output

  def ComputeOutputFileName(self, spec):
    """Compute the filename of the final output for the current target."""

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

    # Compute filename extension: the product extension, or a default
    # for the product type.
    DEFAULT_EXTENSION = {
      'static_library': 'a',
      'loadable_module': 'so',
      'shared_library': 'so',
      }
    extension = spec.get('product_extension',
                         DEFAULT_EXTENSION.get(spec['type'], ''))
    if extension:
      extension = '.' + extension

    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 spec['type'] in ('static_library', 'loadable_module', 'shared_library',
                        'executable'):
      return '%s%s%s' % (prefix, target, extension)
    elif spec['type'] == 'none':
      return '%s.stamp' % target
    else:
      raise 'Unhandled output type', spec['type']

  def ComputeOutput(self, spec):
    """Compute the path for the final output of the spec."""

    filename = self.ComputeOutputFileName(spec)

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

    # Executables and loadable modules go into the output root,
    # libraries go into shared library dir, and everything else
    # goes into the normal place.
    if spec['type'] in ('executable', 'loadable_module'):
      return filename
    elif spec['type'] == 'shared_library':
      libdir = 'lib'
      if self.toolset != 'target':
        libdir = 'lib/%s' % self.toolset
      return os.path.join(libdir, filename)
    else:
      return self.GypPathToUniqueOutput(filename, qualified=False)

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

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

    Returns the name of the new rule."""

    # 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 = rule_name.replace(' ', '_')

    args = args[:]

    # 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.
    cd = 'cd %s; ' % self.build_to_base
    args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args]

    command = cd + gyp.common.EncodePOSIXShellList(args)
    self.ninja.rule(rule_name, command, description)
    self.ninja.newline()

    return rule_name


def CalculateVariables(default_variables, params):
  """Calculate additional variables for use in the build (called by gyp)."""
  cc_target = os.environ.get('CC.target', os.environ.get('CC', 'cc'))
  default_variables['LINKER_SUPPORTS_ICF'] = \
      gyp.system_test.TestLinkerSupportsICF(cc_command=cc_target)


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


def GenerateOutput(target_list, target_dicts, data, params):
  options = params['options']
  generator_flags = params.get('generator_flags', {})

  if options.generator_output:
    raise NotImplementedError, "--generator_output not implemented for ninja"

  config_name = generator_flags.get('config', None)
  if config_name is None:
    # Guess which config we want to use: pick the first one from the
    # first target.
    config_name = target_dicts[target_list[0]]['default_configuration']

  # builddir: relative path from source root to our output files.
  # e.g. "out/Debug"
  builddir = os.path.join(generator_flags.get('output_dir', 'out'), config_name)

  master_ninja = ninja_syntax.Writer(
      OpenOutput(os.path.join(options.toplevel_dir, builddir, 'build.ninja')),
      width=120)

  # TODO: compute cc/cxx/ld/etc. by command-line arguments and system tests.
  master_ninja.variable('cc', os.environ.get('CC', 'gcc'))
  master_ninja.variable('cxx', os.environ.get('CXX', 'g++'))
  master_ninja.variable('ld', '$cxx -Wl,--threads -Wl,--thread-count=4')
  master_ninja.variable('cc_host', '$cc')
  master_ninja.variable('cxx_host', '$cxx')
  master_ninja.newline()

  master_ninja.rule(
    'cc',
    description='CC $out',
    command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c '
             '-c $in -o $out'),
    depfile='$out.d')
  master_ninja.rule(
    'cxx',
    description='CXX $out',
    command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc '
             '-c $in -o $out'),
    depfile='$out.d')
  master_ninja.rule(
    'alink',
    description='AR $out',
    command='rm -f $out && ar rcsT $out $in')
  master_ninja.rule(
    'solink',
    description='SOLINK $out',
    command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname '
             '-Wl,--whole-archive $in -Wl,--no-whole-archive $libs'))
  master_ninja.rule(
    'solink_module',
    description='SOLINK(module) $out',
    command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname '
             '-Wl,--start-group $in -Wl,--end-group $libs'))
  master_ninja.rule(
    'link',
    description='LINK $out',
    command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib '
             '-Wl,--start-group $in -Wl,--end-group $libs'))
  master_ninja.rule(
    'stamp',
    description='STAMP $out',
    command='touch $out')
  master_ninja.rule(
    'copy',
    description='COPY $in $out',
    command='ln -f $in $out 2>/dev/null || cp -af $in $out')
  master_ninja.newline()

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

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

    # TODO: what is options.depth and how is it different than
    # options.toplevel_dir?
    build_file = gyp.common.RelativePath(build_file, options.depth)

    base_path = os.path.dirname(build_file)
    obj = 'obj'
    if toolset != 'target':
      obj += '.' + toolset
    output_file = os.path.join(obj, base_path, name + '.ninja')
    spec = target_dicts[qualified_target]
    config = spec['configurations'][config_name]

    writer = NinjaWriter(target_outputs, base_path, builddir,
                         OpenOutput(os.path.join(options.toplevel_dir,
                                                 builddir,
                                                 output_file)))
    master_ninja.subninja(output_file)

    output, compile_depends = writer.WriteSpec(spec, config)
    if output:
      linkable = spec['type'] in ('static_library', 'shared_library')
      target_outputs[qualified_target] = (output, compile_depends, linkable)

      if qualified_target in all_targets:
        all_outputs.add(output)

  if all_outputs:
    master_ninja.build('all', 'phony', list(all_outputs))
