Merge "runtime_resource_overlay can be included in APEXes"
diff --git a/android/androidmk.go b/android/androidmk.go
index b5f4b2b..d579e30 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -198,6 +198,10 @@
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
+ if am, ok := mod.(ApexModule); ok {
+ a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
+ }
+
archStr := amod.Arch().ArchType.String()
host := false
switch amod.Os().Class {
diff --git a/android/apex.go b/android/apex.go
index 398fbae..f9350d1 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -101,6 +101,16 @@
// Tests if this module is available for the specified APEX or ":platform"
AvailableFor(what string) bool
+ // Return true if this module is not available to platform (i.e. apex_available
+ // property doesn't have "//apex_available:platform"), or shouldn't be available
+ // to platform, which is the case when this module depends on other module that
+ // isn't available to platform.
+ NotAvailableForPlatform() bool
+
+ // Mark that this module is not available to platform. Set by the
+ // check-platform-availability mutator in the apex package.
+ SetNotAvailableForPlatform()
+
// Returns the highest version which is <= maxSdkVersion.
// For example, with maxSdkVersion is 10 and versionList is [9,11]
// it returns 9 as string
@@ -126,6 +136,8 @@
Apex_available []string
Info ApexInfo `blueprint:"mutated"`
+
+ NotAvailableForPlatform bool `blueprint:"mutated"`
}
// Marker interface that identifies dependencies that are excluded from APEX
@@ -215,6 +227,14 @@
return CheckAvailableForApex(what, m.ApexProperties.Apex_available)
}
+func (m *ApexModuleBase) NotAvailableForPlatform() bool {
+ return m.ApexProperties.NotAvailableForPlatform
+}
+
+func (m *ApexModuleBase) SetNotAvailableForPlatform() {
+ m.ApexProperties.NotAvailableForPlatform = true
+}
+
func (m *ApexModuleBase) DepIsInSameApex(ctx BaseModuleContext, dep Module) bool {
// By default, if there is a dependency from A to B, we try to include both in the same APEX,
// unless B is explicitly from outside of the APEX (i.e. a stubs lib). Thus, returning true.
diff --git a/apex/apex.go b/apex/apex.go
index 13f660e..714cf9c 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -747,6 +747,7 @@
ctx.BottomUp("apex", apexMutator).Parallel()
ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
+ ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
}
// Mark the direct and transitive dependencies of apex bundles so that they
@@ -785,6 +786,60 @@
})
}
+// mark if a module cannot be available to platform. A module cannot be available
+// to platform if 1) it is explicitly marked as not available (i.e. "//apex_available:platform"
+// is absent) or 2) it depends on another module that isn't (or can't be) available to platform
+func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
+ // Host and recovery are not considered as platform
+ if mctx.Host() || mctx.Module().InstallInRecovery() {
+ return
+ }
+
+ if am, ok := mctx.Module().(android.ApexModule); ok {
+ availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
+
+ // In a rare case when a lib is marked as available only to an apex
+ // but the apex doesn't exist. This can happen in a partial manifest branch
+ // like master-art. Currently, libstatssocket in the stats APEX is causing
+ // this problem.
+ // Include the lib in platform because the module SDK that ought to provide
+ // it doesn't exist, so it would otherwise be left out completely.
+ // TODO(b/154888298) remove this by adding those libraries in module SDKS and skipping
+ // this check for libraries provided by SDKs.
+ if !availableToPlatform && !android.InAnyApex(am.Name()) {
+ availableToPlatform = true
+ }
+
+ // If any of the dep is not available to platform, this module is also considered
+ // as being not available to platform even if it has "//apex_available:platform"
+ mctx.VisitDirectDeps(func(child android.Module) {
+ if !am.DepIsInSameApex(mctx, child) {
+ // if the dependency crosses apex boundary, don't consider it
+ return
+ }
+ if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
+ availableToPlatform = false
+ // TODO(b/154889534) trigger an error when 'am' has "//apex_available:platform"
+ }
+ })
+
+ // Exception 1: stub libraries and native bridge libraries are always available to platform
+ if cc, ok := mctx.Module().(*cc.Module); ok &&
+ (cc.IsStubs() || cc.Target().NativeBridge == android.NativeBridgeEnabled) {
+ availableToPlatform = true
+ }
+
+ // Exception 2: bootstrap bionic libraries are also always available to platform
+ if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
+ availableToPlatform = true
+ }
+
+ if !availableToPlatform {
+ am.SetNotAvailableForPlatform()
+ }
+ }
+}
+
// If a module in an APEX depends on a module from an SDK then it needs an APEX
// specific variant created for it. Refer to sdk.sdkDepsReplaceMutator.
func inAnySdk(module android.Module) bool {
@@ -1019,11 +1074,17 @@
// Should be only used in tests#.
Test_only_no_hashtree *bool
+ // Whenever apex_payload.img of the APEX should not be dm-verity signed.
+ // Should be only used in tests#.
+ Test_only_unsigned_payload *bool
+
IsCoverageVariant bool `blueprint:"mutated"`
// Whether this APEX is considered updatable or not. When set to true, this will enforce additional
- // rules for making sure that the APEX is truely updatable. This will also disable the size optimizations
- // like symlinking to the system libs. Default is false.
+ // rules for making sure that the APEX is truly updatable.
+ // - To be updatable, min_sdk_version should be set as well
+ // This will also disable the size optimizations like symlinking to the system libs.
+ // Default is false.
Updatable *bool
// The minimum SDK version that this apex must be compatibile with.
@@ -1511,6 +1572,10 @@
return proptools.Bool(a.properties.Test_only_no_hashtree)
}
+func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
+ return proptools.Bool(a.properties.Test_only_unsigned_payload)
+}
+
func (a *apexBundle) getImageVariation(config android.DeviceConfig) string {
if a.vndkApex {
return cc.VendorVariationPrefix + a.vndkVersion(config)
@@ -1815,6 +1880,14 @@
})
}
+func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
+ if proptools.Bool(a.properties.Updatable) {
+ if String(a.properties.Min_sdk_version) == "" {
+ ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
+ }
+ }
+}
+
// Collects the list of module names that directly or indirectly contributes to the payload of this APEX
func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) {
a.depInfos = make(map[string]depInfo)
@@ -1880,6 +1953,7 @@
}
a.checkApexAvailability(ctx)
+ a.checkUpdatable(ctx)
a.collectDepsInfo(ctx)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 97d5cf6..dea7a08 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3758,22 +3758,12 @@
}`)
}
-func TestApexAvailable_CreatedForPlatform(t *testing.T) {
- // check that libfoo and libbar are created only for myapex, but not for the platform
- // TODO(jiyong) the checks for the platform variant are removed because we now create
- // the platform variant regardless of the apex_availability. Instead, we will make sure that
- // the platform variants are not used from other platform modules. When that is done,
- // these checks will be replaced by expecting a specific error message that will be
- // emitted when the platform variant is used.
- // ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared_myapex")
- // ensureListNotContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared")
- // ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_myapex")
- // ensureListNotContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared")
-
+func TestApexAvailable_CheckForPlatform(t *testing.T) {
ctx, _ := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
+ native_shared_libs: ["libbar", "libbaz"],
}
apex_key {
@@ -3786,16 +3776,52 @@
name: "libfoo",
stl: "none",
system_shared_libs: [],
+ shared_libs: ["libbar"],
apex_available: ["//apex_available:platform"],
+ }
+
+ cc_library {
+ name: "libfoo2",
+ stl: "none",
+ system_shared_libs: [],
+ shared_libs: ["libbaz"],
+ apex_available: ["//apex_available:platform"],
+ }
+
+ cc_library {
+ name: "libbar",
+ stl: "none",
+ system_shared_libs: [],
+ apex_available: ["myapex"],
+ }
+
+ cc_library {
+ name: "libbaz",
+ stl: "none",
+ system_shared_libs: [],
+ apex_available: ["myapex"],
+ stubs: {
+ versions: ["1"],
+ },
}`)
- // check that libfoo is created only for the platform
- ensureListNotContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared_myapex")
- ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared")
+ // libfoo shouldn't be available to platform even though it has "//apex_available:platform",
+ // because it depends on libbar which isn't available to platform
+ libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ if libfoo.NotAvailableForPlatform() != true {
+ t.Errorf("%q shouldn't be available to platform", libfoo.String())
+ }
+
+ // libfoo2 however can be available to platform because it depends on libbaz which provides
+ // stubs
+ libfoo2 := ctx.ModuleForTests("libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ if libfoo2.NotAvailableForPlatform() == true {
+ t.Errorf("%q should be available to platform", libfoo2.String())
+ }
}
func TestApexAvailable_CreatedForApex(t *testing.T) {
- testApex(t, `
+ ctx, _ := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3818,17 +3844,14 @@
},
}`)
- // shared variant of libfoo is only available to myapex
- // TODO(jiyong) the checks for the platform variant are removed because we now create
- // the platform variant regardless of the apex_availability. Instead, we will make sure that
- // the platform variants are not used from other platform modules. When that is done,
- // these checks will be replaced by expecting a specific error message that will be
- // emitted when the platform variant is used.
- // ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared_myapex")
- // ensureListNotContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared")
- // // but the static variant is available to both myapex and the platform
- // ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_static_myapex")
- // ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_static")
+ libfooShared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ if libfooShared.NotAvailableForPlatform() != true {
+ t.Errorf("%q shouldn't be available to platform", libfooShared.String())
+ }
+ libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module)
+ if libfooStatic.NotAvailableForPlatform() != false {
+ t.Errorf("%q should be available to platform", libfooStatic.String())
+ }
}
func TestOverrideApex(t *testing.T) {
@@ -4107,6 +4130,7 @@
native_shared_libs: ["mylib"],
java_libs: ["myjar"],
updatable: true,
+ min_sdk_version: "current",
}
apex_key {
@@ -4404,6 +4428,22 @@
}
}
+func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
+ testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: true,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `)
+}
+
func TestNoUpdatableJarsInBootImage(t *testing.T) {
bp := `
java_library {
@@ -4442,6 +4482,7 @@
key: "some-updatable-apex.key",
java_libs: ["some-updatable-apex-lib"],
updatable: true,
+ min_sdk_version: "current",
}
apex {
@@ -4463,6 +4504,7 @@
key: "com.android.art.something.key",
java_libs: ["some-art-lib"],
updatable: true,
+ min_sdk_version: "current",
}
apex_key {
diff --git a/apex/builder.go b/apex/builder.go
index 5a2134a..fba6b94 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -493,6 +493,10 @@
optFlags = append(optFlags, "--no_hashtree")
}
+ if a.testOnlyShouldSkipPayloadSign() {
+ optFlags = append(optFlags, "--unsigned_payload")
+ }
+
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.
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 5438b14..671adb5 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -92,6 +92,9 @@
if len(c.Properties.AndroidMkWholeStaticLibs) > 0 {
entries.AddStrings("LOCAL_WHOLE_STATIC_LIBRARIES", c.Properties.AndroidMkWholeStaticLibs...)
}
+ if len(c.Properties.AndroidMkHeaderLibs) > 0 {
+ entries.AddStrings("LOCAL_HEADER_LIBRARIES", c.Properties.AndroidMkHeaderLibs...)
+ }
entries.SetString("LOCAL_SOONG_LINK_TYPE", c.makeLinkType)
if c.UseVndk() {
entries.SetBool("LOCAL_USE_VNDK", true)
diff --git a/cc/builder.go b/cc/builder.go
index 990069d..2bedd9c 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -58,7 +58,7 @@
ld, ldRE = remoteexec.StaticRules(pctx, "ld",
blueprint.RuleParams{
- Command: "$ldCmd ${crtBegin} @${out}.rsp " +
+ Command: "$reTemplate$ldCmd ${crtBegin} @${out}.rsp " +
"${libFlags} ${crtEnd} -o ${out} ${ldFlags} ${extraLibFlags}",
CommandDeps: []string{"$ldCmd"},
Rspfile: "${out}.rsp",
@@ -66,28 +66,29 @@
// clang -Wl,--out-implib doesn't update its output file if it hasn't changed.
Restat: true,
},
- &remoteexec.REParams{Labels: map[string]string{"type": "link", "tool": "clang"},
+ &remoteexec.REParams{
+ Labels: map[string]string{"type": "link", "tool": "clang"},
ExecStrategy: "${config.RECXXLinksExecStrategy}",
Inputs: []string{"${out}.rsp"},
RSPFile: "${out}.rsp",
- OutputFiles: []string{"${out}"},
+ OutputFiles: []string{"${out}", "$implicitOutputs"},
ToolchainInputs: []string{"$ldCmd"},
Platform: map[string]string{remoteexec.PoolKey: "${config.RECXXLinksPool}"},
- }, []string{"ldCmd", "crtBegin", "libFlags", "crtEnd", "ldFlags", "extraLibFlags"}, nil)
+ }, []string{"ldCmd", "crtBegin", "libFlags", "crtEnd", "ldFlags", "extraLibFlags"}, []string{"implicitOutputs"})
partialLd, partialLdRE = remoteexec.StaticRules(pctx, "partialLd",
blueprint.RuleParams{
// Without -no-pie, clang 7.0 adds -pie to link Android files,
// but -r and -pie cannot be used together.
- Command: "$ldCmd -fuse-ld=lld -nostdlib -no-pie -Wl,-r ${in} -o ${out} ${ldFlags}",
+ Command: "$reTemplate$ldCmd -fuse-ld=lld -nostdlib -no-pie -Wl,-r ${in} -o ${out} ${ldFlags}",
CommandDeps: []string{"$ldCmd"},
}, &remoteexec.REParams{
Labels: map[string]string{"type": "link", "tool": "clang"},
ExecStrategy: "${config.RECXXLinksExecStrategy}", Inputs: []string{"$inCommaList"},
- OutputFiles: []string{"${out}"},
+ OutputFiles: []string{"${out}", "$implicitOutputs"},
ToolchainInputs: []string{"$ldCmd"},
Platform: map[string]string{remoteexec.PoolKey: "${config.RECXXLinksPool}"},
- }, []string{"ldCmd", "ldFlags"}, []string{"inCommaList"})
+ }, []string{"ldCmd", "ldFlags"}, []string{"inCommaList", "implicitOutputs"})
ar = pctx.AndroidStaticRule("ar",
blueprint.RuleParams{
@@ -192,12 +193,18 @@
_ = pctx.SourcePathVariable("sAbiDumper", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-dumper")
// -w has been added since header-abi-dumper does not need to produce any sort of diagnostic information.
- sAbiDump = pctx.AndroidStaticRule("sAbiDump",
+ sAbiDump, sAbiDumpRE = remoteexec.StaticRules(pctx, "sAbiDump",
blueprint.RuleParams{
- Command: "rm -f $out && $sAbiDumper -o ${out} $in $exportDirs -- $cFlags -w -isystem prebuilts/clang-tools/${config.HostPrebuiltTag}/clang-headers",
+ Command: "rm -f $out && $reTemplate$sAbiDumper -o ${out} $in $exportDirs -- $cFlags -w -isystem prebuilts/clang-tools/${config.HostPrebuiltTag}/clang-headers",
CommandDeps: []string{"$sAbiDumper"},
- },
- "cFlags", "exportDirs")
+ }, &remoteexec.REParams{
+ Labels: map[string]string{"type": "abi-dump", "tool": "header-abi-dumper"},
+ ExecStrategy: "${config.REAbiDumperExecStrategy}",
+ Platform: map[string]string{
+ remoteexec.PoolKey: "${config.RECXXPool}",
+ "InputRootAbsolutePath": android.AbsSrcDirForExistingUseCases(),
+ },
+ }, []string{"cFlags", "exportDirs"}, nil)
_ = pctx.SourcePathVariable("sAbiLinker", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-linker")
@@ -559,8 +566,12 @@
sAbiDumpFile := android.ObjPathWithExt(ctx, subdir, srcFile, "sdump")
sAbiDumpFiles = append(sAbiDumpFiles, sAbiDumpFile)
+ dumpRule := sAbiDump
+ if ctx.Config().IsEnvTrue("RBE_ABI_DUMPER") {
+ dumpRule = sAbiDumpRE
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: sAbiDump,
+ Rule: dumpRule,
Description: "header-abi-dumper " + srcFile.Rel(),
Output: sAbiDumpFile,
Input: srcFile,
@@ -664,8 +675,17 @@
}
rule := ld
+ args := map[string]string{
+ "ldCmd": ldCmd,
+ "crtBegin": crtBegin.String(),
+ "libFlags": strings.Join(libFlagsList, " "),
+ "extraLibFlags": flags.extraLibFlags,
+ "ldFlags": flags.globalLdFlags + " " + flags.localLdFlags,
+ "crtEnd": crtEnd.String(),
+ }
if ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
rule = ldRE
+ args["implicitOutputs"] = strings.Join(implicitOutputs.Strings(), ",")
}
ctx.Build(pctx, android.BuildParams{
@@ -675,14 +695,7 @@
ImplicitOutputs: implicitOutputs,
Inputs: objFiles,
Implicits: deps,
- Args: map[string]string{
- "ldCmd": ldCmd,
- "crtBegin": crtBegin.String(),
- "libFlags": strings.Join(libFlagsList, " "),
- "extraLibFlags": flags.extraLibFlags,
- "ldFlags": flags.globalLdFlags + " " + flags.localLdFlags,
- "crtEnd": crtEnd.String(),
- },
+ Args: args,
})
}
diff --git a/cc/cc.go b/cc/cc.go
index 66425c7..082816e 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -223,6 +223,7 @@
AndroidMkStaticLibs []string `blueprint:"mutated"`
AndroidMkRuntimeLibs []string `blueprint:"mutated"`
AndroidMkWholeStaticLibs []string `blueprint:"mutated"`
+ AndroidMkHeaderLibs []string `blueprint:"mutated"`
HideFromMake bool `blueprint:"mutated"`
PreventInstall bool `blueprint:"mutated"`
ApexesProvidingSharedLibs []string `blueprint:"mutated"`
@@ -2606,6 +2607,9 @@
case wholeStaticDepTag:
c.Properties.AndroidMkWholeStaticLibs = append(
c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName))
+ case headerDepTag:
+ c.Properties.AndroidMkHeaderLibs = append(
+ c.Properties.AndroidMkHeaderLibs, makeLibName(depName))
}
})
diff --git a/cc/config/global.go b/cc/config/global.go
index d85ac5f..39c4c33 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -257,8 +257,10 @@
return ""
})
+ pctx.VariableFunc("RECXXPool", envOverrideFunc("RBE_CXX_POOL", remoteexec.DefaultPool))
pctx.VariableFunc("RECXXLinksPool", envOverrideFunc("RBE_CXX_LINKS_POOL", remoteexec.DefaultPool))
pctx.VariableFunc("RECXXLinksExecStrategy", envOverrideFunc("RBE_CXX_LINKS_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+ pctx.VariableFunc("REAbiDumperExecStrategy", envOverrideFunc("RBE_ABI_DUMPER_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
}
var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
diff --git a/cc/fuzz.go b/cc/fuzz.go
index b7173a3..ebe4252 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -366,10 +366,10 @@
return
}
- // Discard vendor-NDK-linked + ramdisk + recovery modules, they're duplicates of
+ // Discard ramdisk + recovery modules, they're duplicates of
// fuzz targets we're going to package anyway.
if !ccModule.Enabled() || ccModule.Properties.PreventInstall ||
- ccModule.UseVndk() || ccModule.InRamdisk() || ccModule.InRecovery() {
+ ccModule.InRamdisk() || ccModule.InRecovery() {
return
}
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 754b96a..953e85f 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -375,7 +375,10 @@
specifiedDeps := specifiedDeps{}
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps)
- p.SharedLibs = specifiedDeps.sharedLibs
+ if !ccModule.HasStubsVariants() {
+ // Propagate dynamic dependencies for implementation libs, but not stubs.
+ p.SharedLibs = specifiedDeps.sharedLibs
+ }
p.SystemSharedLibs = specifiedDeps.systemSharedLibs
}
p.exportedGeneratedHeaders = ccModule.ExportedGeneratedHeaders()
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 0e1bfc6..f984966 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -47,6 +47,8 @@
const SystemPartition = "/system/"
const SystemOtherPartition = "/system_other/"
+var DexpreoptRunningInSoong = false
+
// GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a
// ModuleConfig. The produced files and their install locations will be available through rule.Installs().
func GenerateDexpreoptRule(ctx android.PathContext, globalSoong *GlobalSoongConfig,
@@ -589,7 +591,14 @@
// at that time (Soong processes the jars in dependency order, which may be different from the
// the system server classpath order).
func SystemServerDexJarHostPath(ctx android.PathContext, jar string) android.OutputPath {
- return android.PathForOutput(ctx, "system_server_dexjars", jar+".jar")
+ if DexpreoptRunningInSoong {
+ // Soong module, just use the default output directory $OUT/soong.
+ return android.PathForOutput(ctx, "system_server_dexjars", jar+".jar")
+ } else {
+ // Make module, default output directory is $OUT (passed via the "null config" created
+ // by dexpreopt_gen). Append Soong subdirectory to match Soong module paths.
+ return android.PathForOutput(ctx, "soong", "system_server_dexjars", jar+".jar")
+ }
}
func contains(l []string, s string) bool {
diff --git a/java/androidmk.go b/java/androidmk.go
index 68da23e..2c29192 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -676,6 +676,7 @@
func(entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_CERTIFICATE", r.certificate.AndroidMkString())
entries.SetPath("LOCAL_MODULE_PATH", r.installDir.ToMakePath())
+ entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", r.properties.Overrides...)
},
},
}}
diff --git a/java/app.go b/java/app.go
index 2ee9057..4f4a8d3 100755
--- a/java/app.go
+++ b/java/app.go
@@ -112,7 +112,9 @@
IsCoverageVariant bool `blueprint:"mutated"`
// Whether this app is considered mainline updatable or not. When set to true, this will enforce
- // additional rules for making sure that the APK is truly updatable. Default is false.
+ // additional rules to make sure an app can safely be updated. Default is false.
+ // Prefer using other specific properties if build behaviour must be changed; avoid using this
+ // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Updatable *bool
}
@@ -262,6 +264,9 @@
if !a.sdkVersion().stable() {
ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.sdkVersion())
}
+ if String(a.deviceProperties.Min_sdk_version) == "" {
+ ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
+ }
}
a.checkPlatformAPI(ctx)
@@ -1410,6 +1415,13 @@
// list of android_app modules whose resources are extracted and linked against
Resource_libs []string
+
+ // Names of modules to be overridden. Listed modules can only be other overlays
+ // (in Make or Soong).
+ // This does not completely prevent installation of the overridden overlays, but if both
+ // overlays would be installed by default (in PRODUCT_PACKAGES) the other overlay will be removed
+ // from PRODUCT_PACKAGES.
+ Overrides []string
}
// RuntimeResourceOverlayModule interface is used by the apex package to gather information from
diff --git a/java/app_test.go b/java/app_test.go
index 7b04e46..c1a0cdd 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -276,6 +276,7 @@
name: "foo",
srcs: ["a.java"],
sdk_version: "29",
+ min_sdk_version: "29",
updatable: true,
}`,
},
@@ -285,6 +286,7 @@
name: "foo",
srcs: ["a.java"],
sdk_version: "system_29",
+ min_sdk_version: "29",
updatable: true,
}`,
},
@@ -294,6 +296,7 @@
name: "foo",
srcs: ["a.java"],
sdk_version: "current",
+ min_sdk_version: "29",
updatable: true,
}`,
},
@@ -303,6 +306,7 @@
name: "foo",
srcs: ["a.java"],
sdk_version: "system_current",
+ min_sdk_version: "29",
updatable: true,
}`,
},
@@ -312,6 +316,7 @@
name: "foo",
srcs: ["a.java"],
sdk_version: "module_current",
+ min_sdk_version: "29",
updatable: true,
}`,
},
@@ -321,6 +326,7 @@
name: "foo",
srcs: ["a.java"],
sdk_version: "core_current",
+ min_sdk_version: "29",
updatable: true,
}`,
},
@@ -330,6 +336,7 @@
name: "foo",
srcs: ["a.java"],
platform_apis: true,
+ min_sdk_version: "29",
updatable: true,
}`,
expectedError: "Updatable apps must use stable SDKs",
@@ -340,6 +347,7 @@
name: "foo",
srcs: ["a.java"],
sdk_version: "core_platform",
+ min_sdk_version: "29",
updatable: true,
}`,
expectedError: "Updatable apps must use stable SDKs",
@@ -350,9 +358,20 @@
name: "foo",
srcs: ["a.java"],
updatable: true,
+ min_sdk_version: "29",
}`,
expectedError: "Updatable apps must use stable SDK",
},
+ {
+ name: "Must specify min_sdk_version",
+ bp: `android_app {
+ name: "app_without_min_sdk_version",
+ srcs: ["a.java"],
+ sdk_version: "29",
+ updatable: true,
+ }`,
+ expectedError: "updatable apps must set min_sdk_version.",
+ },
}
for _, test := range testCases {
@@ -2470,6 +2489,7 @@
certificate: "platform",
product_specific: true,
theme: "faza",
+ overrides: ["foo"],
}
android_library {
@@ -2517,14 +2537,15 @@
if expected != signingFlag {
t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
}
- path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_CERTIFICATE"]
+ androidMkEntries := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0]
+ path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
if !reflect.DeepEqual(path, expectedPath) {
t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
}
// Check device location.
- path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+ path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
expectedPath = []string{"/tmp/target/product/test_device/product/overlay"}
if !reflect.DeepEqual(path, expectedPath) {
t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
@@ -2532,9 +2553,16 @@
// A themed module has a different device location
m = ctx.ModuleForTests("foo_themed", "android_common")
- path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+ androidMkEntries = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0]
+ path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
expectedPath = []string{"/tmp/target/product/test_device/product/overlay/faza"}
if !reflect.DeepEqual(path, expectedPath) {
t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
}
+
+ overrides := androidMkEntries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
+ expectedOverrides := []string{"foo"}
+ if !reflect.DeepEqual(overrides, expectedOverrides) {
+ t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
+ }
}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index fba0b97..4725b07 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -62,6 +62,10 @@
}
}
+func init() {
+ dexpreopt.DexpreoptRunningInSoong = true
+}
+
func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
global := dexpreopt.GetGlobalConfig(ctx)
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 8df3c2d..a9b5d5f 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1540,40 +1540,35 @@
apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
- updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
+
+ if baselineFile.Valid() {
+ ctx.PropertyErrorf("current API check can't have a baseline file. (module %s)", ctx.ModuleName())
+ }
d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
rule := android.NewRuleBuilder()
+ // Diff command line.
+ // -F matches the closest "opening" line, such as "package xxx{"
+ // and " public class Yyy {".
+ diff := `diff -u -F '{ *$'`
+
rule.Command().Text("( true")
+ rule.Command().
+ Text(diff).
+ Input(apiFile).Input(d.apiFile)
- srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
- srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
-
- cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
- deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
-
- cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
- FlagWithInput("--check-compatibility:api:current ", apiFile).
- FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
-
- d.inclusionAnnotationsFlags(ctx, cmd)
- d.mergeAnnoDirFlags(ctx, cmd)
-
- if baselineFile.Valid() {
- cmd.FlagWithInput("--baseline ", baselineFile.Path())
- cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
- }
-
- zipSyncCleanupCmd(rule, srcJarDir)
+ rule.Command().
+ Text(diff).
+ Input(removedApiFile).Input(d.removedApiFile)
msg := fmt.Sprintf(`\n******************************\n`+
`You have tried to change the API from what has been previously approved.\n\n`+
`To make these errors go away, you have two choices:\n`+
- ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
- ` errors above.\n\n`+
- ` 2. You can update current.txt by executing the following command:\n`+
+ ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
+ ` to the new methods, etc. shown in the above diff.\n\n`+
+ ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
` make %s-update-current-api\n\n`+
` To submit the revised current.txt to the main Android repository,\n`+
` you will need approval.\n`+
@@ -1586,7 +1581,7 @@
Text("; exit 38").
Text(")")
- rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
+ rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "check current API")
d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
diff --git a/remoteexec/remoteexec.go b/remoteexec/remoteexec.go
index d43dc6c..f511922 100644
--- a/remoteexec/remoteexec.go
+++ b/remoteexec/remoteexec.go
@@ -148,7 +148,8 @@
// locally executable rule and the second rule is a remotely executable rule.
func StaticRules(ctx android.PackageContext, name string, ruleParams blueprint.RuleParams, reParams *REParams, commonArgs []string, reArgs []string) (blueprint.Rule, blueprint.Rule) {
ruleParamsRE := ruleParams
- ruleParamsRE.Command = reParams.Template() + ruleParamsRE.Command
+ ruleParams.Command = strings.ReplaceAll(ruleParams.Command, "$reTemplate", "")
+ ruleParamsRE.Command = strings.ReplaceAll(ruleParamsRE.Command, "$reTemplate", reParams.Template())
return ctx.AndroidStaticRule(name, ruleParams, commonArgs...),
ctx.AndroidRemoteStaticRule(name+"RE", android.RemoteRuleSupports{RBE: true}, ruleParamsRE, append(commonArgs, reArgs...)...)
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 780da9f..733f7ac 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -1749,7 +1749,12 @@
}
cc_library {
+ name: "internaldep",
+ }
+
+ cc_library {
name: "stubslib",
+ shared_libs: ["internaldep"],
stubs: {
symbol_file: "some/where/stubslib.map.txt",
versions: ["1", "2", "3"],