# Copyright (c) 2012 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.

# Notes:
#
# This generates makefiles suitable for inclusion into the Android build system
# via an Android.mk file. It is based on make.py, the standard makefile
# generator.
#
# The code below generates a separate .mk file for each target, but
# all are sourced by the top-level GypAndroid.mk.  This means that all
# variables in .mk-files clobber one another, and furthermore that any
# variables set potentially clash with other Android build system variables.
# Try to avoid setting global variables where possible.

import gyp
import gyp.common
import gyp.generator.make as make  # Reuse global functions from make backend.
import os
import re

generator_default_variables = {
  'OS': 'android',
  'EXECUTABLE_PREFIX': '',
  'EXECUTABLE_SUFFIX': '',
  'STATIC_LIB_PREFIX': 'lib',
  'SHARED_LIB_PREFIX': 'lib',
  'STATIC_LIB_SUFFIX': '.a',
  'SHARED_LIB_SUFFIX': '.so',
  'INTERMEDIATE_DIR': '$(gyp_intermediate_dir)',
  'SHARED_INTERMEDIATE_DIR': '$(gyp_shared_intermediate_dir)',
  'PRODUCT_DIR': '$(gyp_shared_intermediate_dir)',
  'SHARED_LIB_DIR': '$(builddir)/lib.$(TOOLSET)',
  'LIB_DIR': '$(obj).$(TOOLSET)',
  'RULE_INPUT_ROOT': '%(INPUT_ROOT)s',  # This gets expanded by Python.
  'RULE_INPUT_DIRNAME': '%(INPUT_DIRNAME)s',  # This gets expanded by Python.
  'RULE_INPUT_PATH': '$(RULE_SOURCES)',
  'RULE_INPUT_EXT': '$(suffix $<)',
  'RULE_INPUT_NAME': '$(notdir $<)',
  'CONFIGURATION_NAME': 'NOT_USED_ON_ANDROID',
}

# Make supports multiple toolsets
generator_supports_multiple_toolsets = True


# Generator-specific gyp specs.
generator_additional_non_configuration_keys = [
    # Boolean to declare that this target does not want its name mangled.
    'android_unmangled_name',
]
generator_additional_path_sections = []
generator_extra_sources_for_rules = []


SHARED_FOOTER = """\
# "gyp_all_modules" is a concatenation of the "gyp_all_modules" targets from
# all the included sub-makefiles. This is just here to clarify.
gyp_all_modules:
"""

header = """\
# This file is generated by gyp; do not edit.

"""

android_standard_include_paths = set([
    # JNI_H_INCLUDE in build/core/binary.mk
    'dalvik/libnativehelper/include/nativehelper',
    # from SRC_HEADERS in build/core/config.mk
    'system/core/include',
    'hardware/libhardware/include',
    'hardware/libhardware_legacy/include',
    'hardware/ril/include',
    'dalvik/libnativehelper/include',
    'frameworks/native/include',
    'frameworks/native/opengl/include',
    'frameworks/base/include',
    'frameworks/base/opengl/include',
    'frameworks/base/native/include',
    'external/skia/include',
    # TARGET_C_INCLUDES in build/core/combo/TARGET_linux-arm.mk
    'bionic/libc/arch-arm/include',
    'bionic/libc/include',
    'bionic/libstdc++/include',
    'bionic/libc/kernel/common',
    'bionic/libc/kernel/arch-arm',
    'bionic/libm/include',
    'bionic/libm/include/arm',
    'bionic/libthread_db/include',
    ])


# Map gyp target types to Android module classes.
MODULE_CLASSES = {
    'static_library': 'STATIC_LIBRARIES',
    'shared_library': 'SHARED_LIBRARIES',
    'executable': 'EXECUTABLES',
}


def IsCPPExtension(ext):
  return make.COMPILABLE_EXTENSIONS.get(ext) == 'cxx'


def Sourceify(path):
  """Convert a path to its source directory form. The Android backend does not
     support options.generator_output, so this function is a noop."""
  return path


# Map from qualified target to path to output.
# For Android, the target of these maps is a tuple ('static', 'modulename'),
# ('dynamic', 'modulename'), or ('path', 'some/path') instead of a string,
# since we link by module.
target_outputs = {}
# Map from qualified target to any linkable output.  A subset
# of target_outputs.  E.g. when mybinary depends on liba, we want to
# include liba in the linker line; when otherbinary depends on
# mybinary, we just want to build mybinary first.
target_link_deps = {}


class AndroidMkWriter(object):
  """AndroidMkWriter packages up the writing of one target-specific Android.mk.

  Its only real entry point is Write(), and is mostly used for namespacing.
  """

  def __init__(self, android_top_dir):
    self.android_top_dir = android_top_dir

  def Write(self, qualified_target, base_path, output_filename, spec, configs,
            part_of_all):
    """The main entry point: writes a .mk file for a single target.

    Arguments:
      qualified_target: target we're generating
      base_path: path relative to source root we're building in, used to resolve
                 target-relative paths
      output_filename: output .mk file name to write
      spec, configs: gyp info
      part_of_all: flag indicating this target is part of 'all'
    """
    make.ensure_directory_exists(output_filename)

    self.fp = open(output_filename, 'w')

    self.fp.write(header)

    self.qualified_target = qualified_target
    self.path = base_path
    self.target = spec['target_name']
    self.type = spec['type']
    self.toolset = spec['toolset']

    deps, link_deps = self.ComputeDeps(spec)

    # Some of the generation below can add extra output, sources, or
    # link dependencies.  All of the out params of the functions that
    # follow use names like extra_foo.
    extra_outputs = []
    extra_sources = []

    self.android_class = MODULE_CLASSES.get(self.type, 'GYP')
    self.android_module = self.ComputeAndroidModule(spec)
    (self.android_stem, self.android_suffix) = self.ComputeOutputParts(spec)
    self.output = self.output_binary = self.ComputeOutput(spec)

    # Standard header.
    self.WriteLn('include $(CLEAR_VARS)\n')

    # Module class and name.
    self.WriteLn('LOCAL_MODULE_CLASS := ' + self.android_class)
    self.WriteLn('LOCAL_MODULE := ' + self.android_module)
    # Only emit LOCAL_MODULE_STEM if it's different to LOCAL_MODULE.
    # The library module classes fail if the stem is set. ComputeOutputParts
    # makes sure that stem == modulename in these cases.
    if self.android_stem != self.android_module:
      self.WriteLn('LOCAL_MODULE_STEM := ' + self.android_stem)
    self.WriteLn('LOCAL_MODULE_SUFFIX := ' + self.android_suffix)
    self.WriteLn('LOCAL_MODULE_TAGS := optional')
    if self.toolset == 'host':
      self.WriteLn('LOCAL_IS_HOST_MODULE := true')

    # Grab output directories; needed for Actions and Rules.
    self.WriteLn('gyp_intermediate_dir := $(call local-intermediates-dir)')
    self.WriteLn('gyp_shared_intermediate_dir := '
                 '$(call intermediates-dir-for,GYP,shared)')
    self.WriteLn()

    # List files this target depends on so that actions/rules/copies/sources
    # can depend on the list.
    # TODO: doesn't pull in things through transitive link deps; needed?
    target_dependencies = [x[1] for x in deps if x[0] == 'path']
    self.WriteLn('# Make sure our deps are built first.')
    self.WriteList(target_dependencies, 'GYP_TARGET_DEPENDENCIES',
                   local_pathify=True)

    # Actions must come first, since they can generate more OBJs for use below.
    if 'actions' in spec:
      self.WriteActions(spec['actions'], extra_sources, extra_outputs)

    # Rules must be early like actions.
    if 'rules' in spec:
      self.WriteRules(spec['rules'], extra_sources, extra_outputs)

    if 'copies' in spec:
      self.WriteCopies(spec['copies'], extra_outputs)

    # GYP generated outputs.
    self.WriteList(extra_outputs, 'GYP_GENERATED_OUTPUTS', local_pathify=True)

    # Set LOCAL_ADDITIONAL_DEPENDENCIES so that Android's build rules depend
    # on both our dependency targets and our generated files.
    self.WriteLn('# Make sure our deps and generated files are built first.')
    self.WriteLn('LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) '
                 '$(GYP_GENERATED_OUTPUTS)')
    self.WriteLn()

    # Sources.
    if spec.get('sources', []) or extra_sources:
      self.WriteSources(spec, configs, extra_sources)

    self.WriteTarget(spec, configs, deps, link_deps, part_of_all)

    # Update global list of target outputs, used in dependency tracking.
    target_outputs[qualified_target] = ('path', self.output_binary)

    # Update global list of link dependencies.
    if self.type == 'static_library':
      target_link_deps[qualified_target] = ('static', self.android_module)
    elif self.type == 'shared_library':
      target_link_deps[qualified_target] = ('shared', self.android_module)

    self.fp.close()
    return self.android_module


  def WriteActions(self, actions, extra_sources, extra_outputs):
    """Write Makefile code for any 'actions' from the gyp input.

    extra_sources: a list that will be filled in with newly generated source
                   files, if any
    extra_outputs: a list that will be filled in with any outputs of these
                   actions (used to make other pieces dependent on these
                   actions)
    """
    for action in actions:
      name = make.StringToMakefileVariable('%s_%s' % (self.qualified_target,
                                                      action['action_name']))
      self.WriteLn('### Rules for action "%s":' % action['action_name'])
      inputs = action['inputs']
      outputs = action['outputs']

      # Build up a list of outputs.
      # Collect the output dirs we'll need.
      dirs = set()
      for out in outputs:
        if not out.startswith('$'):
          print ('WARNING: Action for target "%s" writes output to local path '
                 '"%s".' % (self.target, out))
        dir = os.path.split(out)[0]
        if dir:
          dirs.add(dir)
      if int(action.get('process_outputs_as_sources', False)):
        extra_sources += outputs

      # Prepare the actual command.
      command = gyp.common.EncodePOSIXShellList(action['action'])
      if 'message' in action:
        quiet_cmd = 'Gyp action: %s ($@)' % action['message']
      else:
        quiet_cmd = 'Gyp action: %s ($@)' % name
      if len(dirs) > 0:
        command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command

      cd_action = 'cd $(gyp_local_path)/%s; ' % self.path
      command = cd_action + command

      # The makefile rules are all relative to the top dir, but the gyp actions
      # are defined relative to their containing dir.  This replaces the gyp_*
      # variables for the action rule with an absolute version so that the
      # output goes in the right place.
      # Only write the gyp_* rules for the "primary" output (:1);
      # it's superfluous for the "extra outputs", and this avoids accidentally
      # writing duplicate dummy rules for those outputs.
      main_output = make.QuoteSpaces(self.LocalPathify(outputs[0]))
      self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' % main_output)
      self.WriteLn('%s: gyp_intermediate_dir := '
                   '$(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)' %
                   main_output)
      self.WriteLn('%s: gyp_shared_intermediate_dir := '
                   '$(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)' %
                   main_output)

      for input in inputs:
        assert ' ' not in input, (
            "Spaces in action input filenames not supported (%s)"  % input)
      for output in outputs:
        assert ' ' not in output, (
            "Spaces in action output filenames not supported (%s)"  % output)

      self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES)' %
                   (main_output, ' '.join(map(self.LocalPathify, inputs))))
      self.WriteLn('\t@echo "%s"' % quiet_cmd)
      self.WriteLn('\t$(hide)%s\n' % command)
      for output in outputs[1:]:
        # Make each output depend on the main output, with an empty command
        # to force make to notice that the mtime has changed.
        self.WriteLn('%s: %s ;' % (self.LocalPathify(output), main_output))

      extra_outputs += outputs
      self.WriteLn()

    self.WriteLn()


  def WriteRules(self, rules, extra_sources, extra_outputs):
    """Write Makefile code for any 'rules' from the gyp input.

    extra_sources: a list that will be filled in with newly generated source
                   files, if any
    extra_outputs: a list that will be filled in with any outputs of these
                   rules (used to make other pieces dependent on these rules)
    """
    if len(rules) == 0:
      return
    rule_trigger = '%s_rule_trigger' % self.android_module

    did_write_rule = False
    for rule in rules:
      if len(rule.get('rule_sources', [])) == 0:
        continue
      did_write_rule = True
      name = make.StringToMakefileVariable('%s_%s' % (self.qualified_target,
                                                      rule['rule_name']))
      self.WriteLn('\n### Generated for rule "%s":' % name)
      self.WriteLn('# "%s":' % rule)

      inputs = rule.get('inputs')
      for rule_source in rule.get('rule_sources', []):
        (rule_source_dirname, rule_source_basename) = os.path.split(rule_source)
        (rule_source_root, rule_source_ext) = \
            os.path.splitext(rule_source_basename)

        outputs = [self.ExpandInputRoot(out, rule_source_root,
                                        rule_source_dirname)
                   for out in rule['outputs']]

        dirs = set()
        for out in outputs:
          if not out.startswith('$'):
            print ('WARNING: Rule for target %s writes output to local path %s'
                   % (self.target, out))
          dir = os.path.dirname(out)
          if dir:
            dirs.add(dir)
        extra_outputs += outputs
        if int(rule.get('process_outputs_as_sources', False)):
          extra_sources.extend(outputs)

        components = []
        for component in rule['action']:
          component = self.ExpandInputRoot(component, rule_source_root,
                                           rule_source_dirname)
          if '$(RULE_SOURCES)' in component:
            component = component.replace('$(RULE_SOURCES)',
                                          rule_source)
          components.append(component)

        command = gyp.common.EncodePOSIXShellList(components)
        cd_action = 'cd $(gyp_local_path)/%s; ' % self.path
        command = cd_action + command
        if dirs:
          command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command

        # We set up a rule to build the first output, and then set up
        # a rule for each additional output to depend on the first.
        outputs = map(self.LocalPathify, outputs)
        main_output = outputs[0]
        self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' % main_output)
        self.WriteLn('%s: gyp_intermediate_dir := '
                     '$(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)'
                     % main_output)
        self.WriteLn('%s: gyp_shared_intermediate_dir := '
                     '$(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)'
                     % main_output)

        main_output_deps = self.LocalPathify(rule_source)
        if inputs:
          main_output_deps += ' '
          main_output_deps += ' '.join([self.LocalPathify(f) for f in inputs])

        self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES)' %
                     (main_output, main_output_deps))
        self.WriteLn('\t%s\n' % command)
        for output in outputs[1:]:
          self.WriteLn('%s: %s' % (output, main_output))
        self.WriteLn('.PHONY: %s' % (rule_trigger))
        self.WriteLn('%s: %s' % (rule_trigger, main_output))
        self.WriteLn('')
    if did_write_rule:
      extra_sources.append(rule_trigger)  # Force all rules to run.
      self.WriteLn('### Finished generating for all rules')
      self.WriteLn('')


  def WriteCopies(self, copies, extra_outputs):
    """Write Makefile code for any 'copies' from the gyp input.

    extra_outputs: a list that will be filled in with any outputs of this action
                   (used to make other pieces dependent on this action)
    """
    self.WriteLn('### Generated for copy rule.')

    variable = make.StringToMakefileVariable(self.qualified_target + '_copies')
    outputs = []
    for copy in copies:
      for path in copy['files']:
        # The Android build system does not allow generation of files into the
        # source tree. The destination should start with a variable, which will
        # typically be $(gyp_intermediate_dir) or
        # $(gyp_shared_intermediate_dir). Note that we can't use an assertion
        # because some of the gyp tests depend on this.
        if not copy['destination'].startswith('$'):
          print ('WARNING: Copy rule for target %s writes output to '
                 'local path %s' % (self.target, copy['destination']))

        # LocalPathify() calls normpath, stripping trailing slashes.
        path = Sourceify(self.LocalPathify(path))
        filename = os.path.split(path)[1]
        output = Sourceify(self.LocalPathify(os.path.join(copy['destination'],
                                                          filename)))

        self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES) | $(ACP)' %
                     (output, path))
        self.WriteLn('\t@echo Copying: $@')
        self.WriteLn('\t$(hide) mkdir -p $(dir $@)')
        self.WriteLn('\t$(hide) $(ACP) -r $< $@')
        self.WriteLn()
        outputs.append(output)
    self.WriteLn('%s = %s' % (variable,
                              ' '.join(map(make.QuoteSpaces, outputs))))
    extra_outputs.append('$(%s)' % variable)
    self.WriteLn()


  def WriteSourceFlags(self, spec, configs):
    """Write out the flags and include paths used to compile source files for
    the current target.

    Args:
      spec, configs: input from gyp.
    """
    config = configs[spec['default_configuration']]
    extracted_includes = []

    self.WriteLn('\n# Flags passed to both C and C++ files.')
    cflags, includes_from_cflags = self.ExtractIncludesFromCFlags(
        config.get('cflags'))
    extracted_includes.extend(includes_from_cflags)
    self.WriteList(cflags, 'MY_CFLAGS')

    cflags_c, includes_from_cflags_c = self.ExtractIncludesFromCFlags(
        config.get('cflags_c'))
    extracted_includes.extend(includes_from_cflags_c)
    self.WriteList(cflags_c, 'MY_CFLAGS_C')

    self.WriteList(config.get('defines'), 'MY_DEFS', prefix='-D',
                   quoter=make.EscapeCppDefine)
    self.WriteLn('LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)')

    # Undefine ANDROID for host modules
    # TODO: the source code should not use macro ANDROID to tell if it's host or
    # target module.
    if self.toolset == 'host':
      self.WriteLn('# Undefine ANDROID for host modules')
      self.WriteLn('LOCAL_CFLAGS += -UANDROID')

    self.WriteLn('\n# Include paths placed before CFLAGS/CPPFLAGS')
    includes = list(config.get('include_dirs', []))
    includes.extend(extracted_includes)
    includes = map(Sourceify, map(self.LocalPathify, includes))
    includes = self.NormalizeIncludePaths(includes)
    self.WriteList(includes, 'LOCAL_C_INCLUDES')
    self.WriteLn('LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) '
                                     '$(LOCAL_C_INCLUDES)')

    self.WriteLn('\n# Flags passed to only C++ (and not C) files.')
    self.WriteList(config.get('cflags_cc'), 'LOCAL_CPPFLAGS')


  def WriteSources(self, spec, configs, extra_sources):
    """Write Makefile code for any 'sources' from the gyp input.
    These are source files necessary to build the current target.
    We need to handle shared_intermediate directory source files as
    a special case by copying them to the intermediate directory and
    treating them as a genereated sources. Otherwise the Android build
    rules won't pick them up.

    Args:
      spec, configs: input from gyp.
      extra_sources: Sources generated from Actions or Rules.
    """
    sources = filter(make.Compilable, spec.get('sources', []))
    generated_not_sources = [x for x in extra_sources if not make.Compilable(x)]
    extra_sources = filter(make.Compilable, extra_sources)

    # Determine and output the C++ extension used by these sources.
    # We simply find the first C++ file and use that extension.
    all_sources = sources + extra_sources
    local_cpp_extension = '.cpp'
    for source in all_sources:
      (root, ext) = os.path.splitext(source)
      if IsCPPExtension(ext):
        local_cpp_extension = ext
        break
    if local_cpp_extension != '.cpp':
      self.WriteLn('LOCAL_CPP_EXTENSION := %s' % local_cpp_extension)

    # We need to move any non-generated sources that are coming from the
    # shared intermediate directory out of LOCAL_SRC_FILES and put them
    # into LOCAL_GENERATED_SOURCES. We also need to move over any C++ files
    # that don't match our local_cpp_extension, since Android will only
    # generate Makefile rules for a single LOCAL_CPP_EXTENSION.
    local_files = []
    for source in sources:
      (root, ext) = os.path.splitext(source)
      if '$(gyp_shared_intermediate_dir)' in source:
        extra_sources.append(source)
      elif '$(gyp_intermediate_dir)' in source:
        extra_sources.append(source)
      elif IsCPPExtension(ext) and ext != local_cpp_extension:
        extra_sources.append(source)
      else:
        local_files.append(os.path.normpath(os.path.join(self.path, source)))

    # For any generated source, if it is coming from the shared intermediate
    # directory then we add a Make rule to copy them to the local intermediate
    # directory first. This is because the Android LOCAL_GENERATED_SOURCES
    # must be in the local module intermediate directory for the compile rules
    # to work properly. If the file has the wrong C++ extension, then we add
    # a rule to copy that to intermediates and use the new version.
    final_generated_sources = []
    # If a source file gets copied, we still need to add the orginal source
    # directory as header search path, for GCC searches headers in the
    # directory that contains the source file by default.
    origin_src_dirs = []
    for source in extra_sources:
      local_file = source
      if not '$(gyp_intermediate_dir)/' in local_file:
        basename = os.path.basename(local_file)
        local_file = '$(gyp_intermediate_dir)/' + basename
      (root, ext) = os.path.splitext(local_file)
      if IsCPPExtension(ext) and ext != local_cpp_extension:
        local_file = root + local_cpp_extension
      if local_file != source:
        self.WriteLn('%s: %s' % (local_file, self.LocalPathify(source)))
        self.WriteLn('\tmkdir -p $(@D); cp $< $@')
        origin_src_dirs.append(os.path.dirname(source))
      final_generated_sources.append(local_file)

    # We add back in all of the non-compilable stuff to make sure that the
    # make rules have dependencies on them.
    final_generated_sources.extend(generated_not_sources)
    self.WriteList(final_generated_sources, 'LOCAL_GENERATED_SOURCES')

    origin_src_dirs = gyp.common.uniquer(origin_src_dirs)
    origin_src_dirs = map(Sourceify, map(self.LocalPathify, origin_src_dirs))
    self.WriteList(origin_src_dirs, 'GYP_COPIED_SOURCE_ORIGIN_DIRS')

    self.WriteList(local_files, 'LOCAL_SRC_FILES')

    # Write out the flags used to compile the source; this must be done last
    # so that GYP_COPIED_SOURCE_ORIGIN_DIRS can be used as an include path.
    self.WriteSourceFlags(spec, configs)


  def ComputeAndroidModule(self, spec):
    """Return the Android module name used for a gyp spec.

    We use the complete qualified target name to avoid collisions between
    duplicate targets in different directories. We also add a suffix to
    distinguish gyp-generated module names.
    """

    if int(spec.get('android_unmangled_name', 0)):
      assert self.type != 'shared_library' or self.target.startswith('lib')
      return self.target

    if self.type == 'shared_library':
      # For reasons of convention, the Android build system requires that all
      # shared library modules are named 'libfoo' when generating -l flags.
      prefix = 'lib_'
    else:
      prefix = ''

    if spec['toolset'] == 'host':
      suffix = '_host_gyp'
    else:
      suffix = '_gyp'

    if self.path:
      name = '%s%s_%s%s' % (prefix, self.path, self.target, suffix)
    else:
      name = '%s%s%s' % (prefix, self.target, suffix)

    return make.StringToMakefileVariable(name)


  def ComputeOutputParts(self, spec):
    """Return the 'output basename' of a gyp spec, split into filename + ext.

    Android libraries must be named the same thing as their module name,
    otherwise the linker can't find them, so product_name and so on must be
    ignored if we are building a library, and the "lib" prepending is
    not done for Android.
    """
    assert self.type != 'loadable_module' # TODO: not supported?

    target = spec['target_name']
    target_prefix = ''
    target_ext = ''
    if self.type == 'static_library':
      target = self.ComputeAndroidModule(spec)
      target_ext = '.a'
    elif self.type == 'shared_library':
      target = self.ComputeAndroidModule(spec)
      target_ext = '.so'
    elif self.type == 'none':
      target_ext = '.stamp'
    elif self.type != 'executable':
      print ("ERROR: What output file should be generated?",
             "type", self.type, "target", target)

    if self.type != 'static_library' and self.type != 'shared_library':
      target_prefix = spec.get('product_prefix', target_prefix)
      target = spec.get('product_name', target)
      product_ext = spec.get('product_extension')
      if product_ext:
        target_ext = '.' + product_ext

    target_stem = target_prefix + target
    return (target_stem, target_ext)


  def ComputeOutputBasename(self, spec):
    """Return the 'output basename' of a gyp spec.

    E.g., the loadable module 'foobar' in directory 'baz' will produce
      'libfoobar.so'
    """
    return ''.join(self.ComputeOutputParts(spec))


  def ComputeOutput(self, spec):
    """Return the 'output' (full output path) of a gyp spec.

    E.g., the loadable module 'foobar' in directory 'baz' will produce
      '$(obj)/baz/libfoobar.so'
    """
    if self.type == 'executable' and self.toolset == 'host':
      # We install host executables into shared_intermediate_dir so they can be
      # run by gyp rules that refer to PRODUCT_DIR.
      path = '$(gyp_shared_intermediate_dir)'
    elif self.type == 'shared_library':
      if self.toolset == 'host':
        path = '$(HOST_OUT_INTERMEDIATE_LIBRARIES)'
      else:
        path = '$(TARGET_OUT_INTERMEDIATE_LIBRARIES)'
    else:
      # Other targets just get built into their intermediate dir.
      if self.toolset == 'host':
        path = '$(call intermediates-dir-for,%s,%s,true)' % (self.android_class,
                                                            self.android_module)
      else:
        path = '$(call intermediates-dir-for,%s,%s)' % (self.android_class,
                                                        self.android_module)

    assert spec.get('product_dir') is None # TODO: not supported?
    return os.path.join(path, self.ComputeOutputBasename(spec))


  def NormalizeLdFlags(self, ld_flags):
    """ Clean up ldflags from gyp file.
    Remove any ldflags that contain android_top_dir.

    Args:
      ld_flags: ldflags from gyp files.

    Returns:
      clean ldflags
    """
    clean_ldflags = []
    for flag in ld_flags:
      if self.android_top_dir in flag:
        continue
      clean_ldflags.append(flag)
    return clean_ldflags

  def NormalizeIncludePaths(self, include_paths):
    """ Normalize include_paths.
    Convert absolute paths to relative to the Android top directory;
    filter out include paths that are already brought in by the Android build
    system.

    Args:
      include_paths: A list of unprocessed include paths.
    Returns:
      A list of normalized include paths.
    """
    normalized = []
    for path in include_paths:
      if path[0] == '/':
        path = gyp.common.RelativePath(path, self.android_top_dir)

      # Filter out the Android standard search path.
      if path not in android_standard_include_paths:
        normalized.append(path)
    return normalized

  def ExtractIncludesFromCFlags(self, cflags):
    """Extract includes "-I..." out from cflags

    Args:
      cflags: A list of compiler flags, which may be mixed with "-I.."
    Returns:
      A tuple of lists: (clean_clfags, include_paths). "-I.." is trimmed.
    """
    clean_cflags = []
    include_paths = []
    if cflags:
      for flag in cflags:
        if flag.startswith('-I'):
          include_paths.append(flag[2:])
        else:
          clean_cflags.append(flag)

    return (clean_cflags, include_paths)

  def ComputeAndroidLibraryModuleNames(self, libraries):
    """Compute the Android module names from libraries, ie spec.get('libraries')

    Args:
      libraries: the value of spec.get('libraries')
    Returns:
      A tuple (static_lib_modules, dynamic_lib_modules)
    """
    static_lib_modules = []
    dynamic_lib_modules = []
    for libs in libraries:
      # Libs can have multiple words.
      for lib in libs.split():
        # Filter the system libraries, which are added by default by the Android
        # build system.
        if (lib == '-lc' or lib == '-lstdc++' or lib == '-lm' or
            lib.endswith('libgcc.a')):
          continue
        match = re.search(r'([^/]+)\.a$', lib)
        if match:
          static_lib_modules.append(match.group(1))
          continue
        match = re.search(r'([^/]+)\.so$', lib)
        if match:
          dynamic_lib_modules.append(match.group(1))
          continue
        # "-lstlport" -> libstlport
        if lib.startswith('-l'):
          if lib.endswith('_static'):
            static_lib_modules.append('lib' + lib[2:])
          else:
            dynamic_lib_modules.append('lib' + lib[2:])
    return (static_lib_modules, dynamic_lib_modules)


  def ComputeDeps(self, spec):
    """Compute the dependencies of a gyp spec.

    Returns a tuple (deps, link_deps), where each is a list of
    filenames that will need to be put in front of make for either
    building (deps) or linking (link_deps).
    """
    deps = []
    link_deps = []
    if 'dependencies' in spec:
      deps.extend([target_outputs[dep] for dep in spec['dependencies']
                   if target_outputs[dep]])
      for dep in spec['dependencies']:
        if dep in target_link_deps:
          link_deps.append(target_link_deps[dep])
      deps.extend(link_deps)
    return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps))


  def WriteTargetFlags(self, spec, configs, link_deps):
    """Write Makefile code to specify the link flags and library dependencies.

    spec, configs: input from gyp.
    link_deps: link dependency list; see ComputeDeps()
    """
    config = configs[spec['default_configuration']]

    # LDFLAGS
    ldflags = list(config.get('ldflags', []))
    static_flags, dynamic_flags = self.ComputeAndroidLibraryModuleNames(
        ldflags)
    self.WriteLn('')
    self.WriteList(self.NormalizeLdFlags(ldflags), 'LOCAL_LDFLAGS')

    # Libraries (i.e. -lfoo)
    libraries = gyp.common.uniquer(spec.get('libraries', []))
    static_libs, dynamic_libs = self.ComputeAndroidLibraryModuleNames(
        libraries)

    # Link dependencies (i.e. libfoo.a, libfoo.so)
    static_link_deps = [x[1] for x in link_deps if x[0] == 'static']
    shared_link_deps = [x[1] for x in link_deps if x[0] == 'shared']
    self.WriteLn('')
    self.WriteList(static_flags + static_libs + static_link_deps,
                   'LOCAL_STATIC_LIBRARIES')
    self.WriteLn('# Enable grouping to fix circular references')
    self.WriteLn('LOCAL_GROUP_STATIC_LIBRARIES := true')
    self.WriteLn('')
    self.WriteList(dynamic_flags + dynamic_libs + shared_link_deps,
                   'LOCAL_SHARED_LIBRARIES')


  def WriteTarget(self, spec, configs, deps, link_deps, part_of_all):
    """Write Makefile code to produce the final target of the gyp spec.

    spec, configs: input from gyp.
    deps, link_deps: dependency lists; see ComputeDeps()
    part_of_all: flag indicating this target is part of 'all'
    """
    self.WriteLn('### Rules for final target.')

    if self.type != 'none':
      self.WriteTargetFlags(spec, configs, link_deps)

    # Add to the set of targets which represent the gyp 'all' target. We use the
    # name 'gyp_all_modules' as the Android build system doesn't allow the use
    # of the Make target 'all' and because 'all_modules' is the equivalent of
    # the Make target 'all' on Android.
    if part_of_all:
      self.WriteLn('# Add target alias to "gyp_all_modules" target.')
      self.WriteLn('.PHONY: gyp_all_modules')
      self.WriteLn('gyp_all_modules: %s' % self.android_module)
      self.WriteLn('')

    # Add an alias from the gyp target name to the Android module name. This
    # simplifies manual builds of the target, and is required by the test
    # framework.
    if self.target != self.android_module:
      self.WriteLn('# Alias gyp target name.')
      self.WriteLn('.PHONY: %s' % self.target)
      self.WriteLn('%s: %s' % (self.target, self.android_module))
      self.WriteLn('')

    # Add the command to trigger build of the target type depending
    # on the toolset. Ex: BUILD_STATIC_LIBRARY vs. BUILD_HOST_STATIC_LIBRARY
    # NOTE: This has to come last!
    modifier = ''
    if self.toolset == 'host':
      modifier = 'HOST_'
    if self.type == 'static_library':
      self.WriteLn('include $(BUILD_%sSTATIC_LIBRARY)' % modifier)
    elif self.type == 'shared_library':
      self.WriteLn('LOCAL_PRELINK_MODULE := false')
      self.WriteLn('include $(BUILD_%sSHARED_LIBRARY)' % modifier)
    elif self.type == 'executable':
      if self.toolset == 'host':
        self.WriteLn('LOCAL_MODULE_PATH := $(gyp_shared_intermediate_dir)')
      else:
        # Don't install target executables for now, as it results in them being
        # included in ROM. This can be revisited if there's a reason to install
        # them later.
        self.WriteLn('LOCAL_UNINSTALLABLE_MODULE := true')
      self.WriteLn('include $(BUILD_%sEXECUTABLE)' % modifier)
    else:
      self.WriteLn('LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp')
      self.WriteLn('LOCAL_UNINSTALLABLE_MODULE := true')
      self.WriteLn()
      self.WriteLn('include $(BUILD_SYSTEM)/base_rules.mk')
      self.WriteLn()
      self.WriteLn('$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)')
      self.WriteLn('\t$(hide) echo "Gyp timestamp: $@"')
      self.WriteLn('\t$(hide) mkdir -p $(dir $@)')
      self.WriteLn('\t$(hide) touch $@')


  def WriteList(self, value_list, variable=None, prefix='',
                quoter=make.QuoteIfNecessary, local_pathify=False):
    """Write a variable definition that is a list of values.

    E.g. WriteList(['a','b'], 'foo', prefix='blah') writes out
         foo = blaha blahb
    but in a pretty-printed style.
    """
    values = ''
    if value_list:
      value_list = [quoter(prefix + l) for l in value_list]
      if local_pathify:
        value_list = [self.LocalPathify(l) for l in value_list]
      values = ' \\\n\t' + ' \\\n\t'.join(value_list)
    self.fp.write('%s :=%s\n\n' % (variable, values))


  def WriteLn(self, text=''):
    self.fp.write(text + '\n')


  def LocalPathify(self, path):
    """Convert a subdirectory-relative path into a normalized path which starts
    with the make variable $(LOCAL_PATH) (i.e. the top of the project tree).
    Absolute paths, or paths that contain variables, are just normalized."""
    if '$(' in path or os.path.isabs(path):
      # path is not a file in the project tree in this case, but calling
      # normpath is still important for trimming trailing slashes.
      return os.path.normpath(path)
    local_path = os.path.join('$(LOCAL_PATH)', self.path, path)
    local_path = os.path.normpath(local_path)
    # Check that normalizing the path didn't ../ itself out of $(LOCAL_PATH)
    # - i.e. that the resulting path is still inside the project tree. The
    # path may legitimately have ended up containing just $(LOCAL_PATH), though,
    # so we don't look for a slash.
    assert local_path.startswith('$(LOCAL_PATH)'), (
           'Path %s attempts to escape from gyp path %s !)' % (path, self.path))
    return local_path


  def ExpandInputRoot(self, template, expansion, dirname):
    if '%(INPUT_ROOT)s' not in template and '%(INPUT_DIRNAME)s' not in template:
      return template
    path = template % {
        'INPUT_ROOT': expansion,
        'INPUT_DIRNAME': dirname,
        }
    return path


def WriteAutoRegenerationRule(params, root_makefile, makefile_name,
                              build_files):
  """Write the target to regenerate the Makefile."""
  options = params['options']
  # Sort to avoid non-functional changes to makefile.
  build_files = sorted([os.path.join('$(LOCAL_PATH)', f) for f in build_files])
  build_files_args = [gyp.common.RelativePath(filename, options.toplevel_dir)
                      for filename in params['build_files_arg']]
  build_files_args = [os.path.join('$(PRIVATE_LOCAL_PATH)', f)
                      for f in build_files_args]
  gyp_binary = gyp.common.FixIfRelativePath(params['gyp_binary'],
                                            options.toplevel_dir)
  makefile_path = os.path.join('$(LOCAL_PATH)', makefile_name)
  if not gyp_binary.startswith(os.sep):
    gyp_binary = os.path.join('.', gyp_binary)
  root_makefile.write('GYP_FILES := \\\n  %s\n\n' %
                      '\\\n  '.join(map(Sourceify, build_files)))
  root_makefile.write('%s: PRIVATE_LOCAL_PATH := $(LOCAL_PATH)\n' %
                      makefile_path)
  root_makefile.write('%s: $(GYP_FILES)\n' % makefile_path)
  root_makefile.write('\techo ACTION Regenerating $@\n\t%s\n\n' %
      gyp.common.EncodePOSIXShellList([gyp_binary, '-fandroid'] +
                                      gyp.RegenerateFlags(options) +
                                      build_files_args))


def GenerateOutput(target_list, target_dicts, data, params):
  options = params['options']
  generator_flags = params.get('generator_flags', {})
  builddir_name = generator_flags.get('output_dir', 'out')
  limit_to_target_all = generator_flags.get('limit_to_target_all', False)
  android_top_dir = os.environ.get('ANDROID_BUILD_TOP')
  assert android_top_dir, '$ANDROID_BUILD_TOP not set; you need to run lunch.'

  def CalculateMakefilePath(build_file, base_name):
    """Determine where to write a Makefile for a given gyp file."""
    # Paths in gyp files are relative to the .gyp file, but we want
    # paths relative to the source root for the master makefile.  Grab
    # the path of the .gyp file as the base to relativize against.
    # E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp".
    base_path = gyp.common.RelativePath(os.path.dirname(build_file),
                                        options.depth)
    # We write the file in the base_path directory.
    output_file = os.path.join(options.depth, base_path, base_name)
    assert not options.generator_output, (
        'The Android backend does not support options.generator_output.')
    base_path = gyp.common.RelativePath(os.path.dirname(build_file),
                                        options.toplevel_dir)
    return base_path, output_file

  # TODO:  search for the first non-'Default' target.  This can go
  # away when we add verification that all targets have the
  # necessary configurations.
  default_configuration = None
  toolsets = set([target_dicts[target]['toolset'] for target in target_list])
  for target in target_list:
    spec = target_dicts[target]
    if spec['default_configuration'] != 'Default':
      default_configuration = spec['default_configuration']
      break
  if not default_configuration:
    default_configuration = 'Default'

  srcdir = '.'
  makefile_name = 'GypAndroid' + options.suffix + '.mk'
  makefile_path = os.path.join(options.toplevel_dir, makefile_name)
  assert not options.generator_output, (
      'The Android backend does not support options.generator_output.')
  make.ensure_directory_exists(makefile_path)
  root_makefile = open(makefile_path, 'w')

  root_makefile.write(header)

  # We set LOCAL_PATH just once, here, to the top of the project tree. This
  # allows all the other paths we use to be relative to the Android.mk file,
  # as the Android build system expects.
  root_makefile.write('\nLOCAL_PATH := $(call my-dir)\n')

  # Find the list of targets that derive from the gyp file(s) being built.
  needed_targets = set()
  for build_file in params['build_files']:
    for target in gyp.common.AllTargets(target_list, target_dicts, build_file):
      needed_targets.add(target)

  build_files = set()
  include_list = set()
  android_modules = {}
  for qualified_target in target_list:
    build_file, target, toolset = gyp.common.ParseQualifiedTarget(
        qualified_target)
    build_files.add(gyp.common.RelativePath(build_file, options.toplevel_dir))
    included_files = data[build_file]['included_files']
    for included_file in included_files:
      # The included_files entries are relative to the dir of the build file
      # that included them, so we have to undo that and then make them relative
      # to the root dir.
      relative_include_file = gyp.common.RelativePath(
          gyp.common.UnrelativePath(included_file, build_file),
          options.toplevel_dir)
      abs_include_file = os.path.abspath(relative_include_file)
      # If the include file is from the ~/.gyp dir, we should use absolute path
      # so that relocating the src dir doesn't break the path.
      if (params['home_dot_gyp'] and
          abs_include_file.startswith(params['home_dot_gyp'])):
        build_files.add(abs_include_file)
      else:
        build_files.add(relative_include_file)

    base_path, output_file = CalculateMakefilePath(build_file,
        target + '.' + toolset + options.suffix + '.mk')

    spec = target_dicts[qualified_target]
    configs = spec['configurations']

    part_of_all = (qualified_target in needed_targets and
                   not int(spec.get('suppress_wildcard', False)))
    if limit_to_target_all and not part_of_all:
      continue
    writer = AndroidMkWriter(android_top_dir)
    android_module = writer.Write(qualified_target, base_path, output_file,
                                  spec, configs, part_of_all=part_of_all)
    if android_module in android_modules:
      print ('ERROR: Android module names must be unique. The following '
             'targets both generate Android module name %s.\n  %s\n  %s' %
             (android_module, android_modules[android_module],
              qualified_target))
      return
    android_modules[android_module] = qualified_target

    # Our root_makefile lives at the source root.  Compute the relative path
    # from there to the output_file for including.
    mkfile_rel_path = gyp.common.RelativePath(output_file,
                                              os.path.dirname(makefile_path))
    include_list.add(mkfile_rel_path)

  # Some tools need to know the absolute path of the top directory.
  root_makefile.write('GYP_ABS_ANDROID_TOP_DIR := $(shell pwd)\n')

  # Write out the sorted list of includes.
  root_makefile.write('\n')
  for include_file in sorted(include_list):
    root_makefile.write('include $(LOCAL_PATH)/' + include_file + '\n')
  root_makefile.write('\n')

  if generator_flags.get('auto_regeneration', True):
    WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files)

  root_makefile.write(SHARED_FOOTER)

  root_makefile.close()
