| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173 | 
							- # 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
 
- import subprocess
 
- 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": "$(GYP_CONFIGURATION)",
 
- }
 
- # 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",
 
-     # Map of android build system variables to set.
 
-     "aosp_build_settings",
 
- ]
 
- generator_additional_path_sections = []
 
- generator_extra_sources_for_rules = []
 
- ALL_MODULES_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.
 
- """
 
- # 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:
 
-     """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,
 
-         relative_target,
 
-         base_path,
 
-         output_filename,
 
-         spec,
 
-         configs,
 
-         part_of_all,
 
-         write_alias_target,
 
-         sdk_version,
 
-     ):
 
-         """The main entry point: writes a .mk file for a single target.
 
-         Arguments:
 
-           qualified_target: target we're generating
 
-           relative_target: qualified target name relative to the root
 
-           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'
 
-           write_alias_target: flag indicating whether to create short aliases for
 
-                               this target
 
-           sdk_version: what to emit for LOCAL_SDK_VERSION in output
 
-         """
 
-         gyp.common.EnsureDirExists(output_filename)
 
-         self.fp = open(output_filename, "w")
 
-         self.fp.write(header)
 
-         self.qualified_target = qualified_target
 
-         self.relative_target = relative_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)
 
-         if self.toolset == "host":
 
-             self.WriteLn("LOCAL_IS_HOST_MODULE := true")
 
-             self.WriteLn("LOCAL_MULTILIB := $(GYP_HOST_MULTILIB)")
 
-         elif sdk_version > 0:
 
-             self.WriteLn(
 
-                 "LOCAL_MODULE_TARGET_ARCH := " "$(TARGET_$(GYP_VAR_PREFIX)ARCH)"
 
-             )
 
-             self.WriteLn("LOCAL_SDK_VERSION := %s" % sdk_version)
 
-         # Grab output directories; needed for Actions and Rules.
 
-         if self.toolset == "host":
 
-             self.WriteLn(
 
-                 "gyp_intermediate_dir := "
 
-                 "$(call local-intermediates-dir,,$(GYP_HOST_VAR_PREFIX))"
 
-             )
 
-         else:
 
-             self.WriteLn(
 
-                 "gyp_intermediate_dir := "
 
-                 "$(call local-intermediates-dir,,$(GYP_VAR_PREFIX))"
 
-             )
 
-         self.WriteLn(
 
-             "gyp_shared_intermediate_dir := "
 
-             "$(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))"
 
-         )
 
-         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, write_alias_target
 
-         )
 
-         # 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(
 
-                 "{}_{}".format(self.relative_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_var_prefix := $(GYP_VAR_PREFIX)" % main_output)
 
-             self.WriteLn(
 
-                 "%s: gyp_intermediate_dir := "
 
-                 "$(abspath $(gyp_intermediate_dir))" % main_output
 
-             )
 
-             self.WriteLn(
 
-                 "%s: gyp_shared_intermediate_dir := "
 
-                 "$(abspath $(gyp_shared_intermediate_dir))" % main_output
 
-             )
 
-             # Android's envsetup.sh adds a number of directories to the path including
 
-             # the built host binary directory. This causes actions/rules invoked by
 
-             # gyp to sometimes use these instead of system versions, e.g. bison.
 
-             # The built host binaries may not be suitable, and can cause errors.
 
-             # So, we remove them from the PATH using the ANDROID_BUILD_PATHS variable
 
-             # set by envsetup.
 
-             self.WriteLn(
 
-                 "%s: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))"
 
-                 % main_output
 
-             )
 
-             # Don't allow spaces in input/output filenames, but make an exception for
 
-             # filenames which start with '$(' since it's okay for there to be spaces
 
-             # inside of make function/macro invocations.
 
-             for input in inputs:
 
-                 if not input.startswith("$(") and " " in input:
 
-                     raise gyp.common.GypError(
 
-                         'Action input filename "%s" in target %s contains a space'
 
-                         % (input, self.target)
 
-                     )
 
-             for output in outputs:
 
-                 if not output.startswith("$(") and " " in output:
 
-                     raise gyp.common.GypError(
 
-                         'Action output filename "%s" in target %s contains a space'
 
-                         % (output, self.target)
 
-                     )
 
-             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(f"{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
 
-         for rule in rules:
 
-             if len(rule.get("rule_sources", [])) == 0:
 
-                 continue
 
-             name = make.StringToMakefileVariable(
 
-                 "{}_{}".format(self.relative_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_var_prefix := $(GYP_VAR_PREFIX)" % main_output)
 
-                 self.WriteLn(
 
-                     "%s: gyp_intermediate_dir := "
 
-                     "$(abspath $(gyp_intermediate_dir))" % main_output
 
-                 )
 
-                 self.WriteLn(
 
-                     "%s: gyp_shared_intermediate_dir := "
 
-                     "$(abspath $(gyp_shared_intermediate_dir))" % main_output
 
-                 )
 
-                 # See explanation in WriteActions.
 
-                 self.WriteLn(
 
-                     "%s: export PATH := "
 
-                     "$(subst $(ANDROID_BUILD_PATHS),,$(PATH))" % 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:]:
 
-                     # Make each output depend on the main output, with an empty command
 
-                     # to force make to notice that the mtime has changed.
 
-                     self.WriteLn(f"{output}: {main_output} ;")
 
-                 self.WriteLn()
 
-         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.relative_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(f"{output}: {path} $(GYP_TARGET_DEPENDENCIES) | $(ACP)")
 
-                 self.WriteLn("\t@echo Copying: $@")
 
-                 self.WriteLn("\t$(hide) mkdir -p $(dir $@)")
 
-                 self.WriteLn("\t$(hide) $(ACP) -rpf $< $@")
 
-                 self.WriteLn()
 
-                 outputs.append(output)
 
-         self.WriteLn(
 
-             "{} = {}".format(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.
 
-         """
 
-         for configname, config in sorted(configs.items()):
 
-             extracted_includes = []
 
-             self.WriteLn("\n# Flags passed to both C and C++ files.")
 
-             cflags, includes_from_cflags = self.ExtractIncludesFromCFlags(
 
-                 config.get("cflags", []) + config.get("cflags_c", [])
 
-             )
 
-             extracted_includes.extend(includes_from_cflags)
 
-             self.WriteList(cflags, "MY_CFLAGS_%s" % configname)
 
-             self.WriteList(
 
-                 config.get("defines"),
 
-                 "MY_DEFS_%s" % configname,
 
-                 prefix="-D",
 
-                 quoter=make.EscapeCppDefine,
 
-             )
 
-             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_%s" % configname)
 
-             self.WriteLn("\n# Flags passed to only C++ (and not C) files.")
 
-             self.WriteList(config.get("cflags_cc"), "LOCAL_CPPFLAGS_%s" % configname)
 
-         self.WriteLn(
 
-             "\nLOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) "
 
-             "$(MY_DEFS_$(GYP_CONFIGURATION))"
 
-         )
 
-         # 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(
 
-             "LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) "
 
-             "$(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))"
 
-         )
 
-         self.WriteLn("LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))")
 
-         # Android uses separate flags for assembly file invocations, but gyp expects
 
-         # the same CFLAGS to be applied:
 
-         self.WriteLn("LOCAL_ASFLAGS := $(LOCAL_CFLAGS)")
 
-     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 generated 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 original 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 "$(gyp_intermediate_dir)/" not 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(f"{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 = "_$(TARGET_$(GYP_VAR_PREFIX)ARCH)_host_gyp"
 
-         else:
 
-             suffix = "_gyp"
 
-         if self.path:
 
-             middle = make.StringToMakefileVariable(f"{self.path}_{self.target}")
 
-         else:
 
-             middle = make.StringToMakefileVariable(self.target)
 
-         return "".join([prefix, middle, suffix])
 
-     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 not in {"static_library", "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":
 
-             # 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 = "$($(GYP_HOST_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES)"
 
-             else:
 
-                 path = "$($(GYP_VAR_PREFIX)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,,"
 
-                     "$(GYP_HOST_VAR_PREFIX))"
 
-                     % (self.android_class, self.android_module)
 
-                 )
 
-             else:
 
-                 path = (
 
-                     f"$(call intermediates-dir-for,{self.android_class},"
 
-                     f"{self.android_module},,,$(GYP_VAR_PREFIX))"
 
-                 )
 
-         assert spec.get("product_dir") is None  # TODO: not supported?
 
-         return os.path.join(path, self.ComputeOutputBasename(spec))
 
-     def NormalizeIncludePaths(self, include_paths):
 
-         """Normalize include_paths.
 
-         Convert absolute paths to relative to the Android top directory.
 
-         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)
 
-             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_cflags, include_paths). "-I.." is trimmed.
 
-         """
 
-         clean_cflags = []
 
-         include_paths = []
 
-         for flag in cflags:
 
-             if flag.startswith("-I"):
 
-                 include_paths.append(flag[2:])
 
-             else:
 
-                 clean_cflags.append(flag)
 
-         return (clean_cflags, include_paths)
 
-     def FilterLibraries(self, libraries):
 
-         """Filter the 'libraries' key to separate things that shouldn't be ldflags.
 
-         Library entries that look like filenames should be converted to android
 
-         module names instead of being passed to the linker as flags.
 
-         Args:
 
-           libraries: the value of spec.get('libraries')
 
-         Returns:
 
-           A tuple (static_lib_modules, dynamic_lib_modules, ldflags)
 
-         """
 
-         static_lib_modules = []
 
-         dynamic_lib_modules = []
 
-         ldflags = []
 
-         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
 
-                 if lib.startswith("-l"):
 
-                     ldflags.append(lib)
 
-         return (static_lib_modules, dynamic_lib_modules, ldflags)
 
-     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()
 
-         """
 
-         # Libraries (i.e. -lfoo)
 
-         # These must be included even for static libraries as some of them provide
 
-         # implicit include paths through the build system.
 
-         libraries = gyp.common.uniquer(spec.get("libraries", []))
 
-         static_libs, dynamic_libs, ldflags_libs = self.FilterLibraries(libraries)
 
-         if self.type != "static_library":
 
-             for configname, config in sorted(configs.items()):
 
-                 ldflags = list(config.get("ldflags", []))
 
-                 self.WriteLn("")
 
-                 self.WriteList(ldflags, "LOCAL_LDFLAGS_%s" % configname)
 
-             self.WriteList(ldflags_libs, "LOCAL_GYP_LIBS")
 
-             self.WriteLn(
 
-                 "LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION)) "
 
-                 "$(LOCAL_GYP_LIBS)"
 
-             )
 
-         # Link dependencies (i.e. other gyp targets this target depends on)
 
-         # These need not be included for static libraries as within the gyp build
 
-         # we do not use the implicit include path mechanism.
 
-         if self.type != "static_library":
 
-             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"]
 
-         else:
 
-             static_link_deps = []
 
-             shared_link_deps = []
 
-         # Only write the lists if they are non-empty.
 
-         if static_libs or static_link_deps:
 
-             self.WriteLn("")
 
-             self.WriteList(static_libs + static_link_deps, "LOCAL_STATIC_LIBRARIES")
 
-             self.WriteLn("# Enable grouping to fix circular references")
 
-             self.WriteLn("LOCAL_GROUP_STATIC_LIBRARIES := true")
 
-         if dynamic_libs or shared_link_deps:
 
-             self.WriteLn("")
 
-             self.WriteList(dynamic_libs + shared_link_deps, "LOCAL_SHARED_LIBRARIES")
 
-     def WriteTarget(
 
-         self, spec, configs, deps, link_deps, part_of_all, write_alias_target
 
-     ):
 
-         """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'
 
-         write_alias_target: flag indicating whether to create short aliases for this
 
-                             target
 
-         """
 
-         self.WriteLn("### Rules for final target.")
 
-         if self.type != "none":
 
-             self.WriteTargetFlags(spec, configs, link_deps)
 
-         settings = spec.get("aosp_build_settings", {})
 
-         if settings:
 
-             self.WriteLn("### Set directly by aosp_build_settings.")
 
-             for k, v in settings.items():
 
-                 if isinstance(v, list):
 
-                     self.WriteList(v, k)
 
-                 else:
 
-                     self.WriteLn(f"{k} := {make.QuoteIfNecessary(v)}")
 
-             self.WriteLn("")
 
-         # 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 and write_alias_target:
 
-             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 and write_alias_target:
 
-             self.WriteLn("# Alias gyp target name.")
 
-             self.WriteLn(".PHONY: %s" % self.target)
 
-             self.WriteLn(f"{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":
 
-             self.WriteLn("LOCAL_CXX_STL := libc++_static")
 
-             # Executables are for build and test purposes only, so they're installed
 
-             # to a directory that doesn't get included in the system image.
 
-             self.WriteLn("LOCAL_MODULE_PATH := $(gyp_shared_intermediate_dir)")
 
-             self.WriteLn("include $(BUILD_%sEXECUTABLE)" % modifier)
 
-         else:
 
-             self.WriteLn("LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp")
 
-             self.WriteLn("LOCAL_UNINSTALLABLE_MODULE := true")
 
-             if self.toolset == "target":
 
-                 self.WriteLn("LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)")
 
-             else:
 
-                 self.WriteLn("LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_HOST_VAR_PREFIX)")
 
-             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 $@")
 
-             self.WriteLn()
 
-             self.WriteLn("LOCAL_2ND_ARCH_VAR_PREFIX :=")
 
-     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 + value) for value in value_list]
 
-             if local_pathify:
 
-                 value_list = [self.LocalPathify(value) for value in value_list]
 
-             values = " \\\n\t" + " \\\n\t".join(value_list)
 
-         self.fp.write(f"{variable} :={values}\n\n")
 
-     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)"
 
-         ), f"Path {path} attempts to escape from gyp 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 os.path.normpath(path)
 
- def PerformBuild(data, configurations, params):
 
-     # The android backend only supports the default configuration.
 
-     options = params["options"]
 
-     makefile = os.path.abspath(os.path.join(options.toplevel_dir, "GypAndroid.mk"))
 
-     env = dict(os.environ)
 
-     env["ONE_SHOT_MAKEFILE"] = makefile
 
-     arguments = ["make", "-C", os.environ["ANDROID_BUILD_TOP"], "gyp_all_modules"]
 
-     print("Building: %s" % arguments)
 
-     subprocess.check_call(arguments, env=env)
 
- def GenerateOutput(target_list, target_dicts, data, params):
 
-     options = params["options"]
 
-     generator_flags = params.get("generator_flags", {})
 
-     limit_to_target_all = generator_flags.get("limit_to_target_all", False)
 
-     write_alias_targets = generator_flags.get("write_alias_targets", True)
 
-     sdk_version = generator_flags.get("aosp_sdk_version", 0)
 
-     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
 
-     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"
 
-     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."
 
-     gyp.common.EnsureDirExists(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)
 
-         relative_build_file = gyp.common.RelativePath(build_file, options.toplevel_dir)
 
-         build_files.add(relative_build_file)
 
-         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
 
-         if limit_to_target_all and not part_of_all:
 
-             continue
 
-         relative_target = gyp.common.QualifiedTarget(
 
-             relative_build_file, target, toolset
 
-         )
 
-         writer = AndroidMkWriter(android_top_dir)
 
-         android_module = writer.Write(
 
-             qualified_target,
 
-             relative_target,
 
-             base_path,
 
-             output_file,
 
-             spec,
 
-             configs,
 
-             part_of_all=part_of_all,
 
-             write_alias_target=write_alias_targets,
 
-             sdk_version=sdk_version,
 
-         )
 
-         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)
 
-     root_makefile.write("GYP_CONFIGURATION ?= %s\n" % default_configuration)
 
-     root_makefile.write("GYP_VAR_PREFIX ?=\n")
 
-     root_makefile.write("GYP_HOST_VAR_PREFIX ?=\n")
 
-     root_makefile.write("GYP_HOST_MULTILIB ?= first\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 write_alias_targets:
 
-         root_makefile.write(ALL_MODULES_FOOTER)
 
-     root_makefile.close()
 
 
  |