github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/android/module.go (about)

     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  	"sort"
    21  	"strings"
    22  	"text/scanner"
    23  
    24  	"github.com/google/blueprint"
    25  	"github.com/google/blueprint/pathtools"
    26  )
    27  
    28  var (
    29  	DeviceSharedLibrary = "shared_library"
    30  	DeviceStaticLibrary = "static_library"
    31  	DeviceExecutable    = "executable"
    32  	HostSharedLibrary   = "host_shared_library"
    33  	HostStaticLibrary   = "host_static_library"
    34  	HostExecutable      = "host_executable"
    35  )
    36  
    37  type BuildParams struct {
    38  	Rule            blueprint.Rule
    39  	Deps            blueprint.Deps
    40  	Depfile         WritablePath
    41  	Description     string
    42  	Output          WritablePath
    43  	Outputs         WritablePaths
    44  	ImplicitOutput  WritablePath
    45  	ImplicitOutputs WritablePaths
    46  	Input           Path
    47  	Inputs          Paths
    48  	Implicit        Path
    49  	Implicits       Paths
    50  	OrderOnly       Paths
    51  	Default         bool
    52  	Args            map[string]string
    53  }
    54  
    55  type ModuleBuildParams BuildParams
    56  
    57  type androidBaseContext interface {
    58  	Target() Target
    59  	TargetPrimary() bool
    60  	Arch() Arch
    61  	Os() OsType
    62  	Host() bool
    63  	Device() bool
    64  	Darwin() bool
    65  	Windows() bool
    66  	Debug() bool
    67  	PrimaryArch() bool
    68  	Platform() bool
    69  	DeviceSpecific() bool
    70  	SocSpecific() bool
    71  	ProductSpecific() bool
    72  	AConfig() Config
    73  	DeviceConfig() DeviceConfig
    74  }
    75  
    76  type BaseContext interface {
    77  	BaseModuleContext
    78  	androidBaseContext
    79  }
    80  
    81  // BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
    82  // a Config instead of an interface{}.
    83  type BaseModuleContext interface {
    84  	ModuleName() string
    85  	ModuleDir() string
    86  	Config() Config
    87  
    88  	ContainsProperty(name string) bool
    89  	Errorf(pos scanner.Position, fmt string, args ...interface{})
    90  	ModuleErrorf(fmt string, args ...interface{})
    91  	PropertyErrorf(property, fmt string, args ...interface{})
    92  	Failed() bool
    93  
    94  	// GlobWithDeps returns a list of files that match the specified pattern but do not match any
    95  	// of the patterns in excludes.  It also adds efficient dependencies to rerun the primary
    96  	// builder whenever a file matching the pattern as added or removed, without rerunning if a
    97  	// file that does not match the pattern is added to a searched directory.
    98  	GlobWithDeps(pattern string, excludes []string) ([]string, error)
    99  
   100  	Fs() pathtools.FileSystem
   101  	AddNinjaFileDeps(deps ...string)
   102  }
   103  
   104  type ModuleContext interface {
   105  	androidBaseContext
   106  	BaseModuleContext
   107  
   108  	// Deprecated: use ModuleContext.Build instead.
   109  	ModuleBuild(pctx PackageContext, params ModuleBuildParams)
   110  
   111  	ExpandSources(srcFiles, excludes []string) Paths
   112  	ExpandSource(srcFile, prop string) Path
   113  	ExpandOptionalSource(srcFile *string, prop string) OptionalPath
   114  	ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
   115  	Glob(globPattern string, excludes []string) Paths
   116  	GlobFiles(globPattern string, excludes []string) Paths
   117  
   118  	InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
   119  	InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
   120  	InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
   121  	CheckbuildFile(srcPath Path)
   122  
   123  	AddMissingDependencies(deps []string)
   124  
   125  	InstallInData() bool
   126  	InstallInSanitizerDir() bool
   127  
   128  	RequiredModuleNames() []string
   129  
   130  	// android.ModuleContext methods
   131  	// These are duplicated instead of embedded so that can eventually be wrapped to take an
   132  	// android.Module instead of a blueprint.Module
   133  	OtherModuleName(m blueprint.Module) string
   134  	OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
   135  	OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
   136  
   137  	GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
   138  	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
   139  
   140  	ModuleSubDir() string
   141  
   142  	VisitDirectDepsBlueprint(visit func(blueprint.Module))
   143  	VisitDirectDeps(visit func(Module))
   144  	VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
   145  	VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
   146  	VisitDepsDepthFirst(visit func(Module))
   147  	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
   148  	WalkDeps(visit func(Module, Module) bool)
   149  
   150  	Variable(pctx PackageContext, name, value string)
   151  	Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
   152  	// Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
   153  	// and performs more verification.
   154  	Build(pctx PackageContext, params BuildParams)
   155  
   156  	PrimaryModule() Module
   157  	FinalModule() Module
   158  	VisitAllModuleVariants(visit func(Module))
   159  
   160  	GetMissingDependencies() []string
   161  	Namespace() blueprint.Namespace
   162  }
   163  
   164  type Module interface {
   165  	blueprint.Module
   166  
   167  	// GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
   168  	// but GenerateAndroidBuildActions also has access to Android-specific information.
   169  	// For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
   170  	GenerateAndroidBuildActions(ModuleContext)
   171  
   172  	DepsMutator(BottomUpMutatorContext)
   173  
   174  	base() *ModuleBase
   175  	Enabled() bool
   176  	Target() Target
   177  	InstallInData() bool
   178  	InstallInSanitizerDir() bool
   179  	SkipInstall()
   180  	ExportedToMake() bool
   181  
   182  	AddProperties(props ...interface{})
   183  	GetProperties() []interface{}
   184  
   185  	BuildParamsForTests() []BuildParams
   186  }
   187  
   188  type nameProperties struct {
   189  	// The name of the module.  Must be unique across all modules.
   190  	Name *string
   191  }
   192  
   193  type commonProperties struct {
   194  	Tags []string
   195  
   196  	// emit build rules for this module
   197  	Enabled *bool `android:"arch_variant"`
   198  
   199  	// control whether this module compiles for 32-bit, 64-bit, or both.  Possible values
   200  	// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
   201  	// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
   202  	// platform
   203  	Compile_multilib *string `android:"arch_variant"`
   204  
   205  	Target struct {
   206  		Host struct {
   207  			Compile_multilib *string
   208  		}
   209  		Android struct {
   210  			Compile_multilib *string
   211  		}
   212  	}
   213  
   214  	Default_multilib string `blueprint:"mutated"`
   215  
   216  	// whether this is a proprietary vendor module, and should be installed into /vendor
   217  	Proprietary *bool
   218  
   219  	// vendor who owns this module
   220  	Owner *string
   221  
   222  	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
   223  	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
   224  	// Use `soc_specific` instead for better meaning.
   225  	Vendor *bool
   226  
   227  	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
   228  	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
   229  	Soc_specific *bool
   230  
   231  	// whether this module is specific to a device, not only for SoC, but also for off-chip
   232  	// peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
   233  	// does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
   234  	// This implies `soc_specific:true`.
   235  	Device_specific *bool
   236  
   237  	// whether this module is specific to a software configuration of a product (e.g. country,
   238  	// network operator, etc). When set to true, it is installed into /product (or
   239  	// /system/product if product partition does not exist).
   240  	Product_specific *bool
   241  
   242  	// init.rc files to be installed if this module is installed
   243  	Init_rc []string
   244  
   245  	// names of other modules to install if this module is installed
   246  	Required []string `android:"arch_variant"`
   247  
   248  	// relative path to a file to include in the list of notices for the device
   249  	Notice *string
   250  
   251  	// Set by TargetMutator
   252  	CompileTarget  Target `blueprint:"mutated"`
   253  	CompilePrimary bool   `blueprint:"mutated"`
   254  
   255  	// Set by InitAndroidModule
   256  	HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
   257  	ArchSpecific          bool                  `blueprint:"mutated"`
   258  
   259  	SkipInstall bool `blueprint:"mutated"`
   260  
   261  	NamespaceExportedToMake bool `blueprint:"mutated"`
   262  }
   263  
   264  type hostAndDeviceProperties struct {
   265  	Host_supported   *bool
   266  	Device_supported *bool
   267  }
   268  
   269  type Multilib string
   270  
   271  const (
   272  	MultilibBoth        Multilib = "both"
   273  	MultilibFirst       Multilib = "first"
   274  	MultilibCommon      Multilib = "common"
   275  	MultilibCommonFirst Multilib = "common_first"
   276  	MultilibDefault     Multilib = ""
   277  )
   278  
   279  type HostOrDeviceSupported int
   280  
   281  const (
   282  	_ HostOrDeviceSupported = iota
   283  	HostSupported
   284  	HostSupportedNoCross
   285  	DeviceSupported
   286  	HostAndDeviceSupported
   287  	HostAndDeviceDefault
   288  	NeitherHostNorDeviceSupported
   289  )
   290  
   291  type moduleKind int
   292  
   293  const (
   294  	platformModule moduleKind = iota
   295  	deviceSpecificModule
   296  	socSpecificModule
   297  	productSpecificModule
   298  )
   299  
   300  func (k moduleKind) String() string {
   301  	switch k {
   302  	case platformModule:
   303  		return "platform"
   304  	case deviceSpecificModule:
   305  		return "device-specific"
   306  	case socSpecificModule:
   307  		return "soc-specific"
   308  	case productSpecificModule:
   309  		return "product-specific"
   310  	default:
   311  		panic(fmt.Errorf("unknown module kind %d", k))
   312  	}
   313  }
   314  
   315  func InitAndroidModule(m Module) {
   316  	base := m.base()
   317  	base.module = m
   318  
   319  	m.AddProperties(
   320  		&base.nameProperties,
   321  		&base.commonProperties,
   322  		&base.variableProperties)
   323  }
   324  
   325  func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
   326  	InitAndroidModule(m)
   327  
   328  	base := m.base()
   329  	base.commonProperties.HostOrDeviceSupported = hod
   330  	base.commonProperties.Default_multilib = string(defaultMultilib)
   331  	base.commonProperties.ArchSpecific = true
   332  
   333  	switch hod {
   334  	case HostAndDeviceSupported, HostAndDeviceDefault:
   335  		m.AddProperties(&base.hostAndDeviceProperties)
   336  	}
   337  
   338  	InitArchModule(m)
   339  }
   340  
   341  // A ModuleBase object contains the properties that are common to all Android
   342  // modules.  It should be included as an anonymous field in every module
   343  // struct definition.  InitAndroidModule should then be called from the module's
   344  // factory function, and the return values from InitAndroidModule should be
   345  // returned from the factory function.
   346  //
   347  // The ModuleBase type is responsible for implementing the GenerateBuildActions
   348  // method to support the blueprint.Module interface. This method will then call
   349  // the module's GenerateAndroidBuildActions method once for each build variant
   350  // that is to be built. GenerateAndroidBuildActions is passed a
   351  // AndroidModuleContext rather than the usual blueprint.ModuleContext.
   352  // AndroidModuleContext exposes extra functionality specific to the Android build
   353  // system including details about the particular build variant that is to be
   354  // generated.
   355  //
   356  // For example:
   357  //
   358  //     import (
   359  //         "android/soong/android"
   360  //     )
   361  //
   362  //     type myModule struct {
   363  //         android.ModuleBase
   364  //         properties struct {
   365  //             MyProperty string
   366  //         }
   367  //     }
   368  //
   369  //     func NewMyModule() android.Module) {
   370  //         m := &myModule{}
   371  //         m.AddProperties(&m.properties)
   372  //         android.InitAndroidModule(m)
   373  //         return m
   374  //     }
   375  //
   376  //     func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
   377  //         // Get the CPU architecture for the current build variant.
   378  //         variantArch := ctx.Arch()
   379  //
   380  //         // ...
   381  //     }
   382  type ModuleBase struct {
   383  	// Putting the curiously recurring thing pointing to the thing that contains
   384  	// the thing pattern to good use.
   385  	// TODO: remove this
   386  	module Module
   387  
   388  	nameProperties          nameProperties
   389  	commonProperties        commonProperties
   390  	variableProperties      variableProperties
   391  	hostAndDeviceProperties hostAndDeviceProperties
   392  	generalProperties       []interface{}
   393  	archProperties          []interface{}
   394  	customizableProperties  []interface{}
   395  
   396  	noAddressSanitizer bool
   397  	installFiles       Paths
   398  	checkbuildFiles    Paths
   399  
   400  	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
   401  	// Only set on the final variant of each module
   402  	installTarget    WritablePath
   403  	checkbuildTarget WritablePath
   404  	blueprintDir     string
   405  
   406  	hooks hooks
   407  
   408  	registerProps []interface{}
   409  
   410  	// For tests
   411  	buildParams []BuildParams
   412  }
   413  
   414  func (a *ModuleBase) AddProperties(props ...interface{}) {
   415  	a.registerProps = append(a.registerProps, props...)
   416  }
   417  
   418  func (a *ModuleBase) GetProperties() []interface{} {
   419  	return a.registerProps
   420  }
   421  
   422  func (a *ModuleBase) BuildParamsForTests() []BuildParams {
   423  	return a.buildParams
   424  }
   425  
   426  // Name returns the name of the module.  It may be overridden by individual module types, for
   427  // example prebuilts will prepend prebuilt_ to the name.
   428  func (a *ModuleBase) Name() string {
   429  	return String(a.nameProperties.Name)
   430  }
   431  
   432  // BaseModuleName returns the name of the module as specified in the blueprints file.
   433  func (a *ModuleBase) BaseModuleName() string {
   434  	return String(a.nameProperties.Name)
   435  }
   436  
   437  func (a *ModuleBase) base() *ModuleBase {
   438  	return a
   439  }
   440  
   441  func (a *ModuleBase) SetTarget(target Target, primary bool) {
   442  	a.commonProperties.CompileTarget = target
   443  	a.commonProperties.CompilePrimary = primary
   444  }
   445  
   446  func (a *ModuleBase) Target() Target {
   447  	return a.commonProperties.CompileTarget
   448  }
   449  
   450  func (a *ModuleBase) TargetPrimary() bool {
   451  	return a.commonProperties.CompilePrimary
   452  }
   453  
   454  func (a *ModuleBase) Os() OsType {
   455  	return a.Target().Os
   456  }
   457  
   458  func (a *ModuleBase) Host() bool {
   459  	return a.Os().Class == Host || a.Os().Class == HostCross
   460  }
   461  
   462  func (a *ModuleBase) Arch() Arch {
   463  	return a.Target().Arch
   464  }
   465  
   466  func (a *ModuleBase) ArchSpecific() bool {
   467  	return a.commonProperties.ArchSpecific
   468  }
   469  
   470  func (a *ModuleBase) OsClassSupported() []OsClass {
   471  	switch a.commonProperties.HostOrDeviceSupported {
   472  	case HostSupported:
   473  		return []OsClass{Host, HostCross}
   474  	case HostSupportedNoCross:
   475  		return []OsClass{Host}
   476  	case DeviceSupported:
   477  		return []OsClass{Device}
   478  	case HostAndDeviceSupported:
   479  		var supported []OsClass
   480  		if Bool(a.hostAndDeviceProperties.Host_supported) {
   481  			supported = append(supported, Host, HostCross)
   482  		}
   483  		if a.hostAndDeviceProperties.Device_supported == nil ||
   484  			*a.hostAndDeviceProperties.Device_supported {
   485  			supported = append(supported, Device)
   486  		}
   487  		return supported
   488  	default:
   489  		return nil
   490  	}
   491  }
   492  
   493  func (a *ModuleBase) DeviceSupported() bool {
   494  	return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
   495  		a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
   496  			(a.hostAndDeviceProperties.Device_supported == nil ||
   497  				*a.hostAndDeviceProperties.Device_supported)
   498  }
   499  
   500  func (a *ModuleBase) Enabled() bool {
   501  	if a.commonProperties.Enabled == nil {
   502  		return !a.Os().DefaultDisabled
   503  	}
   504  	return *a.commonProperties.Enabled
   505  }
   506  
   507  func (a *ModuleBase) SkipInstall() {
   508  	a.commonProperties.SkipInstall = true
   509  }
   510  
   511  func (a *ModuleBase) ExportedToMake() bool {
   512  	return a.commonProperties.NamespaceExportedToMake
   513  }
   514  
   515  func (a *ModuleBase) computeInstallDeps(
   516  	ctx blueprint.ModuleContext) Paths {
   517  
   518  	result := Paths{}
   519  	ctx.VisitDepsDepthFirstIf(isFileInstaller,
   520  		func(m blueprint.Module) {
   521  			fileInstaller := m.(fileInstaller)
   522  			files := fileInstaller.filesToInstall()
   523  			result = append(result, files...)
   524  		})
   525  
   526  	return result
   527  }
   528  
   529  func (a *ModuleBase) filesToInstall() Paths {
   530  	return a.installFiles
   531  }
   532  
   533  func (p *ModuleBase) NoAddressSanitizer() bool {
   534  	return p.noAddressSanitizer
   535  }
   536  
   537  func (p *ModuleBase) InstallInData() bool {
   538  	return false
   539  }
   540  
   541  func (p *ModuleBase) InstallInSanitizerDir() bool {
   542  	return false
   543  }
   544  
   545  func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
   546  	allInstalledFiles := Paths{}
   547  	allCheckbuildFiles := Paths{}
   548  	ctx.VisitAllModuleVariants(func(module Module) {
   549  		a := module.base()
   550  		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
   551  		allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
   552  	})
   553  
   554  	var deps Paths
   555  
   556  	namespacePrefix := ctx.Namespace().(*Namespace).id
   557  	if namespacePrefix != "" {
   558  		namespacePrefix = namespacePrefix + "-"
   559  	}
   560  
   561  	if len(allInstalledFiles) > 0 {
   562  		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
   563  		ctx.Build(pctx, BuildParams{
   564  			Rule:      blueprint.Phony,
   565  			Output:    name,
   566  			Implicits: allInstalledFiles,
   567  			Default:   !ctx.Config().EmbeddedInMake(),
   568  		})
   569  		deps = append(deps, name)
   570  		a.installTarget = name
   571  	}
   572  
   573  	if len(allCheckbuildFiles) > 0 {
   574  		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
   575  		ctx.Build(pctx, BuildParams{
   576  			Rule:      blueprint.Phony,
   577  			Output:    name,
   578  			Implicits: allCheckbuildFiles,
   579  		})
   580  		deps = append(deps, name)
   581  		a.checkbuildTarget = name
   582  	}
   583  
   584  	if len(deps) > 0 {
   585  		suffix := ""
   586  		if ctx.Config().EmbeddedInMake() {
   587  			suffix = "-soong"
   588  		}
   589  
   590  		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
   591  		ctx.Build(pctx, BuildParams{
   592  			Rule:      blueprint.Phony,
   593  			Outputs:   []WritablePath{name},
   594  			Implicits: deps,
   595  		})
   596  
   597  		a.blueprintDir = ctx.ModuleDir()
   598  	}
   599  }
   600  
   601  func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
   602  	var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
   603  	var deviceSpecific = Bool(a.commonProperties.Device_specific)
   604  	var productSpecific = Bool(a.commonProperties.Product_specific)
   605  
   606  	if ((socSpecific || deviceSpecific) && productSpecific) || (socSpecific && deviceSpecific) {
   607  		msg := "conflicting value set here"
   608  		if productSpecific {
   609  			ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
   610  			if deviceSpecific {
   611  				ctx.PropertyErrorf("device_specific", msg)
   612  			}
   613  		} else {
   614  			ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
   615  		}
   616  		if Bool(a.commonProperties.Vendor) {
   617  			ctx.PropertyErrorf("vendor", msg)
   618  		}
   619  		if Bool(a.commonProperties.Proprietary) {
   620  			ctx.PropertyErrorf("proprietary", msg)
   621  		}
   622  		if Bool(a.commonProperties.Soc_specific) {
   623  			ctx.PropertyErrorf("soc_specific", msg)
   624  		}
   625  	}
   626  
   627  	if productSpecific {
   628  		return productSpecificModule
   629  	} else if deviceSpecific {
   630  		return deviceSpecificModule
   631  	} else if socSpecific {
   632  		return socSpecificModule
   633  	} else {
   634  		return platformModule
   635  	}
   636  }
   637  
   638  func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
   639  	return androidBaseContextImpl{
   640  		target:        a.commonProperties.CompileTarget,
   641  		targetPrimary: a.commonProperties.CompilePrimary,
   642  		kind:          determineModuleKind(a, ctx),
   643  		config:        ctx.Config().(Config),
   644  	}
   645  }
   646  
   647  func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
   648  	ctx := &androidModuleContext{
   649  		module:                 a.module,
   650  		ModuleContext:          blueprintCtx,
   651  		androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
   652  		installDeps:            a.computeInstallDeps(blueprintCtx),
   653  		installFiles:           a.installFiles,
   654  		missingDeps:            blueprintCtx.GetMissingDependencies(),
   655  	}
   656  
   657  	desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
   658  	var suffix []string
   659  	if ctx.Os().Class != Device && ctx.Os().Class != Generic {
   660  		suffix = append(suffix, ctx.Os().String())
   661  	}
   662  	if !ctx.PrimaryArch() {
   663  		suffix = append(suffix, ctx.Arch().ArchType.String())
   664  	}
   665  
   666  	ctx.Variable(pctx, "moduleDesc", desc)
   667  
   668  	s := ""
   669  	if len(suffix) > 0 {
   670  		s = " [" + strings.Join(suffix, " ") + "]"
   671  	}
   672  	ctx.Variable(pctx, "moduleDescSuffix", s)
   673  
   674  	if a.Enabled() {
   675  		a.module.GenerateAndroidBuildActions(ctx)
   676  		if ctx.Failed() {
   677  			return
   678  		}
   679  
   680  		a.installFiles = append(a.installFiles, ctx.installFiles...)
   681  		a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
   682  	}
   683  
   684  	if a == ctx.FinalModule().(Module).base() {
   685  		a.generateModuleTarget(ctx)
   686  		if ctx.Failed() {
   687  			return
   688  		}
   689  	}
   690  
   691  	a.buildParams = ctx.buildParams
   692  }
   693  
   694  type androidBaseContextImpl struct {
   695  	target        Target
   696  	targetPrimary bool
   697  	debug         bool
   698  	kind          moduleKind
   699  	config        Config
   700  }
   701  
   702  type androidModuleContext struct {
   703  	blueprint.ModuleContext
   704  	androidBaseContextImpl
   705  	installDeps     Paths
   706  	installFiles    Paths
   707  	checkbuildFiles Paths
   708  	missingDeps     []string
   709  	module          Module
   710  
   711  	// For tests
   712  	buildParams []BuildParams
   713  }
   714  
   715  func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
   716  	a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
   717  		Rule:        ErrorRule,
   718  		Description: desc,
   719  		Outputs:     outputs,
   720  		Optional:    true,
   721  		Args: map[string]string{
   722  			"error": err.Error(),
   723  		},
   724  	})
   725  	return
   726  }
   727  
   728  func (a *androidModuleContext) Config() Config {
   729  	return a.ModuleContext.Config().(Config)
   730  }
   731  
   732  func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
   733  	a.Build(pctx, BuildParams(params))
   734  }
   735  
   736  func convertBuildParams(params BuildParams) blueprint.BuildParams {
   737  	bparams := blueprint.BuildParams{
   738  		Rule:            params.Rule,
   739  		Description:     params.Description,
   740  		Deps:            params.Deps,
   741  		Outputs:         params.Outputs.Strings(),
   742  		ImplicitOutputs: params.ImplicitOutputs.Strings(),
   743  		Inputs:          params.Inputs.Strings(),
   744  		Implicits:       params.Implicits.Strings(),
   745  		OrderOnly:       params.OrderOnly.Strings(),
   746  		Args:            params.Args,
   747  		Optional:        !params.Default,
   748  	}
   749  
   750  	if params.Depfile != nil {
   751  		bparams.Depfile = params.Depfile.String()
   752  	}
   753  	if params.Output != nil {
   754  		bparams.Outputs = append(bparams.Outputs, params.Output.String())
   755  	}
   756  	if params.ImplicitOutput != nil {
   757  		bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
   758  	}
   759  	if params.Input != nil {
   760  		bparams.Inputs = append(bparams.Inputs, params.Input.String())
   761  	}
   762  	if params.Implicit != nil {
   763  		bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
   764  	}
   765  
   766  	return bparams
   767  }
   768  
   769  func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
   770  	a.ModuleContext.Variable(pctx.PackageContext, name, value)
   771  }
   772  
   773  func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
   774  	argNames ...string) blueprint.Rule {
   775  
   776  	return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
   777  }
   778  
   779  func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
   780  	if a.config.captureBuild {
   781  		a.buildParams = append(a.buildParams, params)
   782  	}
   783  
   784  	bparams := convertBuildParams(params)
   785  
   786  	if bparams.Description != "" {
   787  		bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
   788  	}
   789  
   790  	if a.missingDeps != nil {
   791  		a.ninjaError(bparams.Description, bparams.Outputs,
   792  			fmt.Errorf("module %s missing dependencies: %s\n",
   793  				a.ModuleName(), strings.Join(a.missingDeps, ", ")))
   794  		return
   795  	}
   796  
   797  	a.ModuleContext.Build(pctx.PackageContext, bparams)
   798  }
   799  
   800  func (a *androidModuleContext) GetMissingDependencies() []string {
   801  	return a.missingDeps
   802  }
   803  
   804  func (a *androidModuleContext) AddMissingDependencies(deps []string) {
   805  	if deps != nil {
   806  		a.missingDeps = append(a.missingDeps, deps...)
   807  		a.missingDeps = FirstUniqueStrings(a.missingDeps)
   808  	}
   809  }
   810  
   811  func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
   812  	aModule, _ := module.(Module)
   813  	if aModule == nil {
   814  		a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
   815  		return nil
   816  	}
   817  
   818  	if !aModule.Enabled() {
   819  		if a.Config().AllowMissingDependencies() {
   820  			a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
   821  		} else {
   822  			a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
   823  		}
   824  		return nil
   825  	}
   826  
   827  	return aModule
   828  }
   829  
   830  func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
   831  	a.ModuleContext.VisitDirectDeps(visit)
   832  }
   833  
   834  func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
   835  	a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
   836  		if aModule := a.validateAndroidModule(module); aModule != nil {
   837  			visit(aModule)
   838  		}
   839  	})
   840  }
   841  
   842  func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
   843  	a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
   844  		if aModule := a.validateAndroidModule(module); aModule != nil {
   845  			if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
   846  				visit(aModule)
   847  			}
   848  		}
   849  	})
   850  }
   851  
   852  func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
   853  	a.ModuleContext.VisitDirectDepsIf(
   854  		// pred
   855  		func(module blueprint.Module) bool {
   856  			if aModule := a.validateAndroidModule(module); aModule != nil {
   857  				return pred(aModule)
   858  			} else {
   859  				return false
   860  			}
   861  		},
   862  		// visit
   863  		func(module blueprint.Module) {
   864  			visit(module.(Module))
   865  		})
   866  }
   867  
   868  func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
   869  	a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
   870  		if aModule := a.validateAndroidModule(module); aModule != nil {
   871  			visit(aModule)
   872  		}
   873  	})
   874  }
   875  
   876  func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
   877  	a.ModuleContext.VisitDepsDepthFirstIf(
   878  		// pred
   879  		func(module blueprint.Module) bool {
   880  			if aModule := a.validateAndroidModule(module); aModule != nil {
   881  				return pred(aModule)
   882  			} else {
   883  				return false
   884  			}
   885  		},
   886  		// visit
   887  		func(module blueprint.Module) {
   888  			visit(module.(Module))
   889  		})
   890  }
   891  
   892  func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
   893  	a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
   894  		childAndroidModule := a.validateAndroidModule(child)
   895  		parentAndroidModule := a.validateAndroidModule(parent)
   896  		if childAndroidModule != nil && parentAndroidModule != nil {
   897  			return visit(childAndroidModule, parentAndroidModule)
   898  		} else {
   899  			return false
   900  		}
   901  	})
   902  }
   903  
   904  func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
   905  	a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
   906  		visit(module.(Module))
   907  	})
   908  }
   909  
   910  func (a *androidModuleContext) PrimaryModule() Module {
   911  	return a.ModuleContext.PrimaryModule().(Module)
   912  }
   913  
   914  func (a *androidModuleContext) FinalModule() Module {
   915  	return a.ModuleContext.FinalModule().(Module)
   916  }
   917  
   918  func (a *androidBaseContextImpl) Target() Target {
   919  	return a.target
   920  }
   921  
   922  func (a *androidBaseContextImpl) TargetPrimary() bool {
   923  	return a.targetPrimary
   924  }
   925  
   926  func (a *androidBaseContextImpl) Arch() Arch {
   927  	return a.target.Arch
   928  }
   929  
   930  func (a *androidBaseContextImpl) Os() OsType {
   931  	return a.target.Os
   932  }
   933  
   934  func (a *androidBaseContextImpl) Host() bool {
   935  	return a.target.Os.Class == Host || a.target.Os.Class == HostCross
   936  }
   937  
   938  func (a *androidBaseContextImpl) Device() bool {
   939  	return a.target.Os.Class == Device
   940  }
   941  
   942  func (a *androidBaseContextImpl) Darwin() bool {
   943  	return a.target.Os == Darwin
   944  }
   945  
   946  func (a *androidBaseContextImpl) Windows() bool {
   947  	return a.target.Os == Windows
   948  }
   949  
   950  func (a *androidBaseContextImpl) Debug() bool {
   951  	return a.debug
   952  }
   953  
   954  func (a *androidBaseContextImpl) PrimaryArch() bool {
   955  	if len(a.config.Targets[a.target.Os.Class]) <= 1 {
   956  		return true
   957  	}
   958  	return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
   959  }
   960  
   961  func (a *androidBaseContextImpl) AConfig() Config {
   962  	return a.config
   963  }
   964  
   965  func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
   966  	return DeviceConfig{a.config.deviceConfig}
   967  }
   968  
   969  func (a *androidBaseContextImpl) Platform() bool {
   970  	return a.kind == platformModule
   971  }
   972  
   973  func (a *androidBaseContextImpl) DeviceSpecific() bool {
   974  	return a.kind == deviceSpecificModule
   975  }
   976  
   977  func (a *androidBaseContextImpl) SocSpecific() bool {
   978  	return a.kind == socSpecificModule
   979  }
   980  
   981  func (a *androidBaseContextImpl) ProductSpecific() bool {
   982  	return a.kind == productSpecificModule
   983  }
   984  
   985  func (a *androidModuleContext) InstallInData() bool {
   986  	return a.module.InstallInData()
   987  }
   988  
   989  func (a *androidModuleContext) InstallInSanitizerDir() bool {
   990  	return a.module.InstallInSanitizerDir()
   991  }
   992  
   993  func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
   994  	if a.module.base().commonProperties.SkipInstall {
   995  		return true
   996  	}
   997  
   998  	if a.Device() {
   999  		if a.Config().SkipDeviceInstall() {
  1000  			return true
  1001  		}
  1002  
  1003  		if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
  1004  			return true
  1005  		}
  1006  	}
  1007  
  1008  	return false
  1009  }
  1010  
  1011  func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
  1012  	deps ...Path) OutputPath {
  1013  	return a.installFile(installPath, name, srcPath, Cp, deps)
  1014  }
  1015  
  1016  func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
  1017  	deps ...Path) OutputPath {
  1018  	return a.installFile(installPath, name, srcPath, CpExecutable, deps)
  1019  }
  1020  
  1021  func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
  1022  	rule blueprint.Rule, deps []Path) OutputPath {
  1023  
  1024  	fullInstallPath := installPath.Join(a, name)
  1025  	a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
  1026  
  1027  	if !a.skipInstall(fullInstallPath) {
  1028  
  1029  		deps = append(deps, a.installDeps...)
  1030  
  1031  		var implicitDeps, orderOnlyDeps Paths
  1032  
  1033  		if a.Host() {
  1034  			// Installed host modules might be used during the build, depend directly on their
  1035  			// dependencies so their timestamp is updated whenever their dependency is updated
  1036  			implicitDeps = deps
  1037  		} else {
  1038  			orderOnlyDeps = deps
  1039  		}
  1040  
  1041  		a.Build(pctx, BuildParams{
  1042  			Rule:        rule,
  1043  			Description: "install " + fullInstallPath.Base(),
  1044  			Output:      fullInstallPath,
  1045  			Input:       srcPath,
  1046  			Implicits:   implicitDeps,
  1047  			OrderOnly:   orderOnlyDeps,
  1048  			Default:     !a.Config().EmbeddedInMake(),
  1049  		})
  1050  
  1051  		a.installFiles = append(a.installFiles, fullInstallPath)
  1052  	}
  1053  	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
  1054  	return fullInstallPath
  1055  }
  1056  
  1057  func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
  1058  	fullInstallPath := installPath.Join(a, name)
  1059  	a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
  1060  
  1061  	if !a.skipInstall(fullInstallPath) {
  1062  
  1063  		a.Build(pctx, BuildParams{
  1064  			Rule:        Symlink,
  1065  			Description: "install symlink " + fullInstallPath.Base(),
  1066  			Output:      fullInstallPath,
  1067  			OrderOnly:   Paths{srcPath},
  1068  			Default:     !a.Config().EmbeddedInMake(),
  1069  			Args: map[string]string{
  1070  				"fromPath": srcPath.String(),
  1071  			},
  1072  		})
  1073  
  1074  		a.installFiles = append(a.installFiles, fullInstallPath)
  1075  		a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
  1076  	}
  1077  	return fullInstallPath
  1078  }
  1079  
  1080  func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
  1081  	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
  1082  }
  1083  
  1084  type fileInstaller interface {
  1085  	filesToInstall() Paths
  1086  }
  1087  
  1088  func isFileInstaller(m blueprint.Module) bool {
  1089  	_, ok := m.(fileInstaller)
  1090  	return ok
  1091  }
  1092  
  1093  func isAndroidModule(m blueprint.Module) bool {
  1094  	_, ok := m.(Module)
  1095  	return ok
  1096  }
  1097  
  1098  func findStringInSlice(str string, slice []string) int {
  1099  	for i, s := range slice {
  1100  		if s == str {
  1101  			return i
  1102  		}
  1103  	}
  1104  	return -1
  1105  }
  1106  
  1107  func SrcIsModule(s string) string {
  1108  	if len(s) > 1 && s[0] == ':' {
  1109  		return s[1:]
  1110  	}
  1111  	return ""
  1112  }
  1113  
  1114  type sourceDependencyTag struct {
  1115  	blueprint.BaseDependencyTag
  1116  }
  1117  
  1118  var SourceDepTag sourceDependencyTag
  1119  
  1120  // Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
  1121  // using ":module" syntax, if any.
  1122  func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
  1123  	var deps []string
  1124  	set := make(map[string]bool)
  1125  
  1126  	for _, s := range srcFiles {
  1127  		if m := SrcIsModule(s); m != "" {
  1128  			if _, found := set[m]; found {
  1129  				ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
  1130  			} else {
  1131  				set[m] = true
  1132  				deps = append(deps, m)
  1133  			}
  1134  		}
  1135  	}
  1136  
  1137  	ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
  1138  }
  1139  
  1140  // Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
  1141  // using ":module" syntax, if any.
  1142  func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
  1143  	if s != nil {
  1144  		if m := SrcIsModule(*s); m != "" {
  1145  			ctx.AddDependency(ctx.Module(), SourceDepTag, m)
  1146  		}
  1147  	}
  1148  }
  1149  
  1150  type SourceFileProducer interface {
  1151  	Srcs() Paths
  1152  }
  1153  
  1154  // Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
  1155  // ExtractSourcesDeps must have already been called during the dependency resolution phase.
  1156  func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
  1157  	return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
  1158  }
  1159  
  1160  // Returns a single path expanded from globs and modules referenced using ":module" syntax.
  1161  // ExtractSourceDeps must have already been called during the dependency resolution phase.
  1162  func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
  1163  	srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
  1164  	if len(srcFiles) == 1 {
  1165  		return srcFiles[0]
  1166  	} else {
  1167  		ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
  1168  		return nil
  1169  	}
  1170  }
  1171  
  1172  // Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
  1173  // the srcFile is non-nil.
  1174  // ExtractSourceDeps must have already been called during the dependency resolution phase.
  1175  func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
  1176  	if srcFile != nil {
  1177  		return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
  1178  	}
  1179  	return OptionalPath{}
  1180  }
  1181  
  1182  func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
  1183  	prefix := PathForModuleSrc(ctx).String()
  1184  
  1185  	var expandedExcludes []string
  1186  	if excludes != nil {
  1187  		expandedExcludes = make([]string, 0, len(excludes))
  1188  	}
  1189  
  1190  	for _, e := range excludes {
  1191  		if m := SrcIsModule(e); m != "" {
  1192  			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
  1193  			if module == nil {
  1194  				// Error will have been handled by ExtractSourcesDeps
  1195  				continue
  1196  			}
  1197  			if srcProducer, ok := module.(SourceFileProducer); ok {
  1198  				expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
  1199  			} else {
  1200  				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
  1201  			}
  1202  		} else {
  1203  			expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
  1204  		}
  1205  	}
  1206  	expandedSrcFiles := make(Paths, 0, len(srcFiles))
  1207  	for _, s := range srcFiles {
  1208  		if m := SrcIsModule(s); m != "" {
  1209  			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
  1210  			if module == nil {
  1211  				// Error will have been handled by ExtractSourcesDeps
  1212  				continue
  1213  			}
  1214  			if srcProducer, ok := module.(SourceFileProducer); ok {
  1215  				moduleSrcs := srcProducer.Srcs()
  1216  				for _, e := range expandedExcludes {
  1217  					for j, ms := range moduleSrcs {
  1218  						if ms.String() == e {
  1219  							moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
  1220  						}
  1221  					}
  1222  				}
  1223  				expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
  1224  			} else {
  1225  				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
  1226  			}
  1227  		} else if pathtools.IsGlob(s) {
  1228  			globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
  1229  			for i, s := range globbedSrcFiles {
  1230  				globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
  1231  			}
  1232  			expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
  1233  		} else {
  1234  			p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
  1235  			j := findStringInSlice(p.String(), expandedExcludes)
  1236  			if j == -1 {
  1237  				expandedSrcFiles = append(expandedSrcFiles, p)
  1238  			}
  1239  
  1240  		}
  1241  	}
  1242  	return expandedSrcFiles
  1243  }
  1244  
  1245  func (ctx *androidModuleContext) RequiredModuleNames() []string {
  1246  	return ctx.module.base().commonProperties.Required
  1247  }
  1248  
  1249  func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
  1250  	ret, err := ctx.GlobWithDeps(globPattern, excludes)
  1251  	if err != nil {
  1252  		ctx.ModuleErrorf("glob: %s", err.Error())
  1253  	}
  1254  	return pathsForModuleSrcFromFullPath(ctx, ret, true)
  1255  }
  1256  
  1257  func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
  1258  	ret, err := ctx.GlobWithDeps(globPattern, excludes)
  1259  	if err != nil {
  1260  		ctx.ModuleErrorf("glob: %s", err.Error())
  1261  	}
  1262  	return pathsForModuleSrcFromFullPath(ctx, ret, false)
  1263  }
  1264  
  1265  func init() {
  1266  	RegisterSingletonType("buildtarget", BuildTargetSingleton)
  1267  }
  1268  
  1269  func BuildTargetSingleton() Singleton {
  1270  	return &buildTargetSingleton{}
  1271  }
  1272  
  1273  func parentDir(dir string) string {
  1274  	dir, _ = filepath.Split(dir)
  1275  	return filepath.Clean(dir)
  1276  }
  1277  
  1278  type buildTargetSingleton struct{}
  1279  
  1280  func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
  1281  	var checkbuildDeps Paths
  1282  
  1283  	mmTarget := func(dir string) WritablePath {
  1284  		return PathForPhony(ctx,
  1285  			"MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
  1286  	}
  1287  
  1288  	modulesInDir := make(map[string]Paths)
  1289  
  1290  	ctx.VisitAllModules(func(module Module) {
  1291  		blueprintDir := module.base().blueprintDir
  1292  		installTarget := module.base().installTarget
  1293  		checkbuildTarget := module.base().checkbuildTarget
  1294  
  1295  		if checkbuildTarget != nil {
  1296  			checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
  1297  			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
  1298  		}
  1299  
  1300  		if installTarget != nil {
  1301  			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
  1302  		}
  1303  	})
  1304  
  1305  	suffix := ""
  1306  	if ctx.Config().EmbeddedInMake() {
  1307  		suffix = "-soong"
  1308  	}
  1309  
  1310  	// Create a top-level checkbuild target that depends on all modules
  1311  	ctx.Build(pctx, BuildParams{
  1312  		Rule:      blueprint.Phony,
  1313  		Output:    PathForPhony(ctx, "checkbuild"+suffix),
  1314  		Implicits: checkbuildDeps,
  1315  	})
  1316  
  1317  	// Make will generate the MODULES-IN-* targets
  1318  	if ctx.Config().EmbeddedInMake() {
  1319  		return
  1320  	}
  1321  
  1322  	sortedKeys := func(m map[string]Paths) []string {
  1323  		s := make([]string, 0, len(m))
  1324  		for k := range m {
  1325  			s = append(s, k)
  1326  		}
  1327  		sort.Strings(s)
  1328  		return s
  1329  	}
  1330  
  1331  	// Ensure ancestor directories are in modulesInDir
  1332  	dirs := sortedKeys(modulesInDir)
  1333  	for _, dir := range dirs {
  1334  		dir := parentDir(dir)
  1335  		for dir != "." && dir != "/" {
  1336  			if _, exists := modulesInDir[dir]; exists {
  1337  				break
  1338  			}
  1339  			modulesInDir[dir] = nil
  1340  			dir = parentDir(dir)
  1341  		}
  1342  	}
  1343  
  1344  	// Make directories build their direct subdirectories
  1345  	dirs = sortedKeys(modulesInDir)
  1346  	for _, dir := range dirs {
  1347  		p := parentDir(dir)
  1348  		if p != "." && p != "/" {
  1349  			modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
  1350  		}
  1351  	}
  1352  
  1353  	// Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
  1354  	// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
  1355  	// files.
  1356  	for _, dir := range dirs {
  1357  		ctx.Build(pctx, BuildParams{
  1358  			Rule:      blueprint.Phony,
  1359  			Output:    mmTarget(dir),
  1360  			Implicits: modulesInDir[dir],
  1361  			// HACK: checkbuild should be an optional build, but force it
  1362  			// enabled for now in standalone builds
  1363  			Default: !ctx.Config().EmbeddedInMake(),
  1364  		})
  1365  	}
  1366  
  1367  	// Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
  1368  	osDeps := map[OsType]Paths{}
  1369  	ctx.VisitAllModules(func(module Module) {
  1370  		if module.Enabled() {
  1371  			os := module.Target().Os
  1372  			osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
  1373  		}
  1374  	})
  1375  
  1376  	osClass := make(map[string]Paths)
  1377  	for os, deps := range osDeps {
  1378  		var className string
  1379  
  1380  		switch os.Class {
  1381  		case Host:
  1382  			className = "host"
  1383  		case HostCross:
  1384  			className = "host-cross"
  1385  		case Device:
  1386  			className = "target"
  1387  		default:
  1388  			continue
  1389  		}
  1390  
  1391  		name := PathForPhony(ctx, className+"-"+os.Name)
  1392  		osClass[className] = append(osClass[className], name)
  1393  
  1394  		ctx.Build(pctx, BuildParams{
  1395  			Rule:      blueprint.Phony,
  1396  			Output:    name,
  1397  			Implicits: deps,
  1398  		})
  1399  	}
  1400  
  1401  	// Wrap those into host|host-cross|target phony rules
  1402  	osClasses := sortedKeys(osClass)
  1403  	for _, class := range osClasses {
  1404  		ctx.Build(pctx, BuildParams{
  1405  			Rule:      blueprint.Phony,
  1406  			Output:    PathForPhony(ctx, class),
  1407  			Implicits: osClass[class],
  1408  		})
  1409  	}
  1410  }
  1411  
  1412  type AndroidModulesByName struct {
  1413  	slice []Module
  1414  	ctx   interface {
  1415  		ModuleName(blueprint.Module) string
  1416  		ModuleSubDir(blueprint.Module) string
  1417  	}
  1418  }
  1419  
  1420  func (s AndroidModulesByName) Len() int { return len(s.slice) }
  1421  func (s AndroidModulesByName) Less(i, j int) bool {
  1422  	mi, mj := s.slice[i], s.slice[j]
  1423  	ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
  1424  
  1425  	if ni != nj {
  1426  		return ni < nj
  1427  	} else {
  1428  		return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
  1429  	}
  1430  }
  1431  func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }