diff --git a/android/apex.go b/android/apex.go index 17df76240..99b13ab72 100644 --- a/android/apex.go +++ b/android/apex.go @@ -19,6 +19,7 @@ import ( "sync" "github.com/google/blueprint" + "github.com/google/blueprint/proptools" ) // ApexModule is the interface that a module type is expected to implement if @@ -74,9 +75,15 @@ type ApexModule interface { // Sets the name of the apex variant of this module. Called inside // CreateApexVariations. setApexName(apexName string) + + // Return the no_apex property + NoApex() bool } type ApexProperties struct { + // Whether this module should not be part of any APEX. Default is false. + No_apex *bool + // Name of the apex variant that this module is mutated into ApexName string `blueprint:"mutated"` } @@ -125,6 +132,10 @@ func (m *ApexModuleBase) IsInstallableToApex() bool { return false } +func (m *ApexModuleBase) NoApex() bool { + return proptools.Bool(m.ApexProperties.No_apex) +} + func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []blueprint.Module { if len(m.apexVariations) > 0 { sort.Strings(m.apexVariations) diff --git a/apex/apex.go b/apex/apex.go index 574604bb1..cbca8901e 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -126,6 +126,16 @@ var ( usesTag = dependencyTag{name: "uses"} ) +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"}, + } +) + func init() { pctx.Import("android/soong/android") pctx.Import("android/soong/java") @@ -1005,6 +1015,16 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return filesInfo[i].builtFile.String() < filesInfo[j].builtFile.String() }) + // check no_apex modules + whitelist := whitelistNoApex[ctx.ModuleName()] + for i := range filesInfo { + if am, ok := filesInfo[i].module.(android.ApexModule); ok { + if am.NoApex() && !android.InList(filesInfo[i].moduleName, whitelist) { + ctx.ModuleErrorf("tries to include no_apex module %s", filesInfo[i].moduleName) + } + } + } + // 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 { diff --git a/apex/apex_test.go b/apex/apex_test.go index e06c193c5..c3c1fc9fb 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -1768,6 +1768,88 @@ func TestApexUsesFailsIfUseVenderMismatch(t *testing.T) { `) } +func TestApexUsesFailsIfUseNoApex(t *testing.T) { + testApexError(t, `tries to include no_apex module mylib2`, ` + apex { + name: "commonapex", + key: "myapex.key", + native_shared_libs: ["mylib"], + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + shared_libs: ["mylib2"], + system_shared_libs: [], + stl: "none", + } + + cc_library { + name: "mylib2", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + no_apex: true, + } + `) + + ctx, _ := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["mylib"], + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + shared_libs: ["mylib2"], + system_shared_libs: [], + stl: "none", + } + + cc_library { + name: "mylib2", + srcs: ["mylib.cpp"], + shared_libs: ["mylib3"], + system_shared_libs: [], + stl: "none", + stubs: { + versions: ["1", "2", "3"], + }, + } + + cc_library { + name: "mylib3", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + no_apex: true, + } + `) + + module := ctx.ModuleForTests("myapex", "android_common_myapex") + apexRule := module.Rule("apexRule") + copyCmds := apexRule.Args["copy_commands"] + + ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") + ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") + ensureNotContains(t, copyCmds, "image.apex/lib64/mylib3.so") + +} + func TestMain(m *testing.M) { run := func() int { setUp()