Home | History | Annotate | Download | only in cc
      1 // Copyright 2015 Google Inc. All rights reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package cc
     16 
     17 // This file contains the module types for compiling C/C++ for Android, and converts the properties
     18 // into the flags and filenames necessary to pass to the compiler.  The final creation of the rules
     19 // is handled in builder.go
     20 
     21 import (
     22 	"strconv"
     23 	"strings"
     24 
     25 	"github.com/google/blueprint"
     26 	"github.com/google/blueprint/proptools"
     27 
     28 	"android/soong/android"
     29 	"android/soong/cc/config"
     30 	"android/soong/genrule"
     31 )
     32 
     33 func init() {
     34 	android.RegisterModuleType("cc_defaults", defaultsFactory)
     35 
     36 	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
     37 		ctx.BottomUp("link", linkageMutator).Parallel()
     38 		ctx.BottomUp("vndk", vndkMutator).Parallel()
     39 		ctx.BottomUp("image", vendorMutator).Parallel()
     40 		ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
     41 		ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
     42 		ctx.BottomUp("begin", beginMutator).Parallel()
     43 	})
     44 
     45 	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
     46 		ctx.TopDown("asan_deps", sanitizerDepsMutator(asan))
     47 		ctx.BottomUp("asan", sanitizerMutator(asan)).Parallel()
     48 
     49 		ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
     50 		ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
     51 
     52 		ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
     53 		ctx.TopDown("vndk_deps", sabiDepsMutator)
     54 	})
     55 
     56 	pctx.Import("android/soong/cc/config")
     57 }
     58 
     59 type Deps struct {
     60 	SharedLibs, LateSharedLibs                  []string
     61 	StaticLibs, LateStaticLibs, WholeStaticLibs []string
     62 	HeaderLibs                                  []string
     63 
     64 	ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
     65 
     66 	ObjFiles []string
     67 
     68 	GeneratedSources []string
     69 	GeneratedHeaders []string
     70 
     71 	ReexportGeneratedHeaders []string
     72 
     73 	CrtBegin, CrtEnd string
     74 }
     75 
     76 type PathDeps struct {
     77 	// Paths to .so files
     78 	SharedLibs, LateSharedLibs android.Paths
     79 	// Paths to the dependencies to use for .so files (.so.toc files)
     80 	SharedLibsDeps, LateSharedLibsDeps android.Paths
     81 	// Paths to .a files
     82 	StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
     83 
     84 	// Paths to .o files
     85 	Objs               Objects
     86 	StaticLibObjs      Objects
     87 	WholeStaticLibObjs Objects
     88 
     89 	// Paths to generated source files
     90 	GeneratedSources android.Paths
     91 	GeneratedHeaders android.Paths
     92 
     93 	Flags, ReexportedFlags []string
     94 	ReexportedFlagsDeps    android.Paths
     95 
     96 	// Paths to crt*.o files
     97 	CrtBegin, CrtEnd android.OptionalPath
     98 }
     99 
    100 type Flags struct {
    101 	GlobalFlags     []string // Flags that apply to C, C++, and assembly source files
    102 	ArFlags         []string // Flags that apply to ar
    103 	AsFlags         []string // Flags that apply to assembly source files
    104 	CFlags          []string // Flags that apply to C and C++ source files
    105 	ToolingCFlags   []string // Flags that apply to C and C++ source files parsed by clang LibTooling tools
    106 	ConlyFlags      []string // Flags that apply to C source files
    107 	CppFlags        []string // Flags that apply to C++ source files
    108 	ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools
    109 	YaccFlags       []string // Flags that apply to Yacc source files
    110 	protoFlags      []string // Flags that apply to proto source files
    111 	aidlFlags       []string // Flags that apply to aidl source files
    112 	rsFlags         []string // Flags that apply to renderscript source files
    113 	LdFlags         []string // Flags that apply to linker command lines
    114 	libFlags        []string // Flags to add libraries early to the link order
    115 	TidyFlags       []string // Flags that apply to clang-tidy
    116 	SAbiFlags       []string // Flags that apply to header-abi-dumper
    117 	YasmFlags       []string // Flags that apply to yasm assembly source files
    118 
    119 	// Global include flags that apply to C, C++, and assembly source files
    120 	// These must be after any module include flags, which will be in GlobalFlags.
    121 	SystemIncludeFlags []string
    122 
    123 	Toolchain config.Toolchain
    124 	Clang     bool
    125 	Tidy      bool
    126 	Coverage  bool
    127 	SAbiDump  bool
    128 
    129 	RequiredInstructionSet string
    130 	DynamicLinker          string
    131 
    132 	CFlagsDeps android.Paths // Files depended on by compiler flags
    133 
    134 	GroupStaticLibs bool
    135 }
    136 
    137 type ObjectLinkerProperties struct {
    138 	// names of other cc_object modules to link into this module using partial linking
    139 	Objs []string `android:"arch_variant"`
    140 }
    141 
    142 // Properties used to compile all C or C++ modules
    143 type BaseProperties struct {
    144 	// compile module with clang instead of gcc
    145 	Clang *bool `android:"arch_variant"`
    146 
    147 	// Minimum sdk version supported when compiling against the ndk
    148 	Sdk_version string
    149 
    150 	// don't insert default compiler flags into asflags, cflags,
    151 	// cppflags, conlyflags, ldflags, or include_dirs
    152 	No_default_compiler_flags *bool
    153 
    154 	// whether this module should be allowed to install onto /vendor as
    155 	// well as /system. The two variants will be built separately, one
    156 	// like normal, and the other limited to the set of libraries and
    157 	// headers that are exposed to /vendor modules.
    158 	//
    159 	// The vendor variant may be used with a different (newer) /system,
    160 	// so it shouldn't have any unversioned runtime dependencies, or
    161 	// make assumptions about the system that may not be true in the
    162 	// future.
    163 	//
    164 	// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
    165 	Vendor_available *bool
    166 
    167 	AndroidMkSharedLibs []string `blueprint:"mutated"`
    168 	HideFromMake        bool     `blueprint:"mutated"`
    169 	PreventInstall      bool     `blueprint:"mutated"`
    170 
    171 	UseVndk bool `blueprint:"mutated"`
    172 }
    173 
    174 type UnusedProperties struct {
    175 	Tags []string
    176 }
    177 
    178 type ModuleContextIntf interface {
    179 	static() bool
    180 	staticBinary() bool
    181 	clang() bool
    182 	toolchain() config.Toolchain
    183 	noDefaultCompilerFlags() bool
    184 	sdk() bool
    185 	sdkVersion() string
    186 	vndk() bool
    187 	isVndk() bool
    188 	isVndkSp() bool
    189 	createVndkSourceAbiDump() bool
    190 	selectedStl() string
    191 	baseModuleName() string
    192 }
    193 
    194 type ModuleContext interface {
    195 	android.ModuleContext
    196 	ModuleContextIntf
    197 }
    198 
    199 type BaseModuleContext interface {
    200 	android.BaseContext
    201 	ModuleContextIntf
    202 }
    203 
    204 type DepsContext interface {
    205 	android.BottomUpMutatorContext
    206 	ModuleContextIntf
    207 }
    208 
    209 type feature interface {
    210 	begin(ctx BaseModuleContext)
    211 	deps(ctx DepsContext, deps Deps) Deps
    212 	flags(ctx ModuleContext, flags Flags) Flags
    213 	props() []interface{}
    214 }
    215 
    216 type compiler interface {
    217 	compilerInit(ctx BaseModuleContext)
    218 	compilerDeps(ctx DepsContext, deps Deps) Deps
    219 	compilerFlags(ctx ModuleContext, flags Flags) Flags
    220 	compilerProps() []interface{}
    221 
    222 	appendCflags([]string)
    223 	appendAsflags([]string)
    224 	compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects
    225 }
    226 
    227 type linker interface {
    228 	linkerInit(ctx BaseModuleContext)
    229 	linkerDeps(ctx DepsContext, deps Deps) Deps
    230 	linkerFlags(ctx ModuleContext, flags Flags) Flags
    231 	linkerProps() []interface{}
    232 
    233 	link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path
    234 	appendLdflags([]string)
    235 }
    236 
    237 type installer interface {
    238 	installerProps() []interface{}
    239 	install(ctx ModuleContext, path android.Path)
    240 	inData() bool
    241 	inSanitizerDir() bool
    242 	hostToolPath() android.OptionalPath
    243 }
    244 
    245 type dependencyTag struct {
    246 	blueprint.BaseDependencyTag
    247 	name    string
    248 	library bool
    249 
    250 	reexportFlags bool
    251 }
    252 
    253 var (
    254 	sharedDepTag          = dependencyTag{name: "shared", library: true}
    255 	sharedExportDepTag    = dependencyTag{name: "shared", library: true, reexportFlags: true}
    256 	lateSharedDepTag      = dependencyTag{name: "late shared", library: true}
    257 	staticDepTag          = dependencyTag{name: "static", library: true}
    258 	staticExportDepTag    = dependencyTag{name: "static", library: true, reexportFlags: true}
    259 	lateStaticDepTag      = dependencyTag{name: "late static", library: true}
    260 	wholeStaticDepTag     = dependencyTag{name: "whole static", library: true, reexportFlags: true}
    261 	headerDepTag          = dependencyTag{name: "header", library: true}
    262 	headerExportDepTag    = dependencyTag{name: "header", library: true, reexportFlags: true}
    263 	genSourceDepTag       = dependencyTag{name: "gen source"}
    264 	genHeaderDepTag       = dependencyTag{name: "gen header"}
    265 	genHeaderExportDepTag = dependencyTag{name: "gen header", reexportFlags: true}
    266 	objDepTag             = dependencyTag{name: "obj"}
    267 	crtBeginDepTag        = dependencyTag{name: "crtbegin"}
    268 	crtEndDepTag          = dependencyTag{name: "crtend"}
    269 	reuseObjTag           = dependencyTag{name: "reuse objects"}
    270 	ndkStubDepTag         = dependencyTag{name: "ndk stub", library: true}
    271 	ndkLateStubDepTag     = dependencyTag{name: "ndk late stub", library: true}
    272 )
    273 
    274 // Module contains the properties and members used by all C/C++ module types, and implements
    275 // the blueprint.Module interface.  It delegates to compiler, linker, and installer interfaces
    276 // to construct the output file.  Behavior can be customized with a Customizer interface
    277 type Module struct {
    278 	android.ModuleBase
    279 	android.DefaultableModuleBase
    280 
    281 	Properties BaseProperties
    282 	unused     UnusedProperties
    283 
    284 	// initialize before calling Init
    285 	hod      android.HostOrDeviceSupported
    286 	multilib android.Multilib
    287 
    288 	// delegates, initialize before calling Init
    289 	features  []feature
    290 	compiler  compiler
    291 	linker    linker
    292 	installer installer
    293 	stl       *stl
    294 	sanitize  *sanitize
    295 	coverage  *coverage
    296 	sabi      *sabi
    297 	vndkdep   *vndkdep
    298 
    299 	androidMkSharedLibDeps []string
    300 
    301 	outputFile android.OptionalPath
    302 
    303 	cachedToolchain config.Toolchain
    304 
    305 	subAndroidMkOnce map[subAndroidMkProvider]bool
    306 
    307 	// Flags used to compile this module
    308 	flags Flags
    309 }
    310 
    311 func (c *Module) Init() android.Module {
    312 	c.AddProperties(&c.Properties, &c.unused)
    313 	if c.compiler != nil {
    314 		c.AddProperties(c.compiler.compilerProps()...)
    315 	}
    316 	if c.linker != nil {
    317 		c.AddProperties(c.linker.linkerProps()...)
    318 	}
    319 	if c.installer != nil {
    320 		c.AddProperties(c.installer.installerProps()...)
    321 	}
    322 	if c.stl != nil {
    323 		c.AddProperties(c.stl.props()...)
    324 	}
    325 	if c.sanitize != nil {
    326 		c.AddProperties(c.sanitize.props()...)
    327 	}
    328 	if c.coverage != nil {
    329 		c.AddProperties(c.coverage.props()...)
    330 	}
    331 	if c.sabi != nil {
    332 		c.AddProperties(c.sabi.props()...)
    333 	}
    334 	if c.vndkdep != nil {
    335 		c.AddProperties(c.vndkdep.props()...)
    336 	}
    337 	for _, feature := range c.features {
    338 		c.AddProperties(feature.props()...)
    339 	}
    340 
    341 	android.InitAndroidArchModule(c, c.hod, c.multilib)
    342 
    343 	android.InitDefaultableModule(c)
    344 
    345 	return c
    346 }
    347 
    348 // Returns true for dependency roots (binaries)
    349 // TODO(ccross): also handle dlopenable libraries
    350 func (c *Module) isDependencyRoot() bool {
    351 	if root, ok := c.linker.(interface {
    352 		isDependencyRoot() bool
    353 	}); ok {
    354 		return root.isDependencyRoot()
    355 	}
    356 	return false
    357 }
    358 
    359 func (c *Module) vndk() bool {
    360 	return c.Properties.UseVndk
    361 }
    362 
    363 func (c *Module) isVndk() bool {
    364 	if c.vndkdep != nil {
    365 		return c.vndkdep.isVndk()
    366 	}
    367 	return false
    368 }
    369 
    370 type baseModuleContext struct {
    371 	android.BaseContext
    372 	moduleContextImpl
    373 }
    374 
    375 type depsContext struct {
    376 	android.BottomUpMutatorContext
    377 	moduleContextImpl
    378 }
    379 
    380 type moduleContext struct {
    381 	android.ModuleContext
    382 	moduleContextImpl
    383 }
    384 
    385 // Vendor returns true for vendor modules excluding VNDK libraries so that
    386 // they get installed onto the correct partition
    387 func (ctx *moduleContext) Vendor() bool {
    388 	return ctx.ModuleContext.Vendor() || (ctx.mod.vndk() && !ctx.mod.isVndk())
    389 }
    390 
    391 type moduleContextImpl struct {
    392 	mod *Module
    393 	ctx BaseModuleContext
    394 }
    395 
    396 func (ctx *moduleContextImpl) clang() bool {
    397 	return ctx.mod.clang(ctx.ctx)
    398 }
    399 
    400 func (ctx *moduleContextImpl) toolchain() config.Toolchain {
    401 	return ctx.mod.toolchain(ctx.ctx)
    402 }
    403 
    404 func (ctx *moduleContextImpl) static() bool {
    405 	if static, ok := ctx.mod.linker.(interface {
    406 		static() bool
    407 	}); ok {
    408 		return static.static()
    409 	}
    410 	return false
    411 }
    412 
    413 func (ctx *moduleContextImpl) staticBinary() bool {
    414 	if static, ok := ctx.mod.linker.(interface {
    415 		staticBinary() bool
    416 	}); ok {
    417 		return static.staticBinary()
    418 	}
    419 	return false
    420 }
    421 
    422 func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
    423 	return Bool(ctx.mod.Properties.No_default_compiler_flags)
    424 }
    425 
    426 func (ctx *moduleContextImpl) sdk() bool {
    427 	if ctx.ctx.Device() && !ctx.vndk() {
    428 		return ctx.mod.Properties.Sdk_version != ""
    429 	}
    430 	return false
    431 }
    432 
    433 func (ctx *moduleContextImpl) sdkVersion() string {
    434 	if ctx.ctx.Device() {
    435 		if ctx.vndk() {
    436 			return "current"
    437 		} else {
    438 			return ctx.mod.Properties.Sdk_version
    439 		}
    440 	}
    441 	return ""
    442 }
    443 
    444 func (ctx *moduleContextImpl) vndk() bool {
    445 	return ctx.mod.vndk()
    446 }
    447 
    448 func (ctx *moduleContextImpl) isVndk() bool {
    449 	return ctx.mod.isVndk()
    450 }
    451 
    452 func (ctx *moduleContextImpl) isVndkSp() bool {
    453 	if vndk := ctx.mod.vndkdep; vndk != nil {
    454 		return vndk.isVndkSp()
    455 	}
    456 	return false
    457 }
    458 
    459 // Create source abi dumps if the module belongs to the list of VndkLibraries.
    460 func (ctx *moduleContextImpl) createVndkSourceAbiDump() bool {
    461 	return ctx.ctx.Device() && (ctx.mod.isVndk() || inList(ctx.baseModuleName(), llndkLibraries))
    462 }
    463 
    464 func (ctx *moduleContextImpl) selectedStl() string {
    465 	if stl := ctx.mod.stl; stl != nil {
    466 		return stl.Properties.SelectedStl
    467 	}
    468 	return ""
    469 }
    470 
    471 func (ctx *moduleContextImpl) baseModuleName() string {
    472 	return ctx.mod.ModuleBase.BaseModuleName()
    473 }
    474 
    475 func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
    476 	return &Module{
    477 		hod:      hod,
    478 		multilib: multilib,
    479 	}
    480 }
    481 
    482 func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
    483 	module := newBaseModule(hod, multilib)
    484 	module.features = []feature{
    485 		&tidyFeature{},
    486 	}
    487 	module.stl = &stl{}
    488 	module.sanitize = &sanitize{}
    489 	module.coverage = &coverage{}
    490 	module.sabi = &sabi{}
    491 	module.vndkdep = &vndkdep{}
    492 	return module
    493 }
    494 
    495 func (c *Module) Prebuilt() *android.Prebuilt {
    496 	if p, ok := c.linker.(prebuiltLinkerInterface); ok {
    497 		return p.prebuilt()
    498 	}
    499 	return nil
    500 }
    501 
    502 func (c *Module) Name() string {
    503 	name := c.ModuleBase.Name()
    504 	if p, ok := c.linker.(interface {
    505 		Name(string) string
    506 	}); ok {
    507 		name = p.Name(name)
    508 	}
    509 	return name
    510 }
    511 
    512 func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
    513 	ctx := &moduleContext{
    514 		ModuleContext: actx,
    515 		moduleContextImpl: moduleContextImpl{
    516 			mod: c,
    517 		},
    518 	}
    519 	ctx.ctx = ctx
    520 
    521 	flags := Flags{
    522 		Toolchain: c.toolchain(ctx),
    523 		Clang:     c.clang(ctx),
    524 	}
    525 	if c.compiler != nil {
    526 		flags = c.compiler.compilerFlags(ctx, flags)
    527 	}
    528 	if c.linker != nil {
    529 		flags = c.linker.linkerFlags(ctx, flags)
    530 	}
    531 	if c.stl != nil {
    532 		flags = c.stl.flags(ctx, flags)
    533 	}
    534 	if c.sanitize != nil {
    535 		flags = c.sanitize.flags(ctx, flags)
    536 	}
    537 	if c.coverage != nil {
    538 		flags = c.coverage.flags(ctx, flags)
    539 	}
    540 	for _, feature := range c.features {
    541 		flags = feature.flags(ctx, flags)
    542 	}
    543 	if ctx.Failed() {
    544 		return
    545 	}
    546 
    547 	flags.CFlags, _ = filterList(flags.CFlags, config.IllegalFlags)
    548 	flags.CppFlags, _ = filterList(flags.CppFlags, config.IllegalFlags)
    549 	flags.ConlyFlags, _ = filterList(flags.ConlyFlags, config.IllegalFlags)
    550 
    551 	deps := c.depsToPaths(ctx)
    552 	if ctx.Failed() {
    553 		return
    554 	}
    555 	flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...)
    556 	c.flags = flags
    557 	// We need access to all the flags seen by a source file.
    558 	if c.sabi != nil {
    559 		flags = c.sabi.flags(ctx, flags)
    560 	}
    561 	// Optimization to reduce size of build.ninja
    562 	// Replace the long list of flags for each file with a module-local variable
    563 	ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
    564 	ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
    565 	ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
    566 	flags.CFlags = []string{"$cflags"}
    567 	flags.CppFlags = []string{"$cppflags"}
    568 	flags.AsFlags = []string{"$asflags"}
    569 
    570 	var objs Objects
    571 	if c.compiler != nil {
    572 		objs = c.compiler.compile(ctx, flags, deps)
    573 		if ctx.Failed() {
    574 			return
    575 		}
    576 	}
    577 
    578 	if c.linker != nil {
    579 		outputFile := c.linker.link(ctx, flags, deps, objs)
    580 		if ctx.Failed() {
    581 			return
    582 		}
    583 		c.outputFile = android.OptionalPathForPath(outputFile)
    584 	}
    585 
    586 	if c.installer != nil && !c.Properties.PreventInstall && c.outputFile.Valid() {
    587 		c.installer.install(ctx, c.outputFile.Path())
    588 		if ctx.Failed() {
    589 			return
    590 		}
    591 	}
    592 }
    593 
    594 func (c *Module) toolchain(ctx BaseModuleContext) config.Toolchain {
    595 	if c.cachedToolchain == nil {
    596 		c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
    597 	}
    598 	return c.cachedToolchain
    599 }
    600 
    601 func (c *Module) begin(ctx BaseModuleContext) {
    602 	if c.compiler != nil {
    603 		c.compiler.compilerInit(ctx)
    604 	}
    605 	if c.linker != nil {
    606 		c.linker.linkerInit(ctx)
    607 	}
    608 	if c.stl != nil {
    609 		c.stl.begin(ctx)
    610 	}
    611 	if c.sanitize != nil {
    612 		c.sanitize.begin(ctx)
    613 	}
    614 	if c.coverage != nil {
    615 		c.coverage.begin(ctx)
    616 	}
    617 	if c.sabi != nil {
    618 		c.sabi.begin(ctx)
    619 	}
    620 	if c.vndkdep != nil {
    621 		c.vndkdep.begin(ctx)
    622 	}
    623 	for _, feature := range c.features {
    624 		feature.begin(ctx)
    625 	}
    626 	if ctx.sdk() {
    627 		version, err := normalizeNdkApiLevel(ctx.sdkVersion(), ctx.Arch())
    628 		if err != nil {
    629 			ctx.PropertyErrorf("sdk_version", err.Error())
    630 		}
    631 		c.Properties.Sdk_version = version
    632 	}
    633 }
    634 
    635 func (c *Module) deps(ctx DepsContext) Deps {
    636 	deps := Deps{}
    637 
    638 	if c.compiler != nil {
    639 		deps = c.compiler.compilerDeps(ctx, deps)
    640 	}
    641 	if c.linker != nil {
    642 		deps = c.linker.linkerDeps(ctx, deps)
    643 	}
    644 	if c.stl != nil {
    645 		deps = c.stl.deps(ctx, deps)
    646 	}
    647 	if c.sanitize != nil {
    648 		deps = c.sanitize.deps(ctx, deps)
    649 	}
    650 	if c.coverage != nil {
    651 		deps = c.coverage.deps(ctx, deps)
    652 	}
    653 	if c.sabi != nil {
    654 		deps = c.sabi.deps(ctx, deps)
    655 	}
    656 	if c.vndkdep != nil {
    657 		deps = c.vndkdep.deps(ctx, deps)
    658 	}
    659 	for _, feature := range c.features {
    660 		deps = feature.deps(ctx, deps)
    661 	}
    662 
    663 	deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
    664 	deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
    665 	deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
    666 	deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
    667 	deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
    668 	deps.HeaderLibs = lastUniqueElements(deps.HeaderLibs)
    669 
    670 	for _, lib := range deps.ReexportSharedLibHeaders {
    671 		if !inList(lib, deps.SharedLibs) {
    672 			ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib)
    673 		}
    674 	}
    675 
    676 	for _, lib := range deps.ReexportStaticLibHeaders {
    677 		if !inList(lib, deps.StaticLibs) {
    678 			ctx.PropertyErrorf("export_static_lib_headers", "Static library not in static_libs: '%s'", lib)
    679 		}
    680 	}
    681 
    682 	for _, lib := range deps.ReexportHeaderLibHeaders {
    683 		if !inList(lib, deps.HeaderLibs) {
    684 			ctx.PropertyErrorf("export_header_lib_headers", "Header library not in header_libs: '%s'", lib)
    685 		}
    686 	}
    687 
    688 	for _, gen := range deps.ReexportGeneratedHeaders {
    689 		if !inList(gen, deps.GeneratedHeaders) {
    690 			ctx.PropertyErrorf("export_generated_headers", "Generated header module not in generated_headers: '%s'", gen)
    691 		}
    692 	}
    693 
    694 	return deps
    695 }
    696 
    697 func (c *Module) beginMutator(actx android.BottomUpMutatorContext) {
    698 	ctx := &baseModuleContext{
    699 		BaseContext: actx,
    700 		moduleContextImpl: moduleContextImpl{
    701 			mod: c,
    702 		},
    703 	}
    704 	ctx.ctx = ctx
    705 
    706 	c.begin(ctx)
    707 }
    708 
    709 func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
    710 	if !c.Enabled() {
    711 		return
    712 	}
    713 
    714 	ctx := &depsContext{
    715 		BottomUpMutatorContext: actx,
    716 		moduleContextImpl: moduleContextImpl{
    717 			mod: c,
    718 		},
    719 	}
    720 	ctx.ctx = ctx
    721 
    722 	deps := c.deps(ctx)
    723 
    724 	variantNdkLibs := []string{}
    725 	variantLateNdkLibs := []string{}
    726 	if ctx.Os() == android.Android {
    727 		version := ctx.sdkVersion()
    728 
    729 		// Rewrites the names of shared libraries into the names of the NDK
    730 		// libraries where appropriate. This returns two slices.
    731 		//
    732 		// The first is a list of non-variant shared libraries (either rewritten
    733 		// NDK libraries to the modules in prebuilts/ndk, or not rewritten
    734 		// because they are not NDK libraries).
    735 		//
    736 		// The second is a list of ndk_library modules. These need to be
    737 		// separated because they are a variation dependency and must be added
    738 		// in a different manner.
    739 		rewriteNdkLibs := func(list []string) ([]string, []string) {
    740 			variantLibs := []string{}
    741 			nonvariantLibs := []string{}
    742 			for _, entry := range list {
    743 				if ctx.sdk() && inList(entry, ndkPrebuiltSharedLibraries) {
    744 					if !inList(entry, ndkMigratedLibs) {
    745 						nonvariantLibs = append(nonvariantLibs, entry+".ndk."+version)
    746 					} else {
    747 						variantLibs = append(variantLibs, entry+ndkLibrarySuffix)
    748 					}
    749 				} else if ctx.vndk() && inList(entry, llndkLibraries) {
    750 					nonvariantLibs = append(nonvariantLibs, entry+llndkLibrarySuffix)
    751 				} else {
    752 					nonvariantLibs = append(nonvariantLibs, entry)
    753 				}
    754 			}
    755 			return nonvariantLibs, variantLibs
    756 		}
    757 
    758 		deps.SharedLibs, variantNdkLibs = rewriteNdkLibs(deps.SharedLibs)
    759 		deps.LateSharedLibs, variantLateNdkLibs = rewriteNdkLibs(deps.LateSharedLibs)
    760 		deps.ReexportSharedLibHeaders, _ = rewriteNdkLibs(deps.ReexportSharedLibHeaders)
    761 	}
    762 
    763 	for _, lib := range deps.HeaderLibs {
    764 		depTag := headerDepTag
    765 		if inList(lib, deps.ReexportHeaderLibHeaders) {
    766 			depTag = headerExportDepTag
    767 		}
    768 		actx.AddVariationDependencies(nil, depTag, lib)
    769 	}
    770 
    771 	actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
    772 		deps.WholeStaticLibs...)
    773 
    774 	for _, lib := range deps.StaticLibs {
    775 		depTag := staticDepTag
    776 		if inList(lib, deps.ReexportStaticLibHeaders) {
    777 			depTag = staticExportDepTag
    778 		}
    779 		actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, depTag, lib)
    780 	}
    781 
    782 	actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
    783 		deps.LateStaticLibs...)
    784 
    785 	for _, lib := range deps.SharedLibs {
    786 		depTag := sharedDepTag
    787 		if inList(lib, deps.ReexportSharedLibHeaders) {
    788 			depTag = sharedExportDepTag
    789 		}
    790 		actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, depTag, lib)
    791 	}
    792 
    793 	actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
    794 		deps.LateSharedLibs...)
    795 
    796 	actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
    797 
    798 	for _, gen := range deps.GeneratedHeaders {
    799 		depTag := genHeaderDepTag
    800 		if inList(gen, deps.ReexportGeneratedHeaders) {
    801 			depTag = genHeaderExportDepTag
    802 		}
    803 		actx.AddDependency(c, depTag, gen)
    804 	}
    805 
    806 	actx.AddDependency(c, objDepTag, deps.ObjFiles...)
    807 
    808 	if deps.CrtBegin != "" {
    809 		actx.AddDependency(c, crtBeginDepTag, deps.CrtBegin)
    810 	}
    811 	if deps.CrtEnd != "" {
    812 		actx.AddDependency(c, crtEndDepTag, deps.CrtEnd)
    813 	}
    814 
    815 	version := ctx.sdkVersion()
    816 	actx.AddVariationDependencies([]blueprint.Variation{
    817 		{"ndk_api", version}, {"link", "shared"}}, ndkStubDepTag, variantNdkLibs...)
    818 	actx.AddVariationDependencies([]blueprint.Variation{
    819 		{"ndk_api", version}, {"link", "shared"}}, ndkLateStubDepTag, variantLateNdkLibs...)
    820 }
    821 
    822 func beginMutator(ctx android.BottomUpMutatorContext) {
    823 	if c, ok := ctx.Module().(*Module); ok && c.Enabled() {
    824 		c.beginMutator(ctx)
    825 	}
    826 }
    827 
    828 func (c *Module) clang(ctx BaseModuleContext) bool {
    829 	clang := Bool(c.Properties.Clang)
    830 
    831 	if c.Properties.Clang == nil {
    832 		if ctx.Host() {
    833 			clang = true
    834 		}
    835 
    836 		if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
    837 			clang = true
    838 		}
    839 	}
    840 
    841 	if !c.toolchain(ctx).ClangSupported() {
    842 		clang = false
    843 	}
    844 
    845 	return clang
    846 }
    847 
    848 // Convert dependencies to paths.  Returns a PathDeps containing paths
    849 func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
    850 	var depPaths PathDeps
    851 
    852 	// Whether a module can link to another module, taking into
    853 	// account NDK linking.
    854 	checkLinkType := func(from, to *Module) {
    855 		if from.Target().Os != android.Android {
    856 			// Host code is not restricted
    857 			return
    858 		}
    859 		if from.Properties.UseVndk {
    860 			// Though vendor code is limited by the vendor mutator,
    861 			// each vendor-available module needs to check
    862 			// link-type for VNDK.
    863 			if from.vndkdep != nil {
    864 				from.vndkdep.vndkCheckLinkType(ctx, to)
    865 			}
    866 			return
    867 		}
    868 		if from.Properties.Sdk_version == "" {
    869 			// Platform code can link to anything
    870 			return
    871 		}
    872 		if _, ok := to.linker.(*toolchainLibraryDecorator); ok {
    873 			// These are always allowed
    874 			return
    875 		}
    876 		if _, ok := to.linker.(*ndkPrebuiltLibraryLinker); ok {
    877 			// These are allowed, but don't set sdk_version
    878 			return
    879 		}
    880 		if _, ok := to.linker.(*ndkPrebuiltStlLinker); ok {
    881 			// These are allowed, but don't set sdk_version
    882 			return
    883 		}
    884 		if _, ok := to.linker.(*stubDecorator); ok {
    885 			// These aren't real libraries, but are the stub shared libraries that are included in
    886 			// the NDK.
    887 			return
    888 		}
    889 		if to.Properties.Sdk_version == "" {
    890 			// NDK code linking to platform code is never okay.
    891 			ctx.ModuleErrorf("depends on non-NDK-built library %q",
    892 				ctx.OtherModuleName(to))
    893 		}
    894 
    895 		// All this point we know we have two NDK libraries, but we need to
    896 		// check that we're not linking against anything built against a higher
    897 		// API level, as it is only valid to link against older or equivalent
    898 		// APIs.
    899 
    900 		if from.Properties.Sdk_version == "current" {
    901 			// Current can link against anything.
    902 			return
    903 		} else if to.Properties.Sdk_version == "current" {
    904 			// Current can't be linked against by anything else.
    905 			ctx.ModuleErrorf("links %q built against newer API version %q",
    906 				ctx.OtherModuleName(to), "current")
    907 		}
    908 
    909 		fromApi, err := strconv.Atoi(from.Properties.Sdk_version)
    910 		if err != nil {
    911 			ctx.PropertyErrorf("sdk_version",
    912 				"Invalid sdk_version value (must be int): %q",
    913 				from.Properties.Sdk_version)
    914 		}
    915 		toApi, err := strconv.Atoi(to.Properties.Sdk_version)
    916 		if err != nil {
    917 			ctx.PropertyErrorf("sdk_version",
    918 				"Invalid sdk_version value (must be int): %q",
    919 				to.Properties.Sdk_version)
    920 		}
    921 
    922 		if toApi > fromApi {
    923 			ctx.ModuleErrorf("links %q built against newer API version %q",
    924 				ctx.OtherModuleName(to), to.Properties.Sdk_version)
    925 		}
    926 	}
    927 
    928 	ctx.VisitDirectDeps(func(m blueprint.Module) {
    929 		name := ctx.OtherModuleName(m)
    930 		tag := ctx.OtherModuleDependencyTag(m)
    931 
    932 		a, _ := m.(android.Module)
    933 		if a == nil {
    934 			ctx.ModuleErrorf("module %q not an android module", name)
    935 			return
    936 		}
    937 
    938 		cc, _ := m.(*Module)
    939 		if cc == nil {
    940 			switch tag {
    941 			case android.DefaultsDepTag, android.SourceDepTag:
    942 			case genSourceDepTag:
    943 				if genRule, ok := m.(genrule.SourceFileGenerator); ok {
    944 					depPaths.GeneratedSources = append(depPaths.GeneratedSources,
    945 						genRule.GeneratedSourceFiles()...)
    946 				} else {
    947 					ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
    948 				}
    949 				// Support exported headers from a generated_sources dependency
    950 				fallthrough
    951 			case genHeaderDepTag, genHeaderExportDepTag:
    952 				if genRule, ok := m.(genrule.SourceFileGenerator); ok {
    953 					depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
    954 						genRule.GeneratedSourceFiles()...)
    955 					flags := includeDirsToFlags(genRule.GeneratedHeaderDirs())
    956 					depPaths.Flags = append(depPaths.Flags, flags)
    957 					if tag == genHeaderExportDepTag {
    958 						depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags)
    959 						depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps,
    960 							genRule.GeneratedSourceFiles()...)
    961 						// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
    962 						c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags)
    963 
    964 					}
    965 				} else {
    966 					ctx.ModuleErrorf("module %q is not a genrule", name)
    967 				}
    968 			default:
    969 				ctx.ModuleErrorf("depends on non-cc module %q", name)
    970 			}
    971 			return
    972 		}
    973 
    974 		if !a.Enabled() {
    975 			if ctx.AConfig().AllowMissingDependencies() {
    976 				ctx.AddMissingDependencies([]string{name})
    977 			} else {
    978 				ctx.ModuleErrorf("depends on disabled module %q", name)
    979 			}
    980 			return
    981 		}
    982 
    983 		if a.Target().Os != ctx.Os() {
    984 			ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), name)
    985 			return
    986 		}
    987 
    988 		if a.Target().Arch.ArchType != ctx.Arch().ArchType {
    989 			ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), name)
    990 			return
    991 		}
    992 
    993 		if tag == reuseObjTag {
    994 			if l, ok := cc.compiler.(libraryInterface); ok {
    995 				objs, flags, deps := l.reuseObjs()
    996 				depPaths.Objs = depPaths.Objs.Append(objs)
    997 				depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
    998 				depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, deps...)
    999 				return
   1000 			}
   1001 		}
   1002 
   1003 		if t, ok := tag.(dependencyTag); ok && t.library {
   1004 			if i, ok := cc.linker.(exportedFlagsProducer); ok {
   1005 				flags := i.exportedFlags()
   1006 				deps := i.exportedFlagsDeps()
   1007 				depPaths.Flags = append(depPaths.Flags, flags...)
   1008 				depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, deps...)
   1009 
   1010 				if t.reexportFlags {
   1011 					depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
   1012 					depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, deps...)
   1013 					// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
   1014 					// Re-exported flags from shared library dependencies are not included as those shared libraries
   1015 					// will be included in the vndk set.
   1016 					if tag == staticExportDepTag || tag == headerExportDepTag {
   1017 						c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags...)
   1018 					}
   1019 				}
   1020 			}
   1021 
   1022 			checkLinkType(c, cc)
   1023 		}
   1024 
   1025 		var ptr *android.Paths
   1026 		var depPtr *android.Paths
   1027 
   1028 		linkFile := cc.outputFile
   1029 		depFile := android.OptionalPath{}
   1030 
   1031 		switch tag {
   1032 		case ndkStubDepTag, sharedDepTag, sharedExportDepTag:
   1033 			ptr = &depPaths.SharedLibs
   1034 			depPtr = &depPaths.SharedLibsDeps
   1035 			depFile = cc.linker.(libraryInterface).toc()
   1036 		case lateSharedDepTag, ndkLateStubDepTag:
   1037 			ptr = &depPaths.LateSharedLibs
   1038 			depPtr = &depPaths.LateSharedLibsDeps
   1039 			depFile = cc.linker.(libraryInterface).toc()
   1040 		case staticDepTag, staticExportDepTag:
   1041 			ptr = &depPaths.StaticLibs
   1042 		case lateStaticDepTag:
   1043 			ptr = &depPaths.LateStaticLibs
   1044 		case wholeStaticDepTag:
   1045 			ptr = &depPaths.WholeStaticLibs
   1046 			staticLib, ok := cc.linker.(libraryInterface)
   1047 			if !ok || !staticLib.static() {
   1048 				ctx.ModuleErrorf("module %q not a static library", name)
   1049 				return
   1050 			}
   1051 
   1052 			if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
   1053 				postfix := " (required by " + ctx.OtherModuleName(m) + ")"
   1054 				for i := range missingDeps {
   1055 					missingDeps[i] += postfix
   1056 				}
   1057 				ctx.AddMissingDependencies(missingDeps)
   1058 			}
   1059 			depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs())
   1060 		case headerDepTag:
   1061 			// Nothing
   1062 		case objDepTag:
   1063 			depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
   1064 		case crtBeginDepTag:
   1065 			depPaths.CrtBegin = linkFile
   1066 		case crtEndDepTag:
   1067 			depPaths.CrtEnd = linkFile
   1068 		}
   1069 
   1070 		switch tag {
   1071 		case staticDepTag, staticExportDepTag, lateStaticDepTag:
   1072 			staticLib, ok := cc.linker.(libraryInterface)
   1073 			if !ok || !staticLib.static() {
   1074 				ctx.ModuleErrorf("module %q not a static library", name)
   1075 				return
   1076 			}
   1077 
   1078 			// When combining coverage files for shared libraries and executables, coverage files
   1079 			// in static libraries act as if they were whole static libraries. The same goes for
   1080 			// source based Abi dump files.
   1081 			depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
   1082 				staticLib.objs().coverageFiles...)
   1083 			depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
   1084 				staticLib.objs().sAbiDumpFiles...)
   1085 		}
   1086 
   1087 		if ptr != nil {
   1088 			if !linkFile.Valid() {
   1089 				ctx.ModuleErrorf("module %q missing output file", name)
   1090 				return
   1091 			}
   1092 			*ptr = append(*ptr, linkFile.Path())
   1093 		}
   1094 
   1095 		if depPtr != nil {
   1096 			dep := depFile
   1097 			if !dep.Valid() {
   1098 				dep = linkFile
   1099 			}
   1100 			*depPtr = append(*depPtr, dep.Path())
   1101 		}
   1102 
   1103 		// Export the shared libs to the make world. In doing so, .vendor suffix
   1104 		// is added if the lib has both core and vendor variants and this module
   1105 		// is building against vndk. This is because the vendor variant will be
   1106 		// have .vendor suffix in its name in the make world. However, if the
   1107 		// lib is a vendor-only lib or this lib is not building against vndk,
   1108 		// then the suffix is not added.
   1109 		switch tag {
   1110 		case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
   1111 			libName := strings.TrimSuffix(name, llndkLibrarySuffix)
   1112 			libName = strings.TrimPrefix(libName, "prebuilt_")
   1113 			isLLndk := inList(libName, llndkLibraries)
   1114 			if c.vndk() && (Bool(cc.Properties.Vendor_available) || isLLndk) {
   1115 				libName += vendorSuffix
   1116 			}
   1117 			// Note: the order of libs in this list is not important because
   1118 			// they merely serve as dependencies in the make world and do not
   1119 			// affect this lib itself.
   1120 			c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, libName)
   1121 		}
   1122 	})
   1123 
   1124 	// Dedup exported flags from dependencies
   1125 	depPaths.Flags = firstUniqueElements(depPaths.Flags)
   1126 
   1127 	return depPaths
   1128 }
   1129 
   1130 func (c *Module) InstallInData() bool {
   1131 	if c.installer == nil {
   1132 		return false
   1133 	}
   1134 	return c.installer.inData()
   1135 }
   1136 
   1137 func (c *Module) InstallInSanitizerDir() bool {
   1138 	if c.installer == nil {
   1139 		return false
   1140 	}
   1141 	if c.sanitize != nil && c.sanitize.inSanitizerDir() {
   1142 		return true
   1143 	}
   1144 	return c.installer.inSanitizerDir()
   1145 }
   1146 
   1147 func (c *Module) HostToolPath() android.OptionalPath {
   1148 	if c.installer == nil {
   1149 		return android.OptionalPath{}
   1150 	}
   1151 	return c.installer.hostToolPath()
   1152 }
   1153 
   1154 //
   1155 // Defaults
   1156 //
   1157 type Defaults struct {
   1158 	android.ModuleBase
   1159 	android.DefaultsModuleBase
   1160 }
   1161 
   1162 func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
   1163 }
   1164 
   1165 func (d *Defaults) DepsMutator(ctx android.BottomUpMutatorContext) {
   1166 }
   1167 
   1168 func defaultsFactory() android.Module {
   1169 	return DefaultsFactory()
   1170 }
   1171 
   1172 func DefaultsFactory(props ...interface{}) android.Module {
   1173 	module := &Defaults{}
   1174 
   1175 	module.AddProperties(props...)
   1176 	module.AddProperties(
   1177 		&BaseProperties{},
   1178 		&BaseCompilerProperties{},
   1179 		&BaseLinkerProperties{},
   1180 		&LibraryProperties{},
   1181 		&FlagExporterProperties{},
   1182 		&BinaryLinkerProperties{},
   1183 		&TestProperties{},
   1184 		&TestBinaryProperties{},
   1185 		&UnusedProperties{},
   1186 		&StlProperties{},
   1187 		&SanitizeProperties{},
   1188 		&StripProperties{},
   1189 		&InstallerProperties{},
   1190 		&TidyProperties{},
   1191 		&CoverageProperties{},
   1192 		&SAbiProperties{},
   1193 		&VndkProperties{},
   1194 	)
   1195 
   1196 	android.InitDefaultsModule(module)
   1197 
   1198 	return module
   1199 }
   1200 
   1201 const (
   1202 	// coreMode is the variant used for framework-private libraries, or
   1203 	// SDK libraries. (which framework-private libraries can use)
   1204 	coreMode = "core"
   1205 
   1206 	// vendorMode is the variant used for /vendor code that compiles
   1207 	// against the VNDK.
   1208 	vendorMode = "vendor"
   1209 )
   1210 
   1211 func vendorMutator(mctx android.BottomUpMutatorContext) {
   1212 	if mctx.Os() != android.Android {
   1213 		return
   1214 	}
   1215 
   1216 	m, ok := mctx.Module().(*Module)
   1217 	if !ok {
   1218 		return
   1219 	}
   1220 
   1221 	// Sanity check
   1222 	if Bool(m.Properties.Vendor_available) && mctx.Vendor() {
   1223 		mctx.PropertyErrorf("vendor_available",
   1224 			"doesn't make sense at the same time as `vendor: true` or `proprietary: true`")
   1225 		return
   1226 	}
   1227 	if vndk := m.vndkdep; vndk != nil {
   1228 		if vndk.isVndk() && !Bool(m.Properties.Vendor_available) {
   1229 			mctx.PropertyErrorf("vndk",
   1230 				"has to define `vendor_available: true` to enable vndk")
   1231 			return
   1232 		}
   1233 		if !vndk.isVndk() && vndk.isVndkSp() {
   1234 			mctx.PropertyErrorf("vndk",
   1235 				"must set `enabled: true` to set `support_system_process: true`")
   1236 			return
   1237 		}
   1238 	}
   1239 
   1240 	if !mctx.DeviceConfig().CompileVndk() {
   1241 		// If the device isn't compiling against the VNDK, we always
   1242 		// use the core mode.
   1243 		mctx.CreateVariations(coreMode)
   1244 	} else if _, ok := m.linker.(*llndkStubDecorator); ok {
   1245 		// LL-NDK stubs only exist in the vendor variant, since the
   1246 		// real libraries will be used in the core variant.
   1247 		mctx.CreateVariations(vendorMode)
   1248 	} else if Bool(m.Properties.Vendor_available) {
   1249 		// This will be available in both /system and /vendor
   1250 		// or a /system directory that is available to vendor.
   1251 		mod := mctx.CreateVariations(coreMode, vendorMode)
   1252 		mod[1].(*Module).Properties.UseVndk = true
   1253 	} else if mctx.Vendor() && m.Properties.Sdk_version == "" {
   1254 		// This will be available in /vendor only
   1255 		mod := mctx.CreateVariations(vendorMode)
   1256 		mod[0].(*Module).Properties.UseVndk = true
   1257 	} else {
   1258 		// This is either in /system (or similar: /data), or is a
   1259 		// modules built with the NDK. Modules built with the NDK
   1260 		// will be restricted using the existing link type checks.
   1261 		mctx.CreateVariations(coreMode)
   1262 	}
   1263 }
   1264 
   1265 // firstUniqueElements returns all unique elements of a slice, keeping the first copy of each
   1266 // modifies the slice contents in place, and returns a subslice of the original slice
   1267 func firstUniqueElements(list []string) []string {
   1268 	k := 0
   1269 outer:
   1270 	for i := 0; i < len(list); i++ {
   1271 		for j := 0; j < k; j++ {
   1272 			if list[i] == list[j] {
   1273 				continue outer
   1274 			}
   1275 		}
   1276 		list[k] = list[i]
   1277 		k++
   1278 	}
   1279 	return list[:k]
   1280 }
   1281 
   1282 // lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
   1283 // modifies the slice contents in place, and returns a subslice of the original slice
   1284 func lastUniqueElements(list []string) []string {
   1285 	totalSkip := 0
   1286 	for i := len(list) - 1; i >= totalSkip; i-- {
   1287 		skip := 0
   1288 		for j := i - 1; j >= totalSkip; j-- {
   1289 			if list[i] == list[j] {
   1290 				skip++
   1291 			} else {
   1292 				list[j+skip] = list[j]
   1293 			}
   1294 		}
   1295 		totalSkip += skip
   1296 	}
   1297 	return list[totalSkip:]
   1298 }
   1299 
   1300 func getCurrentNdkPrebuiltVersion(ctx DepsContext) string {
   1301 	if ctx.AConfig().PlatformSdkVersionInt() > config.NdkMaxPrebuiltVersionInt {
   1302 		return strconv.Itoa(config.NdkMaxPrebuiltVersionInt)
   1303 	}
   1304 	return ctx.AConfig().PlatformSdkVersion()
   1305 }
   1306 
   1307 var Bool = proptools.Bool
   1308