diff options
Diffstat (limited to 'apex/prebuilt.go')
-rw-r--r-- | apex/prebuilt.go | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/apex/prebuilt.go b/apex/prebuilt.go index d089c285d..03266c55e 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -16,13 +16,29 @@ package apex import ( "fmt" + "strconv" "strings" "android/soong/android" + "android/soong/java" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) +var ( + extractMatchingApex = pctx.StaticRule( + "extractMatchingApex", + blueprint.RuleParams{ + Command: `rm -rf "$out" && ` + + `${extract_apks} -o "${out}" -allow-prereleased=${allow-prereleased} ` + + `-sdk-version=${sdk-version} -abis=${abis} -screen-densities=all -extract-single ` + + `${in}`, + CommandDeps: []string{"${extract_apks}"}, + }, + "abis", "allow-prereleased", "sdk-version") +) + type Prebuilt struct { android.ModuleBase prebuilt android.Prebuilt @@ -208,3 +224,117 @@ func (p *Prebuilt) AndroidMkEntries() []android.AndroidMkEntries { }, }} } + +type ApexSet struct { + android.ModuleBase + prebuilt android.Prebuilt + + properties ApexSetProperties + + installDir android.InstallPath + installFilename string + outputApex android.WritablePath + + // list of commands to create symlinks for backward compatibility. + // these commands will be attached as LOCAL_POST_INSTALL_CMD + compatSymlinks []string +} + +type ApexSetProperties struct { + // the .apks file path that contains prebuilt apex files to be extracted. + Set *string + + // whether the extracted apex file installable. + Installable *bool + + // optional name for the installed apex. If unspecified, name of the + // module is used as the file name + Filename *string + + // names of modules to be overridden. Listed modules can only be other binaries + // (in Make or Soong). + // This does not completely prevent installation of the overridden binaries, but if both + // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed + // from PRODUCT_PACKAGES. + Overrides []string + + // apexes in this set use prerelease SDK version + Prerelease *bool +} + +func (a *ApexSet) installable() bool { + return a.properties.Installable == nil || proptools.Bool(a.properties.Installable) +} + +func (a *ApexSet) InstallFilename() string { + return proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+imageApexSuffix) +} + +func (a *ApexSet) Prebuilt() *android.Prebuilt { + return &a.prebuilt +} + +func (a *ApexSet) Name() string { + return a.prebuilt.Name(a.ModuleBase.Name()) +} + +// prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex. +func apexSetFactory() android.Module { + module := &ApexSet{} + module.AddProperties(&module.properties) + android.InitSingleSourcePrebuiltModule(module, &module.properties, "Set") + android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) + return module +} + +func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { + a.installFilename = a.InstallFilename() + if !strings.HasSuffix(a.installFilename, imageApexSuffix) { + ctx.ModuleErrorf("filename should end in %s for apex_set", imageApexSuffix) + } + + apexSet := a.prebuilt.SingleSourcePath(ctx) + a.outputApex = android.PathForModuleOut(ctx, a.installFilename) + ctx.Build(pctx, + android.BuildParams{ + Rule: extractMatchingApex, + Description: "Extract an apex from an apex set", + Inputs: android.Paths{apexSet}, + Output: a.outputApex, + Args: map[string]string{ + "abis": strings.Join(java.SupportedAbis(ctx), ","), + "allow-prereleased": strconv.FormatBool(proptools.Bool(a.properties.Prerelease)), + "sdk-version": ctx.Config().PlatformSdkVersion(), + }, + }) + a.installDir = android.PathForModuleInstall(ctx, "apex") + if a.installable() { + ctx.InstallFile(a.installDir, a.installFilename, a.outputApex) + } + + // in case that apex_set replaces source apex (using prefer: prop) + a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx) + // or that apex_set overrides other apexes (using overrides: prop) + for _, overridden := range a.properties.Overrides { + a.compatSymlinks = append(a.compatSymlinks, makeCompatSymlinks(overridden, ctx)...) + } +} + +func (a *ApexSet) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{android.AndroidMkEntries{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(a.outputApex), + Include: "$(BUILD_PREBUILT)", + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_PATH", a.installDir.ToMakePath().String()) + entries.SetString("LOCAL_MODULE_STEM", a.installFilename) + entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !a.installable()) + entries.AddStrings("LOCAL_OVERRIDES_MODULES", a.properties.Overrides...) + if len(a.compatSymlinks) > 0 { + entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(a.compatSymlinks, " && ")) + } + }, + }, + }} +} |