Merge "mark platform un-availability"
This commit is contained in:
commit
01db260858
|
@ -198,6 +198,10 @@ func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod bluep
|
|||
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 {
|
||||
|
|
|
@ -101,6 +101,16 @@ type ApexModule interface {
|
|||
// 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 @@ type ApexProperties struct {
|
|||
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 @@ func (m *ApexModuleBase) AvailableFor(what string) bool {
|
|||
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.
|
||||
|
|
55
apex/apex.go
55
apex/apex.go
|
@ -746,6 +746,7 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
|
|||
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
|
||||
|
@ -784,6 +785,60 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) {
|
|||
})
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
|
|
@ -3750,22 +3750,12 @@ func TestApexAvailable_InvalidApexName(t *testing.T) {
|
|||
}`)
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -3778,16 +3768,52 @@ func TestApexAvailable_CreatedForPlatform(t *testing.T) {
|
|||
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",
|
||||
|
@ -3810,17 +3836,14 @@ func TestApexAvailable_CreatedForApex(t *testing.T) {
|
|||
},
|
||||
}`)
|
||||
|
||||
// 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) {
|
||||
|
|
Loading…
Reference in New Issue