diff options
-rw-r--r-- | apex/apex.go | 36 | ||||
-rw-r--r-- | apex/apex_test.go | 54 |
2 files changed, 87 insertions, 3 deletions
diff --git a/apex/apex.go b/apex/apex.go index 149f78220..e525aff5c 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1696,6 +1696,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.checkUpdatable(ctx) a.checkMinSdkVersion(ctx) a.checkStaticLinkingToStubLibraries(ctx) + a.checkStaticExecutables(ctx) if len(a.properties.Tests) > 0 && !a.testApex { ctx.PropertyErrorf("tests", "property allowed only in apex_test module type") return @@ -2487,6 +2488,41 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { }) } +// checkStaticExecutable ensures that executables in an APEX are not static. +func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) { + // No need to run this for host APEXes + if ctx.Host() { + return + } + + ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) { + if ctx.OtherModuleDependencyTag(module) != executableTag { + return + } + + if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() { + apex := a.ApexVariationName() + exec := ctx.OtherModuleName(module) + if isStaticExecutableAllowed(apex, exec) { + return + } + ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module)) + } + }) +} + +// A small list of exceptions where static executables are allowed in APEXes. +func isStaticExecutableAllowed(apex string, exec string) bool { + m := map[string][]string{ + "com.android.runtime": []string{ + "linker", + "linkerconfig", + }, + } + execNames, ok := m[apex] + return ok && android.InList(exec, execNames) +} + // Collect information for opening IDE project files in java/jdeps.go. func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) { dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...) diff --git a/apex/apex_test.go b/apex/apex_test.go index f58bf6cc5..41bfcea49 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -374,7 +374,6 @@ func TestBasicApex(t *testing.T) { symlinks: ["foo_link_"], symlink_preferred_arch: true, system_shared_libs: [], - static_executable: true, stl: "none", apex_available: [ "myapex", "com.android.gki.*" ], } @@ -2494,7 +2493,6 @@ func TestFilesInSubDir(t *testing.T) { srcs: ["mylib.cpp"], relative_install_path: "foo/bar", system_shared_libs: [], - static_executable: true, stl: "none", apex_available: [ "myapex" ], } @@ -2554,7 +2552,6 @@ func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) { name: "mybin", relative_install_path: "foo/bar", system_shared_libs: [], - static_executable: true, stl: "none", apex_available: [ "myapex" ], native_bridge_supported: true, @@ -8188,6 +8185,57 @@ func TestApexJavaCoverage(t *testing.T) { } } +func TestProhibitStaticExecutable(t *testing.T) { + testApexError(t, `executable mybin is static`, ` + apex { + name: "myapex", + key: "myapex.key", + binaries: ["mybin"], + min_sdk_version: "29", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_binary { + name: "mybin", + srcs: ["mylib.cpp"], + relative_install_path: "foo/bar", + static_executable: true, + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + min_sdk_version: "29", + } + `) + + testApexError(t, `executable mybin.rust is static`, ` + apex { + name: "myapex", + key: "myapex.key", + binaries: ["mybin.rust"], + min_sdk_version: "29", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + rust_binary { + name: "mybin.rust", + srcs: ["foo.rs"], + static_executable: true, + apex_available: ["myapex"], + min_sdk_version: "29", + } + `) +} + func TestMain(m *testing.M) { os.Exit(m.Run()) } |