Loading android/androidmk.go +4 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading android/apex.go +20 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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. Loading apex/apex.go +55 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 { Loading apex/apex_test.go +50 −27 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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", Loading @@ -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 Loading
android/androidmk.go +4 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
android/apex.go +20 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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. Loading
apex/apex.go +55 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 { Loading
apex/apex_test.go +50 −27 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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", Loading @@ -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