diff options
Diffstat (limited to 'apex/apex.go')
-rw-r--r-- | apex/apex.go | 166 |
1 files changed, 120 insertions, 46 deletions
diff --git a/apex/apex.go b/apex/apex.go index 23f6d3729..5f714259b 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -47,13 +47,15 @@ var ( Description: "fs_config ${out}", }, "ro_paths", "exec_paths") - injectApexDependency = pctx.StaticRule("injectApexDependency", blueprint.RuleParams{ + apexManifestRule = pctx.StaticRule("apexManifestRule", blueprint.RuleParams{ Command: `rm -f $out && ${jsonmodify} $in ` + `-a provideNativeLibs ${provideNativeLibs} ` + - `-a requireNativeLibs ${requireNativeLibs} -o $out`, + `-a requireNativeLibs ${requireNativeLibs} ` + + `${opt} ` + + `-o $out`, CommandDeps: []string{"${jsonmodify}"}, - Description: "Inject dependency into ${out}", - }, "provideNativeLibs", "requireNativeLibs") + Description: "prepare ${out}", + }, "provideNativeLibs", "requireNativeLibs", "opt") // TODO(b/113233103): make sure that file_contexts is sane, i.e., validate // against the binary policy using sefcontext_compiler -p <policy>. @@ -150,8 +152,6 @@ var ( var ( whitelistNoApex = map[string][]string{ "apex_test_build_features": []string{"libbinder"}, - "com.android.neuralnetworks": []string{"libbinder"}, - "com.android.media": []string{"libbinder"}, "com.android.media.swcodec": []string{"libbinder"}, "test_com.android.media.swcodec": []string{"libbinder"}, "com.android.vndk": []string{"libbinder"}, @@ -185,7 +185,7 @@ func init() { pctx.HostBinToolVariable("zipalign", "zipalign") pctx.HostBinToolVariable("jsonmodify", "jsonmodify") - android.RegisterModuleType("apex", apexBundleFactory) + android.RegisterModuleType("apex", BundleFactory) android.RegisterModuleType("apex_test", testApexBundleFactory) android.RegisterModuleType("apex_vndk", vndkApexBundleFactory) android.RegisterModuleType("apex_defaults", defaultsFactory) @@ -195,12 +195,14 @@ func init() { ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator).Parallel() ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator).Parallel() }) - android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("apex_deps", apexDepsMutator) - ctx.BottomUp("apex", apexMutator).Parallel() - ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel() - ctx.BottomUp("apex_uses", apexUsesMutator).Parallel() - }) + android.PostDepsMutators(RegisterPostDepsMutators) +} + +func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { + ctx.TopDown("apex_deps", apexDepsMutator) + ctx.BottomUp("apex", apexMutator).Parallel() + ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel() + ctx.BottomUp("apex_uses", apexUsesMutator).Parallel() } var ( @@ -220,12 +222,14 @@ func apexVndkGatherMutator(mctx android.TopDownMutatorContext) { if ab.IsNativeBridgeSupported() { mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType()) } - vndkVersion := proptools.StringDefault(ab.vndkProperties.Vndk_version, mctx.DeviceConfig().PlatformVndkVersion()) + + vndkVersion := proptools.String(ab.vndkProperties.Vndk_version) + vndkApexListMutex.Lock() defer vndkApexListMutex.Unlock() vndkApexList := vndkApexList(mctx.Config()) if other, ok := vndkApexList[vndkVersion]; ok { - mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.Name()) + mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.BaseModuleName()) } vndkApexList[vndkVersion] = ab } @@ -287,11 +291,14 @@ func apexMutator(mctx android.BottomUpMutatorContext) { } func apexFlattenedMutator(mctx android.BottomUpMutatorContext) { - if _, ok := mctx.Module().(*apexBundle); ok { + if ab, ok := mctx.Module().(*apexBundle); ok { if !mctx.Config().FlattenApex() || mctx.Config().UnbundledBuild() { modules := mctx.CreateLocalVariations("", "flattened") modules[0].(*apexBundle).SetFlattened(false) modules[1].(*apexBundle).SetFlattened(true) + } else { + ab.SetFlattened(true) + ab.SetFlattenedConfigValue() } } } @@ -339,8 +346,9 @@ type apexBundleProperties struct { // If unspecified, a default one is automatically generated. AndroidManifest *string `android:"path"` - // Canonical name of the APEX bundle in the manifest file. - // If unspecified, defaults to the value of name + // Canonical name of the APEX bundle. Used to determine the path to the activated APEX on + // device (/apex/<apex_name>). + // If unspecified, defaults to the value of name. Apex_name *string // Determines the file contexts file for setting security context to each file in this APEX bundle. @@ -406,9 +414,19 @@ type apexBundleProperties struct { // List of APKs to package inside APEX Apps []string - // To distinguish between flattened and non-flattened variants. - // if set true, then this variant is flattened variant. + // To distinguish between flattened and non-flattened apex. + // if set true, then output files are flattened. Flattened bool `blueprint:"mutated"` + + // if true, it means that TARGET_FLATTEN_APEX is true and + // TARGET_BUILD_APPS is false + FlattenedConfigValue bool `blueprint:"mutated"` + + // List of SDKs that are used to build this APEX. A reference to an SDK should be either + // `name#version` or `name` which is an alias for `name#current`. If left empty, `platform#current` + // is implied. This value affects all modules included in this APEX. In other words, they are + // also built with the SDKs specified here. + Uses_sdks []string } type apexTargetBundleProperties struct { @@ -535,6 +553,7 @@ type apexFile struct { type apexBundle struct { android.ModuleBase android.DefaultableModuleBase + android.SdkBase properties apexBundleProperties targetProperties apexTargetBundleProperties @@ -544,8 +563,8 @@ type apexBundle struct { bundleModuleFile android.WritablePath outputFiles map[apexPackaging]android.WritablePath - flattenedOutput android.OutputPath - installDir android.OutputPath + flattenedOutput android.InstallPath + installDir android.InstallPath prebuiltFileToDelete string @@ -566,9 +585,6 @@ type apexBundle struct { // intermediate path for apex_manifest.json manifestOut android.WritablePath - - // A config value of (TARGET_FLATTEN_APEX && !TARGET_BUILD_APPS) - flattenedConfigValue bool } func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, @@ -737,6 +753,16 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { if cert != "" { ctx.AddDependency(ctx.Module(), certificateTag, cert) } + + // TODO(jiyong): ensure that all apexes are with non-empty uses_sdks + if len(a.properties.Uses_sdks) > 0 { + sdkRefs := []android.SdkRef{} + for _, str := range a.properties.Uses_sdks { + parsed := android.ParseSdkRef(ctx, str, "uses_sdks") + sdkRefs = append(sdkRefs, parsed) + } + a.BuildWithSdks(sdkRefs) + } } func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string { @@ -773,7 +799,7 @@ func (a *apexBundle) installable() bool { func (a *apexBundle) getImageVariation(config android.DeviceConfig) string { if config.VndkVersion() != "" && proptools.Bool(a.properties.Use_vendor) { - return "vendor" + return "vendor." + config.PlatformVndkVersion() } else { return "core" } @@ -819,6 +845,20 @@ func (a *apexBundle) SetFlattened(flattened bool) { a.properties.Flattened = flattened } +func (a *apexBundle) SetFlattenedConfigValue() { + a.properties.FlattenedConfigValue = true +} + +// isFlattenedVariant returns true when the current module is the flattened +// variant of an apex that has both a flattened and an unflattened variant. +// It returns false when the current module is flattened but there is no +// unflattened variant, which occurs when ctx.Config().FlattenedApex() returns +// true. It can be used to avoid collisions between the install paths of the +// flattened and unflattened variants. +func (a *apexBundle) isFlattenedVariant() bool { + return a.properties.Flattened && !a.properties.FlattenedConfigValue +} + func getCopyManifestForNativeLibrary(ccMod *cc.Module, config android.Config, handleSpecialLibs bool) (fileToCopy android.Path, dirInApex string) { // Decide the APEX-local directory by the multilib of the library // In the future, we may query this to the module. @@ -993,7 +1033,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return true } else if sh, ok := child.(*android.ShBinary); ok { fileToCopy, dirInApex := getCopyManifestForShBinary(sh) - filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, shBinary, sh, nil}) + filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, shBinary, sh, sh.Symlinks()}) } else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() { fileToCopy, dirInApex := getCopyManifestForPyBinary(py) filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, pyBinary, py, nil}) @@ -1128,6 +1168,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } else if am.CanHaveApexVariants() && am.IsInstallableToApex() { ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName) + } else if depTag == android.DefaultsDepTag { + return false } else if am.NoApex() && !android.InList(depName, whitelistNoApex[ctx.ModuleName()]) { ctx.ModuleErrorf("tries to include no_apex module %s", depName) } @@ -1136,10 +1178,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return false }) - a.flattenedConfigValue = ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild() - if a.flattenedConfigValue { - a.properties.Flattened = true - } if a.private_key_file == nil { ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.properties.Key)) return @@ -1175,6 +1213,16 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } + // check apex_available requirements + for _, fi := range filesInfo { + if am, ok := fi.module.(android.ApexModule); ok { + if !am.AvailableFor(ctx.ModuleName()) { + ctx.ModuleErrorf("requires %q that is not available for the APEX", fi.module.Name()) + return + } + } + } + // prepend the name of this APEX to the module names. These names will be the names of // modules that will be defined if the APEX is flattened. for i := range filesInfo { @@ -1184,18 +1232,28 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.installDir = android.PathForModuleInstall(ctx, "apex") a.filesInfo = filesInfo + // prepare apex_manifest.json a.manifestOut = android.PathForModuleOut(ctx, "apex_manifest.json") - // put dependency({provide|require}NativeLibs) in apex_manifest.json manifestSrc := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")) + + // put dependency({provide|require}NativeLibs) in apex_manifest.json provideNativeLibs = android.SortedUniqueStrings(provideNativeLibs) requireNativeLibs = android.SortedUniqueStrings(android.RemoveListFromList(requireNativeLibs, provideNativeLibs)) + + // apex name can be overridden + optCommands := []string{} + if a.properties.Apex_name != nil { + optCommands = append(optCommands, "-v name "+*a.properties.Apex_name) + } + ctx.Build(pctx, android.BuildParams{ - Rule: injectApexDependency, + Rule: apexManifestRule, Input: manifestSrc, Output: a.manifestOut, Args: map[string]string{ "provideNativeLibs": strings.Join(provideNativeLibs, " "), "requireNativeLibs": strings.Join(requireNativeLibs, " "), + "opt": strings.Join(optCommands, " "), }, }) @@ -1409,6 +1467,12 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap optFlags = append(optFlags, "--no_hashtree") } + if a.properties.Apex_name != nil { + // If apex_name is set, apexer can skip checking if key name matches with apex name. + // Note that apex_manifest is also mended. + optFlags = append(optFlags, "--do_not_check_keyname") + } + ctx.Build(pctx, android.BuildParams{ Rule: apexRule, Implicits: implicitInputs, @@ -1478,7 +1542,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap }) // Install to $OUT/soong/{target,host}/.../apex - if a.installable() && (!ctx.Config().FlattenApex() || apexType.zip()) && (!a.properties.Flattened || a.flattenedConfigValue) { + if a.installable() && (!ctx.Config().FlattenApex() || apexType.zip()) && !a.isFlattenedVariant() { ctx.InstallFile(a.installDir, ctx.ModuleName()+suffix, a.outputFiles[apexType]) } } @@ -1543,7 +1607,7 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, name, moduleDir string, apex } var suffix string - if a.properties.Flattened && !a.flattenedConfigValue { + if a.isFlattenedVariant() { suffix = ".flattened" } @@ -1554,14 +1618,14 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, name, moduleDir string, apex fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)") fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName+suffix) - // /apex/<name>/{lib|framework|...} + // /apex/<apex_name>/{lib|framework|...} pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", proptools.StringDefault(a.properties.Apex_name, name), fi.installDir) if a.properties.Flattened && apexType.image() { // /system/apex/<name>/{lib|framework|...} - fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)", - a.installDir.RelPathString(), name, fi.installDir)) - if a.flattenedConfigValue { + fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join(a.installDir.ToMakePath().String(), + name, fi.installDir)) + if !a.isFlattenedVariant() { fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated) } if len(fi.symlinks) > 0 { @@ -1643,7 +1707,7 @@ func (a *apexBundle) androidMkForType(apexType apexPackaging) android.AndroidMkD moduleNames = a.androidMkForFiles(w, name, moduleDir, apexType) } - if a.properties.Flattened && !a.flattenedConfigValue { + if a.isFlattenedVariant() { name = name + ".flattened" } @@ -1658,7 +1722,7 @@ func (a *apexBundle) androidMkForType(apexType apexPackaging) android.AndroidMkD fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)") fmt.Fprintln(w, "$(LOCAL_INSTALLED_MODULE): .KATI_IMPLICIT_OUTPUTS :=", a.flattenedOutput.String()) - } else if !a.properties.Flattened || a.flattenedConfigValue { + } else if !a.isFlattenedVariant() { // zip-apex is the less common type so have the name refer to the image-apex // only and use {name}.zip if you want the zip-apex if apexType == zipApex && a.apexTypes == both { @@ -1669,7 +1733,7 @@ func (a *apexBundle) androidMkForType(apexType apexPackaging) android.AndroidMkD fmt.Fprintln(w, "LOCAL_MODULE :=", name) fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") // do we need a new class? fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFiles[apexType].String()) - fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)", a.installDir.RelPathString())) + fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.ToMakePath().String()) fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", name+apexType.suffix()) fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !a.installable()) if len(moduleNames) > 0 { @@ -1680,7 +1744,7 @@ func (a *apexBundle) androidMkForType(apexType apexPackaging) android.AndroidMkD } if a.prebuiltFileToDelete != "" { fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", "rm -rf "+ - filepath.Join("$(OUT_DIR)", a.installDir.RelPathString(), a.prebuiltFileToDelete)) + filepath.Join(a.installDir.ToMakePath().String(), a.prebuiltFileToDelete)) } fmt.Fprintln(w, "include $(BUILD_PREBUILT)") @@ -1702,6 +1766,7 @@ func newApexBundle() *apexBundle { }) android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(module) + android.InitSdkAwareModule(module) return module } @@ -1717,7 +1782,7 @@ func testApexBundleFactory() android.Module { return bundle } -func apexBundleFactory() android.Module { +func BundleFactory() android.Module { return newApexBundle() } @@ -1734,6 +1799,15 @@ func vndkApexBundleFactory() android.Module { }{ proptools.StringPtr("both"), }) + + vndkVersion := proptools.StringDefault(bundle.vndkProperties.Vndk_version, "current") + if vndkVersion == "current" { + vndkVersion = ctx.DeviceConfig().PlatformVndkVersion() + bundle.vndkProperties.Vndk_version = proptools.StringPtr(vndkVersion) + } + + // Ensure VNDK APEX mount point is formatted as com.android.vndk.v### + bundle.properties.Apex_name = proptools.StringPtr("com.android.vndk.v" + vndkVersion) }) return bundle } @@ -1773,7 +1847,7 @@ type Prebuilt struct { properties PrebuiltProperties inputApex android.Path - installDir android.OutputPath + installDir android.InstallPath installFilename string outputApex android.WritablePath } @@ -1920,7 +1994,7 @@ func (p *Prebuilt) AndroidMkEntries() android.AndroidMkEntries { Include: "$(BUILD_PREBUILT)", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(entries *android.AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_PATH", filepath.Join("$(OUT_DIR)", p.installDir.RelPathString())) + entries.SetString("LOCAL_MODULE_PATH", p.installDir.ToMakePath().String()) entries.SetString("LOCAL_MODULE_STEM", p.installFilename) entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable()) entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", p.properties.Overrides...) |