Home | History | Annotate | Download | only in android
      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 android
     16 
     17 import (
     18 	"fmt"
     19 	"path/filepath"
     20 	"strings"
     21 
     22 	"github.com/google/blueprint"
     23 	"github.com/google/blueprint/pathtools"
     24 )
     25 
     26 var (
     27 	DeviceSharedLibrary = "shared_library"
     28 	DeviceStaticLibrary = "static_library"
     29 	DeviceExecutable    = "executable"
     30 	HostSharedLibrary   = "host_shared_library"
     31 	HostStaticLibrary   = "host_static_library"
     32 	HostExecutable      = "host_executable"
     33 )
     34 
     35 type ModuleBuildParams struct {
     36 	Rule            blueprint.Rule
     37 	Deps            blueprint.Deps
     38 	Depfile         WritablePath
     39 	Output          WritablePath
     40 	Outputs         WritablePaths
     41 	ImplicitOutput  WritablePath
     42 	ImplicitOutputs WritablePaths
     43 	Input           Path
     44 	Inputs          Paths
     45 	Implicit        Path
     46 	Implicits       Paths
     47 	OrderOnly       Paths
     48 	Default         bool
     49 	Args            map[string]string
     50 }
     51 
     52 type androidBaseContext interface {
     53 	Target() Target
     54 	TargetPrimary() bool
     55 	Arch() Arch
     56 	Os() OsType
     57 	Host() bool
     58 	Device() bool
     59 	Darwin() bool
     60 	Debug() bool
     61 	PrimaryArch() bool
     62 	Vendor() bool
     63 	AConfig() Config
     64 	DeviceConfig() DeviceConfig
     65 }
     66 
     67 type BaseContext interface {
     68 	blueprint.BaseModuleContext
     69 	androidBaseContext
     70 }
     71 
     72 type ModuleContext interface {
     73 	blueprint.ModuleContext
     74 	androidBaseContext
     75 
     76 	// Similar to Build, but takes Paths instead of []string,
     77 	// and performs more verification.
     78 	ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
     79 
     80 	ExpandSources(srcFiles, excludes []string) Paths
     81 	ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
     82 	Glob(globPattern string, excludes []string) Paths
     83 
     84 	InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
     85 	InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
     86 	InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
     87 	CheckbuildFile(srcPath Path)
     88 
     89 	AddMissingDependencies(deps []string)
     90 
     91 	InstallInData() bool
     92 	InstallInSanitizerDir() bool
     93 
     94 	RequiredModuleNames() []string
     95 }
     96 
     97 type Module interface {
     98 	blueprint.Module
     99 
    100 	GenerateAndroidBuildActions(ModuleContext)
    101 	DepsMutator(BottomUpMutatorContext)
    102 
    103 	base() *ModuleBase
    104 	Enabled() bool
    105 	Target() Target
    106 	InstallInData() bool
    107 	InstallInSanitizerDir() bool
    108 	SkipInstall()
    109 }
    110 
    111 type nameProperties struct {
    112 	// The name of the module.  Must be unique across all modules.
    113 	Name string
    114 }
    115 
    116 type commonProperties struct {
    117 	Tags []string
    118 
    119 	// emit build rules for this module
    120 	Enabled *bool `android:"arch_variant"`
    121 
    122 	// control whether this module compiles for 32-bit, 64-bit, or both.  Possible values
    123 	// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
    124 	// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
    125 	// platform
    126 	Compile_multilib string `android:"arch_variant"`
    127 
    128 	Target struct {
    129 		Host struct {
    130 			Compile_multilib string
    131 		}
    132 		Android struct {
    133 			Compile_multilib string
    134 		}
    135 	}
    136 
    137 	Default_multilib string `blueprint:"mutated"`
    138 
    139 	// whether this is a proprietary vendor module, and should be installed into /vendor
    140 	Proprietary bool
    141 
    142 	// vendor who owns this module
    143 	Owner string
    144 
    145 	// whether this module is device specific and should be installed into /vendor
    146 	Vendor bool
    147 
    148 	// *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
    149 	// file
    150 	Logtags []string
    151 
    152 	// init.rc files to be installed if this module is installed
    153 	Init_rc []string
    154 
    155 	// names of other modules to install if this module is installed
    156 	Required []string
    157 
    158 	// Set by TargetMutator
    159 	CompileTarget  Target `blueprint:"mutated"`
    160 	CompilePrimary bool   `blueprint:"mutated"`
    161 
    162 	// Set by InitAndroidModule
    163 	HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
    164 	ArchSpecific          bool                  `blueprint:"mutated"`
    165 
    166 	SkipInstall bool `blueprint:"mutated"`
    167 }
    168 
    169 type hostAndDeviceProperties struct {
    170 	Host_supported   *bool
    171 	Device_supported *bool
    172 }
    173 
    174 type Multilib string
    175 
    176 const (
    177 	MultilibBoth    Multilib = "both"
    178 	MultilibFirst   Multilib = "first"
    179 	MultilibCommon  Multilib = "common"
    180 	MultilibDefault Multilib = ""
    181 )
    182 
    183 type HostOrDeviceSupported int
    184 
    185 const (
    186 	_ HostOrDeviceSupported = iota
    187 	HostSupported
    188 	HostSupportedNoCross
    189 	DeviceSupported
    190 	HostAndDeviceSupported
    191 	HostAndDeviceDefault
    192 	NeitherHostNorDeviceSupported
    193 )
    194 
    195 func InitAndroidModule(m Module,
    196 	propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
    197 
    198 	base := m.base()
    199 	base.module = m
    200 
    201 	propertyStructs = append(propertyStructs,
    202 		&base.nameProperties,
    203 		&base.commonProperties,
    204 		&base.variableProperties)
    205 
    206 	return m, propertyStructs
    207 }
    208 
    209 func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
    210 	propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
    211 
    212 	_, propertyStructs = InitAndroidModule(m, propertyStructs...)
    213 
    214 	base := m.base()
    215 	base.commonProperties.HostOrDeviceSupported = hod
    216 	base.commonProperties.Default_multilib = string(defaultMultilib)
    217 	base.commonProperties.ArchSpecific = true
    218 
    219 	switch hod {
    220 	case HostAndDeviceSupported:
    221 		// Default to module to device supported, host not supported, can override in module
    222 		// properties
    223 		base.hostAndDeviceProperties.Device_supported = boolPtr(true)
    224 		fallthrough
    225 	case HostAndDeviceDefault:
    226 		propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
    227 	}
    228 
    229 	return InitArchModule(m, propertyStructs...)
    230 }
    231 
    232 // A ModuleBase object contains the properties that are common to all Android
    233 // modules.  It should be included as an anonymous field in every module
    234 // struct definition.  InitAndroidModule should then be called from the module's
    235 // factory function, and the return values from InitAndroidModule should be
    236 // returned from the factory function.
    237 //
    238 // The ModuleBase type is responsible for implementing the GenerateBuildActions
    239 // method to support the blueprint.Module interface. This method will then call
    240 // the module's GenerateAndroidBuildActions method once for each build variant
    241 // that is to be built. GenerateAndroidBuildActions is passed a
    242 // AndroidModuleContext rather than the usual blueprint.ModuleContext.
    243 // AndroidModuleContext exposes extra functionality specific to the Android build
    244 // system including details about the particular build variant that is to be
    245 // generated.
    246 //
    247 // For example:
    248 //
    249 //     import (
    250 //         "android/soong/android"
    251 //         "github.com/google/blueprint"
    252 //     )
    253 //
    254 //     type myModule struct {
    255 //         android.ModuleBase
    256 //         properties struct {
    257 //             MyProperty string
    258 //         }
    259 //     }
    260 //
    261 //     func NewMyModule() (blueprint.Module, []interface{}) {
    262 //         m := &myModule{}
    263 //         return android.InitAndroidModule(m, &m.properties)
    264 //     }
    265 //
    266 //     func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
    267 //         // Get the CPU architecture for the current build variant.
    268 //         variantArch := ctx.Arch()
    269 //
    270 //         // ...
    271 //     }
    272 type ModuleBase struct {
    273 	// Putting the curiously recurring thing pointing to the thing that contains
    274 	// the thing pattern to good use.
    275 	module Module
    276 
    277 	nameProperties          nameProperties
    278 	commonProperties        commonProperties
    279 	variableProperties      variableProperties
    280 	hostAndDeviceProperties hostAndDeviceProperties
    281 	generalProperties       []interface{}
    282 	archProperties          []interface{}
    283 	customizableProperties  []interface{}
    284 
    285 	noAddressSanitizer bool
    286 	installFiles       Paths
    287 	checkbuildFiles    Paths
    288 
    289 	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
    290 	// Only set on the final variant of each module
    291 	installTarget    string
    292 	checkbuildTarget string
    293 	blueprintDir     string
    294 
    295 	hooks hooks
    296 }
    297 
    298 // Name returns the name of the module.  It may be overridden by individual module types, for
    299 // example prebuilts will prepend prebuilt_ to the name.
    300 func (a *ModuleBase) Name() string {
    301 	return a.nameProperties.Name
    302 }
    303 
    304 // BaseModuleName returns the name of the module as specified in the blueprints file.
    305 func (a *ModuleBase) BaseModuleName() string {
    306 	return a.nameProperties.Name
    307 }
    308 
    309 func (a *ModuleBase) base() *ModuleBase {
    310 	return a
    311 }
    312 
    313 func (a *ModuleBase) SetTarget(target Target, primary bool) {
    314 	a.commonProperties.CompileTarget = target
    315 	a.commonProperties.CompilePrimary = primary
    316 }
    317 
    318 func (a *ModuleBase) Target() Target {
    319 	return a.commonProperties.CompileTarget
    320 }
    321 
    322 func (a *ModuleBase) TargetPrimary() bool {
    323 	return a.commonProperties.CompilePrimary
    324 }
    325 
    326 func (a *ModuleBase) Os() OsType {
    327 	return a.Target().Os
    328 }
    329 
    330 func (a *ModuleBase) Host() bool {
    331 	return a.Os().Class == Host || a.Os().Class == HostCross
    332 }
    333 
    334 func (a *ModuleBase) Arch() Arch {
    335 	return a.Target().Arch
    336 }
    337 
    338 func (a *ModuleBase) ArchSpecific() bool {
    339 	return a.commonProperties.ArchSpecific
    340 }
    341 
    342 func (a *ModuleBase) OsClassSupported() []OsClass {
    343 	switch a.commonProperties.HostOrDeviceSupported {
    344 	case HostSupported:
    345 		return []OsClass{Host, HostCross}
    346 	case HostSupportedNoCross:
    347 		return []OsClass{Host}
    348 	case DeviceSupported:
    349 		return []OsClass{Device}
    350 	case HostAndDeviceSupported:
    351 		var supported []OsClass
    352 		if Bool(a.hostAndDeviceProperties.Host_supported) {
    353 			supported = append(supported, Host, HostCross)
    354 		}
    355 		if Bool(a.hostAndDeviceProperties.Device_supported) {
    356 			supported = append(supported, Device)
    357 		}
    358 		return supported
    359 	default:
    360 		return nil
    361 	}
    362 }
    363 
    364 func (a *ModuleBase) DeviceSupported() bool {
    365 	return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
    366 		a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
    367 			Bool(a.hostAndDeviceProperties.Device_supported)
    368 }
    369 
    370 func (a *ModuleBase) Enabled() bool {
    371 	if a.commonProperties.Enabled == nil {
    372 		return !a.Os().DefaultDisabled
    373 	}
    374 	return *a.commonProperties.Enabled
    375 }
    376 
    377 func (a *ModuleBase) SkipInstall() {
    378 	a.commonProperties.SkipInstall = true
    379 }
    380 
    381 func (a *ModuleBase) computeInstallDeps(
    382 	ctx blueprint.ModuleContext) Paths {
    383 
    384 	result := Paths{}
    385 	ctx.VisitDepsDepthFirstIf(isFileInstaller,
    386 		func(m blueprint.Module) {
    387 			fileInstaller := m.(fileInstaller)
    388 			files := fileInstaller.filesToInstall()
    389 			result = append(result, files...)
    390 		})
    391 
    392 	return result
    393 }
    394 
    395 func (a *ModuleBase) filesToInstall() Paths {
    396 	return a.installFiles
    397 }
    398 
    399 func (p *ModuleBase) NoAddressSanitizer() bool {
    400 	return p.noAddressSanitizer
    401 }
    402 
    403 func (p *ModuleBase) InstallInData() bool {
    404 	return false
    405 }
    406 
    407 func (p *ModuleBase) InstallInSanitizerDir() bool {
    408 	return false
    409 }
    410 
    411 func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
    412 	allInstalledFiles := Paths{}
    413 	allCheckbuildFiles := Paths{}
    414 	ctx.VisitAllModuleVariants(func(module blueprint.Module) {
    415 		a := module.(Module).base()
    416 		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
    417 		allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
    418 	})
    419 
    420 	deps := []string{}
    421 
    422 	if len(allInstalledFiles) > 0 {
    423 		name := ctx.ModuleName() + "-install"
    424 		ctx.Build(pctx, blueprint.BuildParams{
    425 			Rule:      blueprint.Phony,
    426 			Outputs:   []string{name},
    427 			Implicits: allInstalledFiles.Strings(),
    428 			Optional:  ctx.Config().(Config).EmbeddedInMake(),
    429 		})
    430 		deps = append(deps, name)
    431 		a.installTarget = name
    432 	}
    433 
    434 	if len(allCheckbuildFiles) > 0 {
    435 		name := ctx.ModuleName() + "-checkbuild"
    436 		ctx.Build(pctx, blueprint.BuildParams{
    437 			Rule:      blueprint.Phony,
    438 			Outputs:   []string{name},
    439 			Implicits: allCheckbuildFiles.Strings(),
    440 			Optional:  true,
    441 		})
    442 		deps = append(deps, name)
    443 		a.checkbuildTarget = name
    444 	}
    445 
    446 	if len(deps) > 0 {
    447 		suffix := ""
    448 		if ctx.Config().(Config).EmbeddedInMake() {
    449 			suffix = "-soong"
    450 		}
    451 
    452 		ctx.Build(pctx, blueprint.BuildParams{
    453 			Rule:      blueprint.Phony,
    454 			Outputs:   []string{ctx.ModuleName() + suffix},
    455 			Implicits: deps,
    456 			Optional:  true,
    457 		})
    458 
    459 		a.blueprintDir = ctx.ModuleDir()
    460 	}
    461 }
    462 
    463 func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
    464 	return androidBaseContextImpl{
    465 		target:        a.commonProperties.CompileTarget,
    466 		targetPrimary: a.commonProperties.CompilePrimary,
    467 		vendor:        a.commonProperties.Proprietary || a.commonProperties.Vendor,
    468 		config:        ctx.Config().(Config),
    469 	}
    470 }
    471 
    472 func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
    473 	androidCtx := &androidModuleContext{
    474 		module:                 a.module,
    475 		ModuleContext:          ctx,
    476 		androidBaseContextImpl: a.androidBaseContextFactory(ctx),
    477 		installDeps:            a.computeInstallDeps(ctx),
    478 		installFiles:           a.installFiles,
    479 		missingDeps:            ctx.GetMissingDependencies(),
    480 	}
    481 
    482 	if a.Enabled() {
    483 		a.module.GenerateAndroidBuildActions(androidCtx)
    484 		if ctx.Failed() {
    485 			return
    486 		}
    487 
    488 		a.installFiles = append(a.installFiles, androidCtx.installFiles...)
    489 		a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
    490 	}
    491 
    492 	if a == ctx.FinalModule().(Module).base() {
    493 		a.generateModuleTarget(ctx)
    494 		if ctx.Failed() {
    495 			return
    496 		}
    497 	}
    498 }
    499 
    500 type androidBaseContextImpl struct {
    501 	target        Target
    502 	targetPrimary bool
    503 	debug         bool
    504 	vendor        bool
    505 	config        Config
    506 }
    507 
    508 type androidModuleContext struct {
    509 	blueprint.ModuleContext
    510 	androidBaseContextImpl
    511 	installDeps     Paths
    512 	installFiles    Paths
    513 	checkbuildFiles Paths
    514 	missingDeps     []string
    515 	module          Module
    516 }
    517 
    518 func (a *androidModuleContext) ninjaError(outputs []string, err error) {
    519 	a.ModuleContext.Build(pctx, blueprint.BuildParams{
    520 		Rule:     ErrorRule,
    521 		Outputs:  outputs,
    522 		Optional: true,
    523 		Args: map[string]string{
    524 			"error": err.Error(),
    525 		},
    526 	})
    527 	return
    528 }
    529 
    530 func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
    531 	if a.missingDeps != nil {
    532 		a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
    533 			a.ModuleName(), strings.Join(a.missingDeps, ", ")))
    534 		return
    535 	}
    536 
    537 	params.Optional = true
    538 	a.ModuleContext.Build(pctx, params)
    539 }
    540 
    541 func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
    542 	bparams := blueprint.BuildParams{
    543 		Rule:            params.Rule,
    544 		Deps:            params.Deps,
    545 		Outputs:         params.Outputs.Strings(),
    546 		ImplicitOutputs: params.ImplicitOutputs.Strings(),
    547 		Inputs:          params.Inputs.Strings(),
    548 		Implicits:       params.Implicits.Strings(),
    549 		OrderOnly:       params.OrderOnly.Strings(),
    550 		Args:            params.Args,
    551 		Optional:        !params.Default,
    552 	}
    553 
    554 	if params.Depfile != nil {
    555 		bparams.Depfile = params.Depfile.String()
    556 	}
    557 	if params.Output != nil {
    558 		bparams.Outputs = append(bparams.Outputs, params.Output.String())
    559 	}
    560 	if params.ImplicitOutput != nil {
    561 		bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
    562 	}
    563 	if params.Input != nil {
    564 		bparams.Inputs = append(bparams.Inputs, params.Input.String())
    565 	}
    566 	if params.Implicit != nil {
    567 		bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
    568 	}
    569 
    570 	if a.missingDeps != nil {
    571 		a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
    572 			a.ModuleName(), strings.Join(a.missingDeps, ", ")))
    573 		return
    574 	}
    575 
    576 	a.ModuleContext.Build(pctx, bparams)
    577 }
    578 
    579 func (a *androidModuleContext) GetMissingDependencies() []string {
    580 	return a.missingDeps
    581 }
    582 
    583 func (a *androidModuleContext) AddMissingDependencies(deps []string) {
    584 	if deps != nil {
    585 		a.missingDeps = append(a.missingDeps, deps...)
    586 	}
    587 }
    588 
    589 func (a *androidBaseContextImpl) Target() Target {
    590 	return a.target
    591 }
    592 
    593 func (a *androidBaseContextImpl) TargetPrimary() bool {
    594 	return a.targetPrimary
    595 }
    596 
    597 func (a *androidBaseContextImpl) Arch() Arch {
    598 	return a.target.Arch
    599 }
    600 
    601 func (a *androidBaseContextImpl) Os() OsType {
    602 	return a.target.Os
    603 }
    604 
    605 func (a *androidBaseContextImpl) Host() bool {
    606 	return a.target.Os.Class == Host || a.target.Os.Class == HostCross
    607 }
    608 
    609 func (a *androidBaseContextImpl) Device() bool {
    610 	return a.target.Os.Class == Device
    611 }
    612 
    613 func (a *androidBaseContextImpl) Darwin() bool {
    614 	return a.target.Os == Darwin
    615 }
    616 
    617 func (a *androidBaseContextImpl) Debug() bool {
    618 	return a.debug
    619 }
    620 
    621 func (a *androidBaseContextImpl) PrimaryArch() bool {
    622 	return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
    623 }
    624 
    625 func (a *androidBaseContextImpl) AConfig() Config {
    626 	return a.config
    627 }
    628 
    629 func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
    630 	return DeviceConfig{a.config.deviceConfig}
    631 }
    632 
    633 func (a *androidBaseContextImpl) Vendor() bool {
    634 	return a.vendor
    635 }
    636 
    637 func (a *androidModuleContext) InstallInData() bool {
    638 	return a.module.InstallInData()
    639 }
    640 
    641 func (a *androidModuleContext) InstallInSanitizerDir() bool {
    642 	return a.module.InstallInSanitizerDir()
    643 }
    644 
    645 func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
    646 	deps ...Path) OutputPath {
    647 
    648 	fullInstallPath := installPath.Join(a, name)
    649 	a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
    650 
    651 	if !a.module.base().commonProperties.SkipInstall &&
    652 		(!a.Device() || !a.AConfig().SkipDeviceInstall()) {
    653 
    654 		deps = append(deps, a.installDeps...)
    655 
    656 		var implicitDeps, orderOnlyDeps Paths
    657 
    658 		if a.Host() {
    659 			// Installed host modules might be used during the build, depend directly on their
    660 			// dependencies so their timestamp is updated whenever their dependency is updated
    661 			implicitDeps = deps
    662 		} else {
    663 			orderOnlyDeps = deps
    664 		}
    665 
    666 		a.ModuleBuild(pctx, ModuleBuildParams{
    667 			Rule:      Cp,
    668 			Output:    fullInstallPath,
    669 			Input:     srcPath,
    670 			Implicits: implicitDeps,
    671 			OrderOnly: orderOnlyDeps,
    672 			Default:   !a.AConfig().EmbeddedInMake(),
    673 		})
    674 
    675 		a.installFiles = append(a.installFiles, fullInstallPath)
    676 	}
    677 	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
    678 	return fullInstallPath
    679 }
    680 
    681 func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
    682 	return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
    683 }
    684 
    685 func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
    686 	fullInstallPath := installPath.Join(a, name)
    687 	a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
    688 
    689 	if !a.module.base().commonProperties.SkipInstall &&
    690 		(!a.Device() || !a.AConfig().SkipDeviceInstall()) {
    691 
    692 		a.ModuleBuild(pctx, ModuleBuildParams{
    693 			Rule:      Symlink,
    694 			Output:    fullInstallPath,
    695 			OrderOnly: Paths{srcPath},
    696 			Default:   !a.AConfig().EmbeddedInMake(),
    697 			Args: map[string]string{
    698 				"fromPath": srcPath.String(),
    699 			},
    700 		})
    701 
    702 		a.installFiles = append(a.installFiles, fullInstallPath)
    703 		a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
    704 	}
    705 	return fullInstallPath
    706 }
    707 
    708 func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
    709 	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
    710 }
    711 
    712 type fileInstaller interface {
    713 	filesToInstall() Paths
    714 }
    715 
    716 func isFileInstaller(m blueprint.Module) bool {
    717 	_, ok := m.(fileInstaller)
    718 	return ok
    719 }
    720 
    721 func isAndroidModule(m blueprint.Module) bool {
    722 	_, ok := m.(Module)
    723 	return ok
    724 }
    725 
    726 func findStringInSlice(str string, slice []string) int {
    727 	for i, s := range slice {
    728 		if s == str {
    729 			return i
    730 		}
    731 	}
    732 	return -1
    733 }
    734 
    735 func SrcIsModule(s string) string {
    736 	if len(s) > 1 && s[0] == ':' {
    737 		return s[1:]
    738 	}
    739 	return ""
    740 }
    741 
    742 type sourceDependencyTag struct {
    743 	blueprint.BaseDependencyTag
    744 }
    745 
    746 var SourceDepTag sourceDependencyTag
    747 
    748 // Returns a list of modules that must be depended on to satisfy filegroup or generated sources
    749 // modules listed in srcFiles using ":module" syntax
    750 func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
    751 	var deps []string
    752 	for _, s := range srcFiles {
    753 		if m := SrcIsModule(s); m != "" {
    754 			deps = append(deps, m)
    755 		}
    756 	}
    757 
    758 	ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
    759 }
    760 
    761 type SourceFileProducer interface {
    762 	Srcs() Paths
    763 }
    764 
    765 // Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
    766 // ExtractSourcesDeps must have already been called during the dependency resolution phase.
    767 func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
    768 	return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
    769 }
    770 
    771 func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
    772 	prefix := PathForModuleSrc(ctx).String()
    773 
    774 	for i, e := range excludes {
    775 		j := findStringInSlice(e, srcFiles)
    776 		if j != -1 {
    777 			srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
    778 		}
    779 
    780 		excludes[i] = filepath.Join(prefix, e)
    781 	}
    782 
    783 	expandedSrcFiles := make(Paths, 0, len(srcFiles))
    784 	for _, s := range srcFiles {
    785 		if m := SrcIsModule(s); m != "" {
    786 			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
    787 			if srcProducer, ok := module.(SourceFileProducer); ok {
    788 				expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
    789 			} else {
    790 				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
    791 			}
    792 		} else if pathtools.IsGlob(s) {
    793 			globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
    794 			expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
    795 			for i, s := range expandedSrcFiles {
    796 				expandedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
    797 			}
    798 		} else {
    799 			s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
    800 			expandedSrcFiles = append(expandedSrcFiles, s)
    801 		}
    802 	}
    803 
    804 	return expandedSrcFiles
    805 }
    806 
    807 func (ctx *androidModuleContext) RequiredModuleNames() []string {
    808 	return ctx.module.base().commonProperties.Required
    809 }
    810 
    811 func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
    812 	ret, err := ctx.GlobWithDeps(globPattern, excludes)
    813 	if err != nil {
    814 		ctx.ModuleErrorf("glob: %s", err.Error())
    815 	}
    816 	return pathsForModuleSrcFromFullPath(ctx, ret)
    817 }
    818 
    819 func init() {
    820 	RegisterSingletonType("buildtarget", BuildTargetSingleton)
    821 }
    822 
    823 func BuildTargetSingleton() blueprint.Singleton {
    824 	return &buildTargetSingleton{}
    825 }
    826 
    827 type buildTargetSingleton struct{}
    828 
    829 func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
    830 	checkbuildDeps := []string{}
    831 
    832 	dirModules := make(map[string][]string)
    833 
    834 	ctx.VisitAllModules(func(module blueprint.Module) {
    835 		if a, ok := module.(Module); ok {
    836 			blueprintDir := a.base().blueprintDir
    837 			installTarget := a.base().installTarget
    838 			checkbuildTarget := a.base().checkbuildTarget
    839 
    840 			if checkbuildTarget != "" {
    841 				checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
    842 				dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
    843 			}
    844 
    845 			if installTarget != "" {
    846 				dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
    847 			}
    848 		}
    849 	})
    850 
    851 	suffix := ""
    852 	if ctx.Config().(Config).EmbeddedInMake() {
    853 		suffix = "-soong"
    854 	}
    855 
    856 	// Create a top-level checkbuild target that depends on all modules
    857 	ctx.Build(pctx, blueprint.BuildParams{
    858 		Rule:      blueprint.Phony,
    859 		Outputs:   []string{"checkbuild" + suffix},
    860 		Implicits: checkbuildDeps,
    861 		Optional:  true,
    862 	})
    863 
    864 	// Create a mm/<directory> target that depends on all modules in a directory
    865 	dirs := sortedKeys(dirModules)
    866 	for _, dir := range dirs {
    867 		ctx.Build(pctx, blueprint.BuildParams{
    868 			Rule:      blueprint.Phony,
    869 			Outputs:   []string{filepath.Join("mm", dir)},
    870 			Implicits: dirModules[dir],
    871 			// HACK: checkbuild should be an optional build, but force it
    872 			// enabled for now in standalone builds
    873 			Optional: ctx.Config().(Config).EmbeddedInMake(),
    874 		})
    875 	}
    876 }
    877 
    878 type AndroidModulesByName struct {
    879 	slice []Module
    880 	ctx   interface {
    881 		ModuleName(blueprint.Module) string
    882 		ModuleSubDir(blueprint.Module) string
    883 	}
    884 }
    885 
    886 func (s AndroidModulesByName) Len() int { return len(s.slice) }
    887 func (s AndroidModulesByName) Less(i, j int) bool {
    888 	mi, mj := s.slice[i], s.slice[j]
    889 	ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
    890 
    891 	if ni != nj {
    892 		return ni < nj
    893 	} else {
    894 		return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
    895 	}
    896 }
    897 func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }
    898