summaryrefslogtreecommitdiff
path: root/apex/apex.go
diff options
context:
space:
mode:
Diffstat (limited to 'apex/apex.go')
-rw-r--r--apex/apex.go166
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...)