Prohibit dependencies outside of uses_sdks
When an APEX is built with uses_sdks, any depedndency from the APEX to the outside of the APEX should be from the SDKs that the APEX is built against. Bug: 138182343 Test: m Change-Id: I1c2ffe8d28ccf648d928ea59652c2d0070bf10eb
This commit is contained in:
parent
d7d5e5a1ac
commit
a7bc8ad0b9
|
@ -77,6 +77,10 @@ type ApexModule interface {
|
|||
|
||||
// Tests if this module is available for the specified APEX or ":platform"
|
||||
AvailableFor(what string) bool
|
||||
|
||||
// DepIsInSameApex tests if the other module 'dep' is installed to the same
|
||||
// APEX as this module
|
||||
DepIsInSameApex(ctx BaseModuleContext, dep Module) bool
|
||||
}
|
||||
|
||||
type ApexProperties struct {
|
||||
|
@ -154,6 +158,13 @@ func (m *ApexModuleBase) AvailableFor(what string) bool {
|
|||
return CheckAvailableForApex(what, m.ApexProperties.Apex_available)
|
||||
}
|
||||
|
||||
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.
|
||||
// This is overridden by some module types like apex.ApexBundle, cc.Module, java.Module, etc.
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
|
||||
for _, n := range m.ApexProperties.Apex_available {
|
||||
if n == availableToPlatform || n == availableToAnyApex {
|
||||
|
|
|
@ -44,6 +44,17 @@ func (s SdkRef) Unversioned() bool {
|
|||
return s.Version == ""
|
||||
}
|
||||
|
||||
// String returns string representation of this SdkRef for debugging purpose
|
||||
func (s SdkRef) String() string {
|
||||
if s.Name == "" {
|
||||
return "(No Sdk)"
|
||||
}
|
||||
if s.Unversioned() {
|
||||
return s.Name
|
||||
}
|
||||
return s.Name + string(SdkVersionSeparator) + s.Version
|
||||
}
|
||||
|
||||
// SdkVersionSeparator is a character used to separate an sdk name and its version
|
||||
const SdkVersionSeparator = '@'
|
||||
|
||||
|
|
|
@ -791,6 +791,11 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *apexBundle) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
|
||||
// direct deps of an APEX bundle are all part of the APEX bundle
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
|
||||
certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
|
||||
if overridden {
|
||||
|
|
10
cc/cc.go
10
cc/cc.go
|
@ -2182,6 +2182,16 @@ func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Write
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
|
||||
if depTag, ok := ctx.OtherModuleDependencyTag(dep).(dependencyTag); ok {
|
||||
if cc, ok := dep.(*Module); ok && cc.IsStubs() && depTag.shared {
|
||||
// dynamic dep to a stubs lib crosses APEX boundary
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//
|
||||
// Defaults
|
||||
//
|
||||
|
|
|
@ -190,6 +190,7 @@ func GatherRequiredDepsForTest(os android.OsType) string {
|
|||
name: "crtbegin_so",
|
||||
recovery_available: true,
|
||||
vendor_available: true,
|
||||
stl: "none",
|
||||
}
|
||||
|
||||
cc_object {
|
||||
|
@ -208,6 +209,7 @@ func GatherRequiredDepsForTest(os android.OsType) string {
|
|||
name: "crtend_so",
|
||||
recovery_available: true,
|
||||
vendor_available: true,
|
||||
stl: "none",
|
||||
}
|
||||
|
||||
cc_object {
|
||||
|
|
|
@ -1567,6 +1567,12 @@ func (j *Module) hasCode(ctx android.ModuleContext) bool {
|
|||
return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
|
||||
}
|
||||
|
||||
func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
|
||||
depTag := ctx.OtherModuleDependencyTag(dep)
|
||||
// dependencies other than the static linkage are all considered crossing APEX boundary
|
||||
return depTag == staticLibTag
|
||||
}
|
||||
|
||||
//
|
||||
// Java libraries (.jar file)
|
||||
//
|
||||
|
|
29
sdk/sdk.go
29
sdk/sdk.go
|
@ -122,6 +122,7 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
|
|||
// should have been mutated for the apex before the SDK requirements are set.
|
||||
ctx.TopDown("SdkDepsMutator", sdkDepsMutator).Parallel()
|
||||
ctx.BottomUp("SdkDepsReplaceMutator", sdkDepsReplaceMutator).Parallel()
|
||||
ctx.TopDown("SdkRequirementCheck", sdkRequirementsMutator).Parallel()
|
||||
}
|
||||
|
||||
type dependencyTag struct {
|
||||
|
@ -229,3 +230,31 @@ func sdkDepsReplaceMutator(mctx android.BottomUpMutatorContext) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6: ensure that the dependencies from outside of the APEX are all from the required SDKs
|
||||
func sdkRequirementsMutator(mctx android.TopDownMutatorContext) {
|
||||
if m, ok := mctx.Module().(interface {
|
||||
DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool
|
||||
RequiredSdks() android.SdkRefs
|
||||
}); ok {
|
||||
requiredSdks := m.RequiredSdks()
|
||||
if len(requiredSdks) == 0 {
|
||||
return
|
||||
}
|
||||
mctx.VisitDirectDeps(func(dep android.Module) {
|
||||
if mctx.OtherModuleDependencyTag(dep) == android.DefaultsDepTag {
|
||||
// dependency to defaults is always okay
|
||||
return
|
||||
}
|
||||
|
||||
// If the dep is from outside of the APEX, but is not in any of the
|
||||
// required SDKs, we know that the dep is a violation.
|
||||
if sa, ok := dep.(android.SdkAware); ok {
|
||||
if !m.DepIsInSameApex(mctx, dep) && !requiredSdks.Contains(sa.ContainingSdk()) {
|
||||
mctx.ModuleErrorf("depends on %q (in SDK %q) that isn't part of the required SDKs: %v",
|
||||
sa.Name(), sa.ContainingSdk(), requiredSdks)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,23 @@ func testSdk(t *testing.T, bp string) (*android.TestContext, android.Config) {
|
|||
return ctx, config
|
||||
}
|
||||
|
||||
func testSdkError(t *testing.T, pattern, bp string) {
|
||||
t.Helper()
|
||||
ctx, config := testSdkContext(t, bp)
|
||||
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
|
||||
if len(errs) > 0 {
|
||||
android.FailIfNoMatchingErrors(t, pattern, errs)
|
||||
return
|
||||
}
|
||||
_, errs = ctx.PrepareBuildActions(config)
|
||||
if len(errs) > 0 {
|
||||
android.FailIfNoMatchingErrors(t, pattern, errs)
|
||||
return
|
||||
}
|
||||
|
||||
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
|
||||
}
|
||||
|
||||
// ensure that 'result' contains 'expected'
|
||||
func ensureContains(t *testing.T, result string, expected string) {
|
||||
t.Helper()
|
||||
|
@ -303,6 +320,63 @@ func TestBasicSdkWithCc(t *testing.T) {
|
|||
ensureListContains(t, pathsToStrings(cpplibForMyApex2.Rule("ld").Implicits), sdkMemberV2.String())
|
||||
}
|
||||
|
||||
func TestDepNotInRequiredSdks(t *testing.T) {
|
||||
testSdkError(t, `module "myjavalib".*depends on "otherlib".*that isn't part of the required SDKs:.*`, `
|
||||
sdk {
|
||||
name: "mysdk",
|
||||
java_libs: ["sdkmember"],
|
||||
}
|
||||
|
||||
sdk_snapshot {
|
||||
name: "mysdk@1",
|
||||
java_libs: ["sdkmember_mysdk_1"],
|
||||
}
|
||||
|
||||
java_import {
|
||||
name: "sdkmember",
|
||||
prefer: false,
|
||||
host_supported: true,
|
||||
}
|
||||
|
||||
java_import {
|
||||
name: "sdkmember_mysdk_1",
|
||||
sdk_member_name: "sdkmember",
|
||||
host_supported: true,
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "myjavalib",
|
||||
srcs: ["Test.java"],
|
||||
libs: [
|
||||
"sdkmember",
|
||||
"otherlib",
|
||||
],
|
||||
system_modules: "none",
|
||||
sdk_version: "none",
|
||||
compile_dex: true,
|
||||
host_supported: true,
|
||||
}
|
||||
|
||||
// this lib is no in mysdk
|
||||
java_library {
|
||||
name: "otherlib",
|
||||
srcs: ["Test.java"],
|
||||
system_modules: "none",
|
||||
sdk_version: "none",
|
||||
compile_dex: true,
|
||||
host_supported: true,
|
||||
}
|
||||
|
||||
apex {
|
||||
name: "myapex",
|
||||
java_libs: ["myjavalib"],
|
||||
uses_sdks: ["mysdk@1"],
|
||||
key: "myapex.key",
|
||||
certificate: ":myapex.cert",
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
var buildDir string
|
||||
|
||||
func setUp() {
|
||||
|
|
Loading…
Reference in New Issue