// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cc

// This file contains the module types for compiling C/C++ for Android, and converts the properties
// into the flags and filenames necessary to pass to the compiler.  The final creation of the rules
// is handled in builder.go

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

	"android/soong"
	"android/soong/android"
	"android/soong/genrule"
)

func init() {
	soong.RegisterModuleType("cc_library_static", libraryStaticFactory)
	soong.RegisterModuleType("cc_library_shared", librarySharedFactory)
	soong.RegisterModuleType("cc_library", libraryFactory)
	soong.RegisterModuleType("cc_object", objectFactory)
	soong.RegisterModuleType("cc_binary", binaryFactory)
	soong.RegisterModuleType("cc_test", testFactory)
	soong.RegisterModuleType("cc_test_library", testLibraryFactory)
	soong.RegisterModuleType("cc_benchmark", benchmarkFactory)
	soong.RegisterModuleType("cc_defaults", defaultsFactory)

	soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
	soong.RegisterModuleType("ndk_prebuilt_library", ndkPrebuiltLibraryFactory)
	soong.RegisterModuleType("ndk_prebuilt_object", ndkPrebuiltObjectFactory)
	soong.RegisterModuleType("ndk_prebuilt_static_stl", ndkPrebuiltStaticStlFactory)
	soong.RegisterModuleType("ndk_prebuilt_shared_stl", ndkPrebuiltSharedStlFactory)

	soong.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory)
	soong.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory)
	soong.RegisterModuleType("cc_binary_host", binaryHostFactory)
	soong.RegisterModuleType("cc_test_host", testHostFactory)
	soong.RegisterModuleType("cc_benchmark_host", benchmarkHostFactory)

	// LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
	// the Go initialization order because this package depends on common, so common's init
	// functions will run first.
	android.RegisterBottomUpMutator("link", linkageMutator)
	android.RegisterBottomUpMutator("test_per_src", testPerSrcMutator)
	android.RegisterBottomUpMutator("deps", depsMutator)

	android.RegisterTopDownMutator("asan_deps", sanitizerDepsMutator(asan))
	android.RegisterBottomUpMutator("asan", sanitizerMutator(asan))

	android.RegisterTopDownMutator("tsan_deps", sanitizerDepsMutator(tsan))
	android.RegisterBottomUpMutator("tsan", sanitizerMutator(tsan))
}

var (
	HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
)

// Flags used by lots of devices.  Putting them in package static variables will save bytes in
// build.ninja so they aren't repeated for every file
var (
	commonGlobalCflags = []string{
		"-DANDROID",
		"-fmessage-length=0",
		"-W",
		"-Wall",
		"-Wno-unused",
		"-Winit-self",
		"-Wpointer-arith",

		// COMMON_RELEASE_CFLAGS
		"-DNDEBUG",
		"-UDEBUG",
	}

	deviceGlobalCflags = []string{
		"-fdiagnostics-color",

		// TARGET_ERROR_FLAGS
		"-Werror=return-type",
		"-Werror=non-virtual-dtor",
		"-Werror=address",
		"-Werror=sequence-point",
		"-Werror=date-time",
	}

	hostGlobalCflags = []string{}

	commonGlobalCppflags = []string{
		"-Wsign-promo",
	}

	noOverrideGlobalCflags = []string{
		"-Werror=int-to-pointer-cast",
		"-Werror=pointer-to-int-cast",
	}

	illegalFlags = []string{
		"-w",
	}

	ndkPrebuiltSharedLibs = []string{
		"android",
		"c",
		"dl",
		"EGL",
		"GLESv1_CM",
		"GLESv2",
		"GLESv3",
		"jnigraphics",
		"log",
		"mediandk",
		"m",
		"OpenMAXAL",
		"OpenSLES",
		"stdc++",
		"vulkan",
		"z",
	}
	ndkPrebuiltSharedLibraries = addPrefix(append([]string(nil), ndkPrebuiltSharedLibs...), "lib")
)

func init() {
	if android.BuildOs == android.Linux {
		commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
	}

	pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
	pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
	pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
	pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))

	pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))

	pctx.StaticVariable("commonClangGlobalCflags",
		strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
	pctx.StaticVariable("deviceClangGlobalCflags",
		strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
	pctx.StaticVariable("hostClangGlobalCflags",
		strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
	pctx.StaticVariable("noOverrideClangGlobalCflags",
		strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))

	pctx.StaticVariable("commonClangGlobalCppflags",
		strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))

	// Everything in this list is a crime against abstraction and dependency tracking.
	// Do not add anything to this list.
	pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
		[]string{
			"system/core/include",
			"system/media/audio/include",
			"hardware/libhardware/include",
			"hardware/libhardware_legacy/include",
			"hardware/ril/include",
			"libnativehelper/include",
			"frameworks/native/include",
			"frameworks/native/opengl/include",
			"frameworks/av/include",
			"frameworks/base/include",
		})
	// This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
	// with this, since there is no associated library.
	pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
		[]string{"libnativehelper/include/nativehelper"})

	pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
	pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
		if override := config.(android.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
			return override, nil
		}
		return "${clangDefaultBase}", nil
	})
	pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
		if override := config.(android.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
			return override, nil
		}
		return "clang-3016494", nil
	})
	pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}")
	pctx.StaticVariable("clangBin", "${clangPath}/bin")
}

type Deps struct {
	SharedLibs, LateSharedLibs                  []string
	StaticLibs, LateStaticLibs, WholeStaticLibs []string

	ReexportSharedLibHeaders, ReexportStaticLibHeaders []string

	ObjFiles []string

	GeneratedSources []string
	GeneratedHeaders []string

	CrtBegin, CrtEnd string
}

type PathDeps struct {
	SharedLibs, LateSharedLibs                  android.Paths
	StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths

	ObjFiles               android.Paths
	WholeStaticLibObjFiles android.Paths

	GeneratedSources android.Paths
	GeneratedHeaders android.Paths

	Flags, ReexportedFlags []string

	CrtBegin, CrtEnd android.OptionalPath
}

type Flags struct {
	GlobalFlags []string // Flags that apply to C, C++, and assembly source files
	AsFlags     []string // Flags that apply to assembly source files
	CFlags      []string // Flags that apply to C and C++ source files
	ConlyFlags  []string // Flags that apply to C source files
	CppFlags    []string // Flags that apply to C++ source files
	YaccFlags   []string // Flags that apply to Yacc source files
	LdFlags     []string // Flags that apply to linker command lines
	libFlags    []string // Flags to add libraries early to the link order

	Nocrt     bool
	Toolchain Toolchain
	Clang     bool

	RequiredInstructionSet string
	DynamicLinker          string

	CFlagsDeps android.Paths // Files depended on by compiler flags
}

type BaseCompilerProperties struct {
	// list of source files used to compile the C/C++ module.  May be .c, .cpp, or .S files.
	Srcs []string `android:"arch_variant"`

	// list of source files that should not be used to build the C/C++ module.
	// This is most useful in the arch/multilib variants to remove non-common files
	Exclude_srcs []string `android:"arch_variant"`

	// list of module-specific flags that will be used for C and C++ compiles.
	Cflags []string `android:"arch_variant"`

	// list of module-specific flags that will be used for C++ compiles
	Cppflags []string `android:"arch_variant"`

	// list of module-specific flags that will be used for C compiles
	Conlyflags []string `android:"arch_variant"`

	// list of module-specific flags that will be used for .S compiles
	Asflags []string `android:"arch_variant"`

	// list of module-specific flags that will be used for C and C++ compiles when
	// compiling with clang
	Clang_cflags []string `android:"arch_variant"`

	// list of module-specific flags that will be used for .S compiles when
	// compiling with clang
	Clang_asflags []string `android:"arch_variant"`

	// list of module-specific flags that will be used for .y and .yy compiles
	Yaccflags []string

	// the instruction set architecture to use to compile the C/C++
	// module.
	Instruction_set string `android:"arch_variant"`

	// list of directories relative to the root of the source tree that will
	// be added to the include path using -I.
	// If possible, don't use this.  If adding paths from the current directory use
	// local_include_dirs, if adding paths from other modules use export_include_dirs in
	// that module.
	Include_dirs []string `android:"arch_variant"`

	// list of directories relative to the Blueprints file that will
	// be added to the include path using -I
	Local_include_dirs []string `android:"arch_variant"`

	// list of generated sources to compile. These are the names of gensrcs or
	// genrule modules.
	Generated_sources []string `android:"arch_variant"`

	// list of generated headers to add to the include path. These are the names
	// of genrule modules.
	Generated_headers []string `android:"arch_variant"`

	// pass -frtti instead of -fno-rtti
	Rtti *bool

	Debug, Release struct {
		// list of module-specific flags that will be used for C and C++ compiles in debug or
		// release builds
		Cflags []string `android:"arch_variant"`
	} `android:"arch_variant"`
}

type BaseLinkerProperties struct {
	// list of modules whose object files should be linked into this module
	// in their entirety.  For static library modules, all of the .o files from the intermediate
	// directory of the dependency will be linked into this modules .a file.  For a shared library,
	// the dependency's .a file will be linked into this module using -Wl,--whole-archive.
	Whole_static_libs []string `android:"arch_variant,variant_prepend"`

	// list of modules that should be statically linked into this module.
	Static_libs []string `android:"arch_variant,variant_prepend"`

	// list of modules that should be dynamically linked into this module.
	Shared_libs []string `android:"arch_variant"`

	// list of module-specific flags that will be used for all link steps
	Ldflags []string `android:"arch_variant"`

	// don't insert default compiler flags into asflags, cflags,
	// cppflags, conlyflags, ldflags, or include_dirs
	No_default_compiler_flags *bool

	// list of system libraries that will be dynamically linked to
	// shared library and executable modules.  If unset, generally defaults to libc
	// and libm.  Set to [] to prevent linking against libc and libm.
	System_shared_libs []string

	// allow the module to contain undefined symbols.  By default,
	// modules cannot contain undefined symbols that are not satisified by their immediate
	// dependencies.  Set this flag to true to remove --no-undefined from the linker flags.
	// This flag should only be necessary for compiling low-level libraries like libc.
	Allow_undefined_symbols *bool

	// don't link in libgcc.a
	No_libgcc *bool

	// -l arguments to pass to linker for host-provided shared libraries
	Host_ldlibs []string `android:"arch_variant"`

	// list of shared libraries to re-export include directories from. Entries must be
	// present in shared_libs.
	Export_shared_lib_headers []string `android:"arch_variant"`

	// list of static libraries to re-export include directories from. Entries must be
	// present in static_libs.
	Export_static_lib_headers []string `android:"arch_variant"`

	// don't link in crt_begin and crt_end.  This flag should only be necessary for
	// compiling crt or libc.
	Nocrt *bool `android:"arch_variant"`
}

type LibraryCompilerProperties struct {
	Static struct {
		Srcs         []string `android:"arch_variant"`
		Exclude_srcs []string `android:"arch_variant"`
		Cflags       []string `android:"arch_variant"`
	} `android:"arch_variant"`
	Shared struct {
		Srcs         []string `android:"arch_variant"`
		Exclude_srcs []string `android:"arch_variant"`
		Cflags       []string `android:"arch_variant"`
	} `android:"arch_variant"`
}

type FlagExporterProperties struct {
	// list of directories relative to the Blueprints file that will
	// be added to the include path using -I for any module that links against this module
	Export_include_dirs []string `android:"arch_variant"`
}

type LibraryLinkerProperties struct {
	Static struct {
		Enabled           *bool    `android:"arch_variant"`
		Whole_static_libs []string `android:"arch_variant"`
		Static_libs       []string `android:"arch_variant"`
		Shared_libs       []string `android:"arch_variant"`
	} `android:"arch_variant"`
	Shared struct {
		Enabled           *bool    `android:"arch_variant"`
		Whole_static_libs []string `android:"arch_variant"`
		Static_libs       []string `android:"arch_variant"`
		Shared_libs       []string `android:"arch_variant"`
	} `android:"arch_variant"`

	// local file name to pass to the linker as --version_script
	Version_script *string `android:"arch_variant"`
	// local file name to pass to the linker as -unexported_symbols_list
	Unexported_symbols_list *string `android:"arch_variant"`
	// local file name to pass to the linker as -force_symbols_not_weak_list
	Force_symbols_not_weak_list *string `android:"arch_variant"`
	// local file name to pass to the linker as -force_symbols_weak_list
	Force_symbols_weak_list *string `android:"arch_variant"`

	// rename host libraries to prevent overlap with system installed libraries
	Unique_host_soname *bool

	VariantName string `blueprint:"mutated"`
}

type BinaryLinkerProperties struct {
	// compile executable with -static
	Static_executable *bool `android:"arch_variant"`

	// set the name of the output
	Stem string `android:"arch_variant"`

	// append to the name of the output
	Suffix string `android:"arch_variant"`

	// if set, add an extra objcopy --prefix-symbols= step
	Prefix_symbols string
}

type TestLinkerProperties struct {
	// if set, build against the gtest library. Defaults to true.
	Gtest bool

	// Create a separate binary for each source file.  Useful when there is
	// global state that can not be torn down and reset between each test suite.
	Test_per_src *bool
}

type ObjectLinkerProperties struct {
	// names of other cc_object modules to link into this module using partial linking
	Objs []string `android:"arch_variant"`
}

// Properties used to compile all C or C++ modules
type BaseProperties struct {
	// compile module with clang instead of gcc
	Clang *bool `android:"arch_variant"`

	// Minimum sdk version supported when compiling against the ndk
	Sdk_version string

	// don't insert default compiler flags into asflags, cflags,
	// cppflags, conlyflags, ldflags, or include_dirs
	No_default_compiler_flags *bool

	AndroidMkSharedLibs []string `blueprint:"mutated"`
	HideFromMake        bool     `blueprint:"mutated"`
}

type InstallerProperties struct {
	// install to a subdirectory of the default install path for the module
	Relative_install_path string

	// install symlinks to the module
	Symlinks []string `android:"arch_variant"`
}

type StripProperties struct {
	Strip struct {
		None         bool
		Keep_symbols bool
	}
}

type UnusedProperties struct {
	Native_coverage *bool
	Required        []string
	Tags            []string
}

type ModuleContextIntf interface {
	static() bool
	staticBinary() bool
	clang() bool
	toolchain() Toolchain
	noDefaultCompilerFlags() bool
	sdk() bool
	sdkVersion() string
	selectedStl() string
}

type ModuleContext interface {
	android.ModuleContext
	ModuleContextIntf
}

type BaseModuleContext interface {
	android.BaseContext
	ModuleContextIntf
}

type CustomizerFlagsContext interface {
	BaseModuleContext
	AppendCflags(...string)
	AppendLdflags(...string)
	AppendAsflags(...string)
}

type Customizer interface {
	Flags(CustomizerFlagsContext)
	Properties() []interface{}
}

type feature interface {
	begin(ctx BaseModuleContext)
	deps(ctx BaseModuleContext, deps Deps) Deps
	flags(ctx ModuleContext, flags Flags) Flags
	props() []interface{}
}

type compiler interface {
	feature
	appendCflags([]string)
	appendAsflags([]string)
	compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths
}

type linker interface {
	feature
	link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles android.Paths) android.Path
	appendLdflags([]string)
	installable() bool
}

type installer interface {
	props() []interface{}
	install(ctx ModuleContext, path android.Path)
	inData() bool
}

type dependencyTag struct {
	blueprint.BaseDependencyTag
	name    string
	library bool

	reexportFlags bool
}

var (
	sharedDepTag       = dependencyTag{name: "shared", library: true}
	sharedExportDepTag = dependencyTag{name: "shared", library: true, reexportFlags: true}
	lateSharedDepTag   = dependencyTag{name: "late shared", library: true}
	staticDepTag       = dependencyTag{name: "static", library: true}
	staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true}
	lateStaticDepTag   = dependencyTag{name: "late static", library: true}
	wholeStaticDepTag  = dependencyTag{name: "whole static", library: true, reexportFlags: true}
	genSourceDepTag    = dependencyTag{name: "gen source"}
	genHeaderDepTag    = dependencyTag{name: "gen header"}
	objDepTag          = dependencyTag{name: "obj"}
	crtBeginDepTag     = dependencyTag{name: "crtbegin"}
	crtEndDepTag       = dependencyTag{name: "crtend"}
	reuseObjTag        = dependencyTag{name: "reuse objects"}
)

// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface.  It delegates to compiler, linker, and installer interfaces
// to construct the output file.  Behavior can be customized with a Customizer interface
type Module struct {
	android.ModuleBase
	android.DefaultableModule

	Properties BaseProperties
	unused     UnusedProperties

	// initialize before calling Init
	hod      android.HostOrDeviceSupported
	multilib android.Multilib

	// delegates, initialize before calling Init
	Customizer Customizer
	features   []feature
	compiler   compiler
	linker     linker
	installer  installer
	stl        *stl
	sanitize   *sanitize

	androidMkSharedLibDeps []string

	outputFile android.OptionalPath

	cachedToolchain Toolchain
}

func (c *Module) Init() (blueprint.Module, []interface{}) {
	props := []interface{}{&c.Properties, &c.unused}
	if c.Customizer != nil {
		props = append(props, c.Customizer.Properties()...)
	}
	if c.compiler != nil {
		props = append(props, c.compiler.props()...)
	}
	if c.linker != nil {
		props = append(props, c.linker.props()...)
	}
	if c.installer != nil {
		props = append(props, c.installer.props()...)
	}
	if c.stl != nil {
		props = append(props, c.stl.props()...)
	}
	if c.sanitize != nil {
		props = append(props, c.sanitize.props()...)
	}
	for _, feature := range c.features {
		props = append(props, feature.props()...)
	}

	_, props = android.InitAndroidArchModule(c, c.hod, c.multilib, props...)

	return android.InitDefaultableModule(c, c, props...)
}

type baseModuleContext struct {
	android.BaseContext
	moduleContextImpl
}

type moduleContext struct {
	android.ModuleContext
	moduleContextImpl
}

type moduleContextImpl struct {
	mod *Module
	ctx BaseModuleContext
}

func (ctx *moduleContextImpl) AppendCflags(flags ...string) {
	CheckBadCompilerFlags(ctx.ctx, "", flags)
	ctx.mod.compiler.appendCflags(flags)
}

func (ctx *moduleContextImpl) AppendAsflags(flags ...string) {
	CheckBadCompilerFlags(ctx.ctx, "", flags)
	ctx.mod.compiler.appendAsflags(flags)
}

func (ctx *moduleContextImpl) AppendLdflags(flags ...string) {
	CheckBadLinkerFlags(ctx.ctx, "", flags)
	ctx.mod.linker.appendLdflags(flags)
}

func (ctx *moduleContextImpl) clang() bool {
	return ctx.mod.clang(ctx.ctx)
}

func (ctx *moduleContextImpl) toolchain() Toolchain {
	return ctx.mod.toolchain(ctx.ctx)
}

func (ctx *moduleContextImpl) static() bool {
	if ctx.mod.linker == nil {
		panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
	}
	if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
		return linker.static()
	} else {
		panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
	}
}

func (ctx *moduleContextImpl) staticBinary() bool {
	if ctx.mod.linker == nil {
		panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
	}
	if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
		return linker.staticBinary()
	} else {
		panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
	}
}

func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
	return Bool(ctx.mod.Properties.No_default_compiler_flags)
}

func (ctx *moduleContextImpl) sdk() bool {
	if ctx.ctx.Device() {
		return ctx.mod.Properties.Sdk_version != ""
	}
	return false
}

func (ctx *moduleContextImpl) sdkVersion() string {
	if ctx.ctx.Device() {
		return ctx.mod.Properties.Sdk_version
	}
	return ""
}

func (ctx *moduleContextImpl) selectedStl() string {
	if stl := ctx.mod.stl; stl != nil {
		return stl.Properties.SelectedStl
	}
	return ""
}

func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
	return &Module{
		hod:      hod,
		multilib: multilib,
	}
}

func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
	module := newBaseModule(hod, multilib)
	module.stl = &stl{}
	module.sanitize = &sanitize{}
	return module
}

func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
	ctx := &moduleContext{
		ModuleContext: actx,
		moduleContextImpl: moduleContextImpl{
			mod: c,
		},
	}
	ctx.ctx = ctx

	if c.Customizer != nil {
		c.Customizer.Flags(ctx)
	}

	flags := Flags{
		Toolchain: c.toolchain(ctx),
		Clang:     c.clang(ctx),
	}
	if c.compiler != nil {
		flags = c.compiler.flags(ctx, flags)
	}
	if c.linker != nil {
		flags = c.linker.flags(ctx, flags)
	}
	if c.stl != nil {
		flags = c.stl.flags(ctx, flags)
	}
	if c.sanitize != nil {
		flags = c.sanitize.flags(ctx, flags)
	}
	for _, feature := range c.features {
		flags = feature.flags(ctx, flags)
	}
	if ctx.Failed() {
		return
	}

	flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
	flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
	flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)

	// Optimization to reduce size of build.ninja
	// Replace the long list of flags for each file with a module-local variable
	ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
	ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
	ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
	flags.CFlags = []string{"$cflags"}
	flags.CppFlags = []string{"$cppflags"}
	flags.AsFlags = []string{"$asflags"}

	deps := c.depsToPaths(ctx)
	if ctx.Failed() {
		return
	}

	flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...)

	var objFiles android.Paths
	if c.compiler != nil {
		objFiles = c.compiler.compile(ctx, flags, deps)
		if ctx.Failed() {
			return
		}
	}

	if c.linker != nil {
		outputFile := c.linker.link(ctx, flags, deps, objFiles)
		if ctx.Failed() {
			return
		}
		c.outputFile = android.OptionalPathForPath(outputFile)

		if c.installer != nil && c.linker.installable() {
			c.installer.install(ctx, outputFile)
			if ctx.Failed() {
				return
			}
		}
	}
}

func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
	if c.cachedToolchain == nil {
		arch := ctx.Arch()
		os := ctx.Os()
		factory := toolchainFactories[os][arch.ArchType]
		if factory == nil {
			ctx.ModuleErrorf("Toolchain not found for %s arch %q", os.String(), arch.String())
			return nil
		}
		c.cachedToolchain = factory(arch)
	}
	return c.cachedToolchain
}

func (c *Module) begin(ctx BaseModuleContext) {
	if c.compiler != nil {
		c.compiler.begin(ctx)
	}
	if c.linker != nil {
		c.linker.begin(ctx)
	}
	if c.stl != nil {
		c.stl.begin(ctx)
	}
	if c.sanitize != nil {
		c.sanitize.begin(ctx)
	}
	for _, feature := range c.features {
		feature.begin(ctx)
	}
}

func (c *Module) deps(ctx BaseModuleContext) Deps {
	deps := Deps{}

	if c.compiler != nil {
		deps = c.compiler.deps(ctx, deps)
	}
	if c.linker != nil {
		deps = c.linker.deps(ctx, deps)
	}
	if c.stl != nil {
		deps = c.stl.deps(ctx, deps)
	}
	if c.sanitize != nil {
		deps = c.sanitize.deps(ctx, deps)
	}
	for _, feature := range c.features {
		deps = feature.deps(ctx, deps)
	}

	deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
	deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
	deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
	deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
	deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)

	for _, lib := range deps.ReexportSharedLibHeaders {
		if !inList(lib, deps.SharedLibs) {
			ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib)
		}
	}

	for _, lib := range deps.ReexportStaticLibHeaders {
		if !inList(lib, deps.StaticLibs) {
			ctx.PropertyErrorf("export_static_lib_headers", "Static library not in static_libs: '%s'", lib)
		}
	}

	return deps
}

func (c *Module) depsMutator(actx android.BottomUpMutatorContext) {
	ctx := &baseModuleContext{
		BaseContext: actx,
		moduleContextImpl: moduleContextImpl{
			mod: c,
		},
	}
	ctx.ctx = ctx

	c.begin(ctx)

	deps := c.deps(ctx)

	c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, deps.SharedLibs...)
	c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, deps.LateSharedLibs...)

	if ctx.sdk() {
		version := "." + ctx.sdkVersion()

		rewriteNdkLibs := func(list []string) []string {
			for i, entry := range list {
				if inList(entry, ndkPrebuiltSharedLibraries) {
					list[i] = "ndk_" + entry + version
				}
			}
			return list
		}

		deps.SharedLibs = rewriteNdkLibs(deps.SharedLibs)
		deps.LateSharedLibs = rewriteNdkLibs(deps.LateSharedLibs)
	}

	actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
		deps.WholeStaticLibs...)

	for _, lib := range deps.StaticLibs {
		depTag := staticDepTag
		if inList(lib, deps.ReexportStaticLibHeaders) {
			depTag = staticExportDepTag
		}
		actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, depTag, lib)
	}

	actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
		deps.LateStaticLibs...)

	for _, lib := range deps.SharedLibs {
		depTag := sharedDepTag
		if inList(lib, deps.ReexportSharedLibHeaders) {
			depTag = sharedExportDepTag
		}
		actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, depTag, lib)
	}

	actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
		deps.LateSharedLibs...)

	actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
	actx.AddDependency(c, genHeaderDepTag, deps.GeneratedHeaders...)

	actx.AddDependency(c, objDepTag, deps.ObjFiles...)

	if deps.CrtBegin != "" {
		actx.AddDependency(c, crtBeginDepTag, deps.CrtBegin)
	}
	if deps.CrtEnd != "" {
		actx.AddDependency(c, crtEndDepTag, deps.CrtEnd)
	}
}

func depsMutator(ctx android.BottomUpMutatorContext) {
	if c, ok := ctx.Module().(*Module); ok && c.Enabled() {
		c.depsMutator(ctx)
	}
}

func (c *Module) clang(ctx BaseModuleContext) bool {
	clang := Bool(c.Properties.Clang)

	if c.Properties.Clang == nil {
		if ctx.Host() {
			clang = true
		}

		if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
			clang = true
		}
	}

	if !c.toolchain(ctx).ClangSupported() {
		clang = false
	}

	return clang
}

// Convert dependencies to paths.  Returns a PathDeps containing paths
func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
	var depPaths PathDeps

	// Whether a module can link to another module, taking into
	// account NDK linking.
	linkTypeOk := func(from, to *Module) bool {
		if from.Target().Os != android.Android {
			// Host code is not restricted
			return true
		}
		if from.Properties.Sdk_version == "" {
			// Platform code can link to anything
			return true
		}
		if _, ok := to.linker.(*toolchainLibraryLinker); ok {
			// These are always allowed
			return true
		}
		if _, ok := to.linker.(*ndkPrebuiltLibraryLinker); ok {
			// These are allowed, but don't set sdk_version
			return true
		}
		if _, ok := to.linker.(*ndkPrebuiltStlLinker); ok {
			// These are allowed, but don't set sdk_version
			return true
		}
		return to.Properties.Sdk_version != ""
	}

	ctx.VisitDirectDeps(func(m blueprint.Module) {
		name := ctx.OtherModuleName(m)
		tag := ctx.OtherModuleDependencyTag(m)

		a, _ := m.(android.Module)
		if a == nil {
			ctx.ModuleErrorf("module %q not an android module", name)
			return
		}

		cc, _ := m.(*Module)
		if cc == nil {
			switch tag {
			case android.DefaultsDepTag:
			case genSourceDepTag:
				if genRule, ok := m.(genrule.SourceFileGenerator); ok {
					depPaths.GeneratedSources = append(depPaths.GeneratedSources,
						genRule.GeneratedSourceFiles()...)
				} else {
					ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
				}
			case genHeaderDepTag:
				if genRule, ok := m.(genrule.SourceFileGenerator); ok {
					depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
						genRule.GeneratedSourceFiles()...)
					depPaths.Flags = append(depPaths.Flags,
						includeDirsToFlags(android.Paths{genRule.GeneratedHeaderDir()}))
				} else {
					ctx.ModuleErrorf("module %q is not a genrule", name)
				}
			default:
				ctx.ModuleErrorf("depends on non-cc module %q", name)
			}
			return
		}

		if !a.Enabled() {
			ctx.ModuleErrorf("depends on disabled module %q", name)
			return
		}

		if a.Target().Os != ctx.Os() {
			ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), name)
			return
		}

		if a.Target().Arch.ArchType != ctx.Arch().ArchType {
			ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), name)
			return
		}

		if !cc.outputFile.Valid() {
			ctx.ModuleErrorf("module %q missing output file", name)
			return
		}

		if tag == reuseObjTag {
			depPaths.ObjFiles = append(depPaths.ObjFiles,
				cc.compiler.(*libraryCompiler).reuseObjFiles...)
			return
		}

		if t, ok := tag.(dependencyTag); ok && t.library {
			if i, ok := cc.linker.(exportedFlagsProducer); ok {
				flags := i.exportedFlags()
				depPaths.Flags = append(depPaths.Flags, flags...)

				if t.reexportFlags {
					depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
				}
			}

			if !linkTypeOk(c, cc) {
				ctx.ModuleErrorf("depends on non-NDK-built library %q", name)
			}
		}

		var depPtr *android.Paths

		switch tag {
		case sharedDepTag, sharedExportDepTag:
			depPtr = &depPaths.SharedLibs
		case lateSharedDepTag:
			depPtr = &depPaths.LateSharedLibs
		case staticDepTag, staticExportDepTag:
			depPtr = &depPaths.StaticLibs
		case lateStaticDepTag:
			depPtr = &depPaths.LateStaticLibs
		case wholeStaticDepTag:
			depPtr = &depPaths.WholeStaticLibs
			staticLib, _ := cc.linker.(libraryInterface)
			if staticLib == nil || !staticLib.static() {
				ctx.ModuleErrorf("module %q not a static library", name)
				return
			}

			if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
				postfix := " (required by " + ctx.OtherModuleName(m) + ")"
				for i := range missingDeps {
					missingDeps[i] += postfix
				}
				ctx.AddMissingDependencies(missingDeps)
			}
			depPaths.WholeStaticLibObjFiles =
				append(depPaths.WholeStaticLibObjFiles, staticLib.objs()...)
		case objDepTag:
			depPtr = &depPaths.ObjFiles
		case crtBeginDepTag:
			depPaths.CrtBegin = cc.outputFile
		case crtEndDepTag:
			depPaths.CrtEnd = cc.outputFile
		default:
			panic(fmt.Errorf("unknown dependency tag: %s", tag))
		}

		if depPtr != nil {
			*depPtr = append(*depPtr, cc.outputFile.Path())
		}
	})

	return depPaths
}

func (c *Module) InstallInData() bool {
	if c.installer == nil {
		return false
	}
	return c.installer.inData()
}

// Compiler

type baseCompiler struct {
	Properties BaseCompilerProperties
}

var _ compiler = (*baseCompiler)(nil)

func (compiler *baseCompiler) appendCflags(flags []string) {
	compiler.Properties.Cflags = append(compiler.Properties.Cflags, flags...)
}

func (compiler *baseCompiler) appendAsflags(flags []string) {
	compiler.Properties.Asflags = append(compiler.Properties.Asflags, flags...)
}

func (compiler *baseCompiler) props() []interface{} {
	return []interface{}{&compiler.Properties}
}

func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}

func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps {
	deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
	deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)

	return deps
}

// Create a Flags struct that collects the compile flags from global values,
// per-target values, module type values, and per-module Blueprints properties
func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
	toolchain := ctx.toolchain()

	CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
	CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)

	flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
	flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
	flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
	flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
	flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)

	// Include dir cflags
	rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs)
	localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
	flags.GlobalFlags = append(flags.GlobalFlags,
		includeDirsToFlags(localIncludeDirs),
		includeDirsToFlags(rootIncludeDirs))

	if !ctx.noDefaultCompilerFlags() {
		if !ctx.sdk() || ctx.Host() {
			flags.GlobalFlags = append(flags.GlobalFlags,
				"${commonGlobalIncludes}",
				toolchain.IncludeFlags(),
				"${commonNativehelperInclude}")
		}

		flags.GlobalFlags = append(flags.GlobalFlags, []string{
			"-I" + android.PathForModuleSrc(ctx).String(),
			"-I" + android.PathForModuleOut(ctx).String(),
			"-I" + android.PathForModuleGen(ctx).String(),
		}...)
	}

	instructionSet := compiler.Properties.Instruction_set
	if flags.RequiredInstructionSet != "" {
		instructionSet = flags.RequiredInstructionSet
	}
	instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
	if flags.Clang {
		instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
	}
	if err != nil {
		ctx.ModuleErrorf("%s", err)
	}

	CheckBadCompilerFlags(ctx, "release.cflags", compiler.Properties.Release.Cflags)

	// TODO: debug
	flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)

	if flags.Clang {
		CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
		CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)

		flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
		flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
		flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
		flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
		flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
		flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)

		target := "-target " + toolchain.ClangTriple()
		var gccPrefix string
		if !ctx.Darwin() {
			gccPrefix = "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
		}

		flags.CFlags = append(flags.CFlags, target, gccPrefix)
		flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
		flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
	}

	hod := "host"
	if ctx.Os().Class == android.Device {
		hod = "device"
	}

	if !ctx.noDefaultCompilerFlags() {
		flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)

		if flags.Clang {
			flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
			flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
			flags.GlobalFlags = append(flags.GlobalFlags,
				toolchain.ClangCflags(),
				"${commonClangGlobalCflags}",
				fmt.Sprintf("${%sClangGlobalCflags}", hod))

			flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
		} else {
			flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
			flags.GlobalFlags = append(flags.GlobalFlags,
				toolchain.Cflags(),
				"${commonGlobalCflags}",
				fmt.Sprintf("${%sGlobalCflags}", hod))
		}

		if Bool(ctx.AConfig().ProductVariables.Brillo) {
			flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
		}

		if ctx.Device() {
			if Bool(compiler.Properties.Rtti) {
				flags.CppFlags = append(flags.CppFlags, "-frtti")
			} else {
				flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
			}
		}

		flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")

		if flags.Clang {
			flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
		} else {
			flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
		}
	}

	if flags.Clang {
		flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
	} else {
		flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
	}

	if !ctx.sdk() {
		if ctx.Host() && !flags.Clang {
			// The host GCC doesn't support C++14 (and is deprecated, so likely
			// never will). Build these modules with C++11.
			flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
		} else {
			flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
		}
	}

	// We can enforce some rules more strictly in the code we own. strict
	// indicates if this is code that we can be stricter with. If we have
	// rules that we want to apply to *our* code (but maybe can't for
	// vendor/device specific things), we could extend this to be a ternary
	// value.
	strict := true
	if strings.HasPrefix(android.PathForModuleSrc(ctx).String(), "external/") {
		strict = false
	}

	// Can be used to make some annotations stricter for code we can fix
	// (such as when we mark functions as deprecated).
	if strict {
		flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
	}

	return flags
}

func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
	// Compile files listed in c.Properties.Srcs into objects
	objFiles := compiler.compileObjs(ctx, flags, "",
		compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
		deps.GeneratedSources, deps.GeneratedHeaders)

	if ctx.Failed() {
		return nil
	}

	return objFiles
}

// Compile a list of source files into objects a specified subdirectory
func (compiler *baseCompiler) compileObjs(ctx android.ModuleContext, flags Flags,
	subdir string, srcFiles, excludes []string, extraSrcs, deps android.Paths) android.Paths {

	buildFlags := flagsToBuilderFlags(flags)

	inputFiles := ctx.ExpandSources(srcFiles, excludes)
	inputFiles = append(inputFiles, extraSrcs...)
	srcPaths, gendeps := genSources(ctx, inputFiles, buildFlags)

	deps = append(deps, gendeps...)
	deps = append(deps, flags.CFlagsDeps...)

	return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
}

// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
type baseLinker struct {
	Properties        BaseLinkerProperties
	dynamicProperties struct {
		VariantIsShared       bool     `blueprint:"mutated"`
		VariantIsStatic       bool     `blueprint:"mutated"`
		VariantIsStaticBinary bool     `blueprint:"mutated"`
		RunPaths              []string `blueprint:"mutated"`
	}
}

func (linker *baseLinker) appendLdflags(flags []string) {
	linker.Properties.Ldflags = append(linker.Properties.Ldflags, flags...)
}

func (linker *baseLinker) begin(ctx BaseModuleContext) {
	if ctx.toolchain().Is64Bit() {
		linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
	} else {
		linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
	}
}

func (linker *baseLinker) props() []interface{} {
	return []interface{}{&linker.Properties, &linker.dynamicProperties}
}

func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
	deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
	deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)

	deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, linker.Properties.Export_static_lib_headers...)
	deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, linker.Properties.Export_shared_lib_headers...)

	if !ctx.sdk() && ctx.ModuleName() != "libcompiler_rt-extras" {
		deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt-extras")
	}

	if ctx.Device() {
		// libgcc and libatomic have to be last on the command line
		deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
		if !Bool(linker.Properties.No_libgcc) {
			deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
		}

		if !linker.static() {
			if linker.Properties.System_shared_libs != nil {
				deps.LateSharedLibs = append(deps.LateSharedLibs,
					linker.Properties.System_shared_libs...)
			} else if !ctx.sdk() {
				deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
			}
		}

		if ctx.sdk() {
			deps.SharedLibs = append(deps.SharedLibs,
				"libc",
				"libm",
			)
		}
	}

	return deps
}

func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
	toolchain := ctx.toolchain()

	flags.Nocrt = Bool(linker.Properties.Nocrt)

	if !ctx.noDefaultCompilerFlags() {
		if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
			flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
		}

		if flags.Clang {
			flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
		} else {
			flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
		}

		if ctx.Host() {
			CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs)

			flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
		}
	}

	CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags)

	flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)

	if ctx.Host() && !linker.static() {
		rpath_prefix := `\$$ORIGIN/`
		if ctx.Darwin() {
			rpath_prefix = "@loader_path/"
		}

		for _, rpath := range linker.dynamicProperties.RunPaths {
			flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
		}
	}

	if flags.Clang {
		flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
	} else {
		flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
	}

	return flags
}

func (linker *baseLinker) static() bool {
	return linker.dynamicProperties.VariantIsStatic
}

func (linker *baseLinker) staticBinary() bool {
	return linker.dynamicProperties.VariantIsStaticBinary
}

func (linker *baseLinker) setStatic(static bool) {
	linker.dynamicProperties.VariantIsStatic = static
}

func (linker *baseLinker) isDependencyRoot() bool {
	return false
}

type baseLinkerInterface interface {
	// Returns true if the build options for the module have selected a static or shared build
	buildStatic() bool
	buildShared() bool

	// Sets whether a specific variant is static or shared
	setStatic(bool)

	// Returns whether a specific variant is a static library or binary
	static() bool

	// Returns whether a module is a static binary
	staticBinary() bool

	// Returns true for dependency roots (binaries)
	// TODO(ccross): also handle dlopenable libraries
	isDependencyRoot() bool
}

type baseInstaller struct {
	Properties InstallerProperties

	dir   string
	dir64 string
	data  bool

	path android.OutputPath
}

var _ installer = (*baseInstaller)(nil)

func (installer *baseInstaller) props() []interface{} {
	return []interface{}{&installer.Properties}
}

func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) {
	subDir := installer.dir
	if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
		subDir = installer.dir64
	}
	if !ctx.Host() && !ctx.Arch().Native {
		subDir = filepath.Join(subDir, ctx.Arch().ArchType.String())
	}
	dir := android.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
	installer.path = ctx.InstallFile(dir, file)
	for _, symlink := range installer.Properties.Symlinks {
		ctx.InstallSymlink(dir, symlink, installer.path)
	}
}

func (installer *baseInstaller) inData() bool {
	return installer.data
}

//
// Combined static+shared libraries
//

type flagExporter struct {
	Properties FlagExporterProperties

	flags []string
}

func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
	includeDirs := android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
	for _, dir := range includeDirs.Strings() {
		f.flags = append(f.flags, inc+dir)
	}
}

func (f *flagExporter) reexportFlags(flags []string) {
	f.flags = append(f.flags, flags...)
}

func (f *flagExporter) exportedFlags() []string {
	return f.flags
}

type exportedFlagsProducer interface {
	exportedFlags() []string
}

var _ exportedFlagsProducer = (*flagExporter)(nil)

type libraryCompiler struct {
	baseCompiler

	linker     *libraryLinker
	Properties LibraryCompilerProperties

	// For reusing static library objects for shared library
	reuseObjFiles android.Paths
}

var _ compiler = (*libraryCompiler)(nil)

func (library *libraryCompiler) props() []interface{} {
	props := library.baseCompiler.props()
	return append(props, &library.Properties)
}

func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
	flags = library.baseCompiler.flags(ctx, flags)

	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
	// all code is position independent, and then those warnings get promoted to
	// errors.
	if ctx.Os() != android.Windows {
		flags.CFlags = append(flags.CFlags, "-fPIC")
	}

	if library.linker.static() {
		flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
	} else {
		flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
	}

	return flags
}

func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
	var objFiles android.Paths

	objFiles = library.baseCompiler.compile(ctx, flags, deps)
	library.reuseObjFiles = objFiles

	if library.linker.static() {
		objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceStaticLibrary,
			library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
			nil, deps.GeneratedHeaders)...)
	} else {
		objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceSharedLibrary,
			library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
			nil, deps.GeneratedHeaders)...)
	}

	return objFiles
}

type libraryLinker struct {
	baseLinker
	flagExporter
	stripper

	Properties LibraryLinkerProperties

	dynamicProperties struct {
		BuildStatic bool `blueprint:"mutated"`
		BuildShared bool `blueprint:"mutated"`
	}

	// If we're used as a whole_static_lib, our missing dependencies need
	// to be given
	wholeStaticMissingDeps []string

	// For whole_static_libs
	objFiles android.Paths
}

var _ linker = (*libraryLinker)(nil)

type libraryInterface interface {
	getWholeStaticMissingDeps() []string
	static() bool
	objs() android.Paths
}

func (library *libraryLinker) props() []interface{} {
	props := library.baseLinker.props()
	return append(props,
		&library.Properties,
		&library.dynamicProperties,
		&library.flagExporter.Properties,
		&library.stripper.StripProperties)
}

func (library *libraryLinker) getLibName(ctx ModuleContext) string {
	name := ctx.ModuleName()

	if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
		if !strings.HasSuffix(name, "-host") {
			name = name + "-host"
		}
	}

	return name + library.Properties.VariantName
}

func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
	flags = library.baseLinker.flags(ctx, flags)

	if !library.static() {
		libName := library.getLibName(ctx)
		// GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
		sharedFlag := "-Wl,-shared"
		if flags.Clang || ctx.Host() {
			sharedFlag = "-shared"
		}
		var f []string
		if ctx.Device() {
			f = append(f,
				"-nostdlib",
				"-Wl,--gc-sections",
			)
		}

		if ctx.Darwin() {
			f = append(f,
				"-dynamiclib",
				"-single_module",
				//"-read_only_relocs suppress",
				"-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
			)
		} else {
			f = append(f,
				sharedFlag,
				"-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
		}

		flags.LdFlags = append(f, flags.LdFlags...)
	}

	return flags
}

func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	deps = library.baseLinker.deps(ctx, deps)
	if library.static() {
		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
		deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
		deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
	} else {
		if ctx.Device() && !Bool(library.baseLinker.Properties.Nocrt) {
			if !ctx.sdk() {
				deps.CrtBegin = "crtbegin_so"
				deps.CrtEnd = "crtend_so"
			} else {
				deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
				deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
			}
		}
		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
		deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
		deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
	}

	return deps
}

func (library *libraryLinker) linkStatic(ctx ModuleContext,
	flags Flags, deps PathDeps, objFiles android.Paths) android.Path {

	library.objFiles = append(android.Paths{}, deps.WholeStaticLibObjFiles...)
	library.objFiles = append(library.objFiles, objFiles...)

	outputFile := android.PathForModuleOut(ctx,
		ctx.ModuleName()+library.Properties.VariantName+staticLibraryExtension)

	if ctx.Darwin() {
		TransformDarwinObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
	} else {
		TransformObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
	}

	library.wholeStaticMissingDeps = ctx.GetMissingDependencies()

	ctx.CheckbuildFile(outputFile)

	return outputFile
}

func (library *libraryLinker) linkShared(ctx ModuleContext,
	flags Flags, deps PathDeps, objFiles android.Paths) android.Path {

	var linkerDeps android.Paths

	versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
	unexportedSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
	forceNotWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
	forceWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
	if !ctx.Darwin() {
		if versionScript.Valid() {
			flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
			linkerDeps = append(linkerDeps, versionScript.Path())
		}
		if unexportedSymbols.Valid() {
			ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
		}
		if forceNotWeakSymbols.Valid() {
			ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
		}
		if forceWeakSymbols.Valid() {
			ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
		}
	} else {
		if versionScript.Valid() {
			ctx.PropertyErrorf("version_script", "Not supported on Darwin")
		}
		if unexportedSymbols.Valid() {
			flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
			linkerDeps = append(linkerDeps, unexportedSymbols.Path())
		}
		if forceNotWeakSymbols.Valid() {
			flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
			linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
		}
		if forceWeakSymbols.Valid() {
			flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
			linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
		}
	}

	fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
	outputFile := android.PathForModuleOut(ctx, fileName)
	ret := outputFile

	builderFlags := flagsToBuilderFlags(flags)

	if library.stripper.needsStrip(ctx) {
		strippedOutputFile := outputFile
		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
		library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
	}

	sharedLibs := deps.SharedLibs
	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)

	TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
		deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
		linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)

	return ret
}

func (library *libraryLinker) link(ctx ModuleContext,
	flags Flags, deps PathDeps, objFiles android.Paths) android.Path {

	objFiles = append(objFiles, deps.ObjFiles...)

	var out android.Path
	if library.static() {
		out = library.linkStatic(ctx, flags, deps, objFiles)
	} else {
		out = library.linkShared(ctx, flags, deps, objFiles)
	}

	library.exportIncludes(ctx, "-I")
	library.reexportFlags(deps.ReexportedFlags)

	return out
}

func (library *libraryLinker) buildStatic() bool {
	return library.dynamicProperties.BuildStatic &&
		(library.Properties.Static.Enabled == nil || *library.Properties.Static.Enabled)
}

func (library *libraryLinker) buildShared() bool {
	return library.dynamicProperties.BuildShared &&
		(library.Properties.Shared.Enabled == nil || *library.Properties.Shared.Enabled)
}

func (library *libraryLinker) getWholeStaticMissingDeps() []string {
	return library.wholeStaticMissingDeps
}

func (library *libraryLinker) installable() bool {
	return !library.static()
}

func (library *libraryLinker) objs() android.Paths {
	return library.objFiles
}

type libraryInstaller struct {
	baseInstaller

	linker   *libraryLinker
	sanitize *sanitize
}

func (library *libraryInstaller) install(ctx ModuleContext, file android.Path) {
	if !library.linker.static() {
		library.baseInstaller.install(ctx, file)
	}
}

func (library *libraryInstaller) inData() bool {
	return library.baseInstaller.inData() || library.sanitize.inData()
}

func NewLibrary(hod android.HostOrDeviceSupported, shared, static bool) *Module {
	module := newModule(hod, android.MultilibBoth)

	linker := &libraryLinker{}
	linker.dynamicProperties.BuildShared = shared
	linker.dynamicProperties.BuildStatic = static
	module.linker = linker

	module.compiler = &libraryCompiler{
		linker: linker,
	}
	module.installer = &libraryInstaller{
		baseInstaller: baseInstaller{
			dir:   "lib",
			dir64: "lib64",
		},
		linker:   linker,
		sanitize: module.sanitize,
	}

	return module
}

func libraryFactory() (blueprint.Module, []interface{}) {
	module := NewLibrary(android.HostAndDeviceSupported, true, true)
	return module.Init()
}

//
// Objects (for crt*.o)
//

type objectLinker struct {
	Properties ObjectLinkerProperties
}

func objectFactory() (blueprint.Module, []interface{}) {
	module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
	module.compiler = &baseCompiler{}
	module.linker = &objectLinker{}
	return module.Init()
}

func (object *objectLinker) appendLdflags(flags []string) {
	panic(fmt.Errorf("appendLdflags on object Linker not supported"))
}

func (object *objectLinker) props() []interface{} {
	return []interface{}{&object.Properties}
}

func (*objectLinker) begin(ctx BaseModuleContext) {}

func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
	return deps
}

func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
	if flags.Clang {
		flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
	} else {
		flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
	}

	return flags
}

func (object *objectLinker) link(ctx ModuleContext,
	flags Flags, deps PathDeps, objFiles android.Paths) android.Path {

	objFiles = append(objFiles, deps.ObjFiles...)

	var outputFile android.Path
	if len(objFiles) == 1 {
		outputFile = objFiles[0]
	} else {
		output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
		TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
		outputFile = output
	}

	ctx.CheckbuildFile(outputFile)
	return outputFile
}

func (*objectLinker) installable() bool {
	return false
}

//
// Executables
//

type binaryLinker struct {
	baseLinker
	stripper

	Properties BinaryLinkerProperties

	hostToolPath android.OptionalPath
}

var _ linker = (*binaryLinker)(nil)

func (binary *binaryLinker) props() []interface{} {
	return append(binary.baseLinker.props(),
		&binary.Properties,
		&binary.stripper.StripProperties)

}

func (binary *binaryLinker) buildStatic() bool {
	return binary.baseLinker.staticBinary()
}

func (binary *binaryLinker) buildShared() bool {
	return !binary.baseLinker.staticBinary()
}

func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
	stem := ctx.ModuleName()
	if binary.Properties.Stem != "" {
		stem = binary.Properties.Stem
	}

	return stem + binary.Properties.Suffix
}

func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	deps = binary.baseLinker.deps(ctx, deps)
	if ctx.Device() {
		if !Bool(binary.baseLinker.Properties.Nocrt) {
			if !ctx.sdk() {
				if binary.buildStatic() {
					deps.CrtBegin = "crtbegin_static"
				} else {
					deps.CrtBegin = "crtbegin_dynamic"
				}
				deps.CrtEnd = "crtend_android"
			} else {
				if binary.buildStatic() {
					deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
				} else {
					if Bool(binary.Properties.Static_executable) {
						deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
					} else {
						deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
					}
					deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
				}
			}
		}

		if binary.buildStatic() {
			if inList("libc++_static", deps.StaticLibs) {
				deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
			}
			// static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
			// --start-group/--end-group along with libgcc.  If they are in deps.StaticLibs,
			// move them to the beginning of deps.LateStaticLibs
			var groupLibs []string
			deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
				[]string{"libc", "libc_nomalloc", "libcompiler_rt"})
			deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
		}
	}

	if binary.buildShared() && inList("libc", deps.StaticLibs) {
		ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
			"from static libs or set static_executable: true")
	}
	return deps
}

func (*binaryLinker) installable() bool {
	return true
}

func (binary *binaryLinker) isDependencyRoot() bool {
	return true
}

func NewBinary(hod android.HostOrDeviceSupported) *Module {
	module := newModule(hod, android.MultilibFirst)
	module.compiler = &baseCompiler{}
	module.linker = &binaryLinker{}
	module.installer = &baseInstaller{
		dir: "bin",
	}
	return module
}

func binaryFactory() (blueprint.Module, []interface{}) {
	module := NewBinary(android.HostAndDeviceSupported)
	return module.Init()
}

func (binary *binaryLinker) begin(ctx BaseModuleContext) {
	binary.baseLinker.begin(ctx)

	static := Bool(binary.Properties.Static_executable)
	if ctx.Host() {
		if ctx.Os() == android.Linux {
			if binary.Properties.Static_executable == nil && Bool(ctx.AConfig().ProductVariables.HostStaticBinaries) {
				static = true
			}
		} else {
			// Static executables are not supported on Darwin or Windows
			static = false
		}
	}
	if static {
		binary.dynamicProperties.VariantIsStatic = true
		binary.dynamicProperties.VariantIsStaticBinary = true
	}
}

func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
	flags = binary.baseLinker.flags(ctx, flags)

	if ctx.Host() && !binary.staticBinary() {
		flags.LdFlags = append(flags.LdFlags, "-pie")
		if ctx.Os() == android.Windows {
			flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
		}
	}

	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
	// all code is position independent, and then those warnings get promoted to
	// errors.
	if ctx.Os() != android.Windows {
		flags.CFlags = append(flags.CFlags, "-fpie")
	}

	if ctx.Device() {
		if binary.buildStatic() {
			// Clang driver needs -static to create static executable.
			// However, bionic/linker uses -shared to overwrite.
			// Linker for x86 targets does not allow coexistance of -static and -shared,
			// so we add -static only if -shared is not used.
			if !inList("-shared", flags.LdFlags) {
				flags.LdFlags = append(flags.LdFlags, "-static")
			}

			flags.LdFlags = append(flags.LdFlags,
				"-nostdlib",
				"-Bstatic",
				"-Wl,--gc-sections",
			)

		} else {
			if flags.DynamicLinker == "" {
				flags.DynamicLinker = "/system/bin/linker"
				if flags.Toolchain.Is64Bit() {
					flags.DynamicLinker += "64"
				}
			}

			flags.LdFlags = append(flags.LdFlags,
				"-pie",
				"-nostdlib",
				"-Bdynamic",
				"-Wl,--gc-sections",
				"-Wl,-z,nocopyreloc",
			)
		}
	} else {
		if binary.staticBinary() {
			flags.LdFlags = append(flags.LdFlags, "-static")
		}
		if ctx.Darwin() {
			flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
		}
	}

	return flags
}

func (binary *binaryLinker) link(ctx ModuleContext,
	flags Flags, deps PathDeps, objFiles android.Paths) android.Path {

	fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
	outputFile := android.PathForModuleOut(ctx, fileName)
	ret := outputFile
	if ctx.Os().Class == android.Host {
		binary.hostToolPath = android.OptionalPathForPath(outputFile)
	}

	var linkerDeps android.Paths

	sharedLibs := deps.SharedLibs
	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)

	if flags.DynamicLinker != "" {
		flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
	}

	builderFlags := flagsToBuilderFlags(flags)

	if binary.stripper.needsStrip(ctx) {
		strippedOutputFile := outputFile
		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
		binary.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
	}

	if binary.Properties.Prefix_symbols != "" {
		afterPrefixSymbols := outputFile
		outputFile = android.PathForModuleOut(ctx, "unprefixed", fileName)
		TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
			flagsToBuilderFlags(flags), afterPrefixSymbols)
	}

	TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
		deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
		builderFlags, outputFile)

	return ret
}

func (binary *binaryLinker) HostToolPath() android.OptionalPath {
	return binary.hostToolPath
}

type stripper struct {
	StripProperties StripProperties
}

func (stripper *stripper) needsStrip(ctx ModuleContext) bool {
	return !ctx.AConfig().EmbeddedInMake() && !stripper.StripProperties.Strip.None
}

func (stripper *stripper) strip(ctx ModuleContext, in, out android.ModuleOutPath,
	flags builderFlags) {
	if ctx.Darwin() {
		TransformDarwinStrip(ctx, in, out)
	} else {
		flags.stripKeepSymbols = stripper.StripProperties.Strip.Keep_symbols
		// TODO(ccross): don't add gnu debuglink for user builds
		flags.stripAddGnuDebuglink = true
		TransformStrip(ctx, in, out, flags)
	}
}

func testPerSrcMutator(mctx android.BottomUpMutatorContext) {
	if m, ok := mctx.Module().(*Module); ok {
		if test, ok := m.linker.(*testBinaryLinker); ok {
			if Bool(test.testLinker.Properties.Test_per_src) {
				testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
				for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
					testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
				}
				tests := mctx.CreateLocalVariations(testNames...)
				for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
					tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
					tests[i].(*Module).linker.(*testBinaryLinker).binaryLinker.Properties.Stem = testNames[i]
				}
			}
		}
	}
}

type testLinker struct {
	Properties TestLinkerProperties
}

func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
	if !test.Properties.Gtest {
		return flags
	}

	flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
	if ctx.Host() {
		flags.CFlags = append(flags.CFlags, "-O0", "-g")

		switch ctx.Os() {
		case android.Windows:
			flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
		case android.Linux:
			flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
			flags.LdFlags = append(flags.LdFlags, "-lpthread")
		case android.Darwin:
			flags.CFlags = append(flags.CFlags, "-DGTEST_OS_MAC")
			flags.LdFlags = append(flags.LdFlags, "-lpthread")
		}
	} else {
		flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
	}

	return flags
}

func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	if test.Properties.Gtest {
		if ctx.sdk() && ctx.Device() {
			switch ctx.selectedStl() {
			case "ndk_libc++_shared", "ndk_libc++_static":
				deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_libcxx", "libgtest_ndk_libcxx")
			case "ndk_libgnustl_static":
				deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_gnustl", "libgtest_ndk_gnustl")
			default:
				deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk", "libgtest_ndk")
			}
		} else {
			deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
		}
	}
	return deps
}

type testBinaryLinker struct {
	testLinker
	binaryLinker
}

func (test *testBinaryLinker) begin(ctx BaseModuleContext) {
	test.binaryLinker.begin(ctx)
	runpath := "../../lib"
	if ctx.toolchain().Is64Bit() {
		runpath += "64"
	}
	test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
}

func (test *testBinaryLinker) props() []interface{} {
	return append(test.binaryLinker.props(), &test.testLinker.Properties)
}

func (test *testBinaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
	flags = test.binaryLinker.flags(ctx, flags)
	flags = test.testLinker.flags(ctx, flags)
	return flags
}

func (test *testBinaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	deps = test.testLinker.deps(ctx, deps)
	deps = test.binaryLinker.deps(ctx, deps)
	return deps
}

type testLibraryLinker struct {
	testLinker
	*libraryLinker
}

func (test *testLibraryLinker) props() []interface{} {
	return append(test.libraryLinker.props(), &test.testLinker.Properties)
}

func (test *testLibraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
	flags = test.libraryLinker.flags(ctx, flags)
	flags = test.testLinker.flags(ctx, flags)
	return flags
}

func (test *testLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	deps = test.testLinker.deps(ctx, deps)
	deps = test.libraryLinker.deps(ctx, deps)
	return deps
}

type testInstaller struct {
	baseInstaller
}

func (installer *testInstaller) install(ctx ModuleContext, file android.Path) {
	installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
	installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
	installer.baseInstaller.install(ctx, file)
}

func NewTest(hod android.HostOrDeviceSupported) *Module {
	module := newModule(hod, android.MultilibBoth)
	module.compiler = &baseCompiler{}
	linker := &testBinaryLinker{}
	linker.testLinker.Properties.Gtest = true
	module.linker = linker
	module.installer = &testInstaller{
		baseInstaller: baseInstaller{
			dir:   "nativetest",
			dir64: "nativetest64",
			data:  true,
		},
	}
	return module
}

func testFactory() (blueprint.Module, []interface{}) {
	module := NewTest(android.HostAndDeviceSupported)
	return module.Init()
}

func NewTestLibrary(hod android.HostOrDeviceSupported) *Module {
	module := NewLibrary(android.HostAndDeviceSupported, false, true)
	linker := &testLibraryLinker{
		libraryLinker: module.linker.(*libraryLinker),
	}
	linker.testLinker.Properties.Gtest = true
	module.linker = linker
	module.installer = &testInstaller{
		baseInstaller: baseInstaller{
			dir:   "nativetest",
			dir64: "nativetest64",
			data:  true,
		},
	}
	return module
}

func testLibraryFactory() (blueprint.Module, []interface{}) {
	module := NewTestLibrary(android.HostAndDeviceSupported)
	return module.Init()
}

type benchmarkLinker struct {
	testBinaryLinker
}

func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	deps = benchmark.testBinaryLinker.deps(ctx, deps)
	deps.StaticLibs = append(deps.StaticLibs, "libgoogle-benchmark")
	return deps
}

func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
	module := newModule(hod, android.MultilibFirst)
	module.compiler = &baseCompiler{}
	module.linker = &benchmarkLinker{}
	module.installer = &testInstaller{
		baseInstaller: baseInstaller{
			dir:   "nativetest",
			dir64: "nativetest64",
			data:  true,
		},
	}
	return module
}

func benchmarkFactory() (blueprint.Module, []interface{}) {
	module := NewBenchmark(android.HostAndDeviceSupported)
	return module.Init()
}

//
// Static library
//

func libraryStaticFactory() (blueprint.Module, []interface{}) {
	module := NewLibrary(android.HostAndDeviceSupported, false, true)
	return module.Init()
}

//
// Shared libraries
//

func librarySharedFactory() (blueprint.Module, []interface{}) {
	module := NewLibrary(android.HostAndDeviceSupported, true, false)
	return module.Init()
}

//
// Host static library
//

func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
	module := NewLibrary(android.HostSupported, false, true)
	return module.Init()
}

//
// Host Shared libraries
//

func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
	module := NewLibrary(android.HostSupported, true, false)
	return module.Init()
}

//
// Host Binaries
//

func binaryHostFactory() (blueprint.Module, []interface{}) {
	module := NewBinary(android.HostSupported)
	return module.Init()
}

//
// Host Tests
//

func testHostFactory() (blueprint.Module, []interface{}) {
	module := NewTest(android.HostSupported)
	return module.Init()
}

//
// Host Benchmarks
//

func benchmarkHostFactory() (blueprint.Module, []interface{}) {
	module := NewBenchmark(android.HostSupported)
	return module.Init()
}

//
// Defaults
//
type Defaults struct {
	android.ModuleBase
	android.DefaultsModule
}

func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}

func defaultsFactory() (blueprint.Module, []interface{}) {
	module := &Defaults{}

	propertyStructs := []interface{}{
		&BaseProperties{},
		&BaseCompilerProperties{},
		&BaseLinkerProperties{},
		&LibraryCompilerProperties{},
		&FlagExporterProperties{},
		&LibraryLinkerProperties{},
		&BinaryLinkerProperties{},
		&TestLinkerProperties{},
		&UnusedProperties{},
		&StlProperties{},
		&SanitizeProperties{},
		&StripProperties{},
	}

	_, propertyStructs = android.InitAndroidArchModule(module, android.HostAndDeviceDefault,
		android.MultilibDefault, propertyStructs...)

	return android.InitDefaultsModule(module, module, propertyStructs...)
}

//
// Device libraries shipped with gcc
//

type toolchainLibraryLinker struct {
	baseLinker
}

var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)

func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	// toolchain libraries can't have any dependencies
	return deps
}

func (*toolchainLibraryLinker) buildStatic() bool {
	return true
}

func (*toolchainLibraryLinker) buildShared() bool {
	return false
}

func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
	module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
	module.compiler = &baseCompiler{}
	module.linker = &toolchainLibraryLinker{}
	module.Properties.Clang = proptools.BoolPtr(false)
	return module.Init()
}

func (library *toolchainLibraryLinker) link(ctx ModuleContext,
	flags Flags, deps PathDeps, objFiles android.Paths) android.Path {

	libName := ctx.ModuleName() + staticLibraryExtension
	outputFile := android.PathForModuleOut(ctx, libName)

	if flags.Clang {
		ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
	}

	CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)

	ctx.CheckbuildFile(outputFile)

	return outputFile
}

func (*toolchainLibraryLinker) installable() bool {
	return false
}

// NDK prebuilt libraries.
//
// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
// either (with the exception of the shared STLs, which are installed to the app's directory rather
// than to the system image).

func getNdkLibDir(ctx android.ModuleContext, toolchain Toolchain, version string) android.SourcePath {
	suffix := ""
	// Most 64-bit NDK prebuilts store libraries in "lib64", except for arm64 which is not a
	// multilib toolchain and stores the libraries in "lib".
	if toolchain.Is64Bit() && ctx.Arch().ArchType != android.Arm64 {
		suffix = "64"
	}
	return android.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib%s",
		version, toolchain.Name(), suffix))
}

func ndkPrebuiltModuleToPath(ctx android.ModuleContext, toolchain Toolchain,
	ext string, version string) android.Path {

	// NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
	// We want to translate to just NAME.EXT
	name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
	dir := getNdkLibDir(ctx, toolchain, version)
	return dir.Join(ctx, name+ext)
}

type ndkPrebuiltObjectLinker struct {
	objectLinker
}

func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	// NDK objects can't have any dependencies
	return deps
}

func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
	module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
	module.linker = &ndkPrebuiltObjectLinker{}
	module.Properties.HideFromMake = true
	return module.Init()
}

func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
	deps PathDeps, objFiles android.Paths) android.Path {
	// A null build step, but it sets up the output path.
	if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
		ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
	}

	return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
}

type ndkPrebuiltLibraryLinker struct {
	libraryLinker
}

var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
var _ exportedFlagsProducer = (*libraryLinker)(nil)

func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
	return append(ndk.libraryLinker.props(), &ndk.Properties, &ndk.flagExporter.Properties)
}

func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
	// NDK libraries can't have any dependencies
	return deps
}

func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
	module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
	linker := &ndkPrebuiltLibraryLinker{}
	linker.dynamicProperties.BuildShared = true
	module.linker = linker
	module.Properties.HideFromMake = true
	return module.Init()
}

func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
	deps PathDeps, objFiles android.Paths) android.Path {
	// A null build step, but it sets up the output path.
	if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
		ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
	}

	ndk.exportIncludes(ctx, "-isystem")

	return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
		ctx.sdkVersion())
}

// The NDK STLs are slightly different from the prebuilt system libraries:
//     * Are not specific to each platform version.
//     * The libraries are not in a predictable location for each STL.

type ndkPrebuiltStlLinker struct {
	ndkPrebuiltLibraryLinker
}

func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
	module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
	linker := &ndkPrebuiltStlLinker{}
	linker.dynamicProperties.BuildShared = true
	module.linker = linker
	module.Properties.HideFromMake = true
	return module.Init()
}

func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
	module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
	linker := &ndkPrebuiltStlLinker{}
	linker.dynamicProperties.BuildStatic = true
	module.linker = linker
	module.Properties.HideFromMake = true
	return module.Init()
}

func getNdkStlLibDir(ctx android.ModuleContext, toolchain Toolchain, stl string) android.SourcePath {
	gccVersion := toolchain.GccVersion()
	var libDir string
	switch stl {
	case "libstlport":
		libDir = "cxx-stl/stlport/libs"
	case "libc++":
		libDir = "cxx-stl/llvm-libc++/libs"
	case "libgnustl":
		libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
	}

	if libDir != "" {
		ndkSrcRoot := "prebuilts/ndk/current/sources"
		return android.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
	}

	ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
	return android.PathForSource(ctx, "")
}

func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
	deps PathDeps, objFiles android.Paths) android.Path {
	// A null build step, but it sets up the output path.
	if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
		ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
	}

	ndk.exportIncludes(ctx, "-I")

	libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
	libExt := flags.Toolchain.ShlibSuffix()
	if ndk.dynamicProperties.BuildStatic {
		libExt = staticLibraryExtension
	}

	stlName := strings.TrimSuffix(libName, "_shared")
	stlName = strings.TrimSuffix(stlName, "_static")
	libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
	return libDir.Join(ctx, libName+libExt)
}

func linkageMutator(mctx android.BottomUpMutatorContext) {
	if m, ok := mctx.Module().(*Module); ok {
		if m.linker != nil {
			if linker, ok := m.linker.(baseLinkerInterface); ok {
				var modules []blueprint.Module
				if linker.buildStatic() && linker.buildShared() {
					modules = mctx.CreateLocalVariations("static", "shared")
					static := modules[0].(*Module)
					shared := modules[1].(*Module)

					static.linker.(baseLinkerInterface).setStatic(true)
					shared.linker.(baseLinkerInterface).setStatic(false)

					if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
						sharedCompiler := shared.compiler.(*libraryCompiler)
						if len(staticCompiler.Properties.Static.Cflags) == 0 &&
							len(sharedCompiler.Properties.Shared.Cflags) == 0 {
							// Optimize out compiling common .o files twice for static+shared libraries
							mctx.AddInterVariantDependency(reuseObjTag, shared, static)
							sharedCompiler.baseCompiler.Properties.Srcs = nil
							sharedCompiler.baseCompiler.Properties.Generated_sources = nil
						}
					}
				} else if linker.buildStatic() {
					modules = mctx.CreateLocalVariations("static")
					modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
				} else if linker.buildShared() {
					modules = mctx.CreateLocalVariations("shared")
					modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
				} else {
					panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
				}
			}
		}
	}
}

// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
// modifies the slice contents in place, and returns a subslice of the original slice
func lastUniqueElements(list []string) []string {
	totalSkip := 0
	for i := len(list) - 1; i >= totalSkip; i-- {
		skip := 0
		for j := i - 1; j >= totalSkip; j-- {
			if list[i] == list[j] {
				skip++
			} else {
				list[j+skip] = list[j]
			}
		}
		totalSkip += skip
	}
	return list[totalSkip:]
}

var Bool = proptools.Bool
