From 16e91a067d13698c59323349d5251aab9dca479f Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Thu, 20 Dec 2018 18:18:08 +0900 Subject: [PATCH] Fix: static dependency across an APEX is lost This change fixes following problem: 1) a native lib having stubs is defined. 2) the lib is included in an APEX. 3) a static binary is linking the lib from outside of the APEX. 4) then, the dependency from the binary to the lib is vanishing. This is happening because cc.depsToPaths() mistakely does not distinguish static lib deps from shared lib deps. For shared lib deps, it creates two dependencies (one for stubs variant and the other for non-stubs variant) and choose the stubs variant when the lib and the current module is not in the same APEX (i.e. dependency to the non-stubs variant is discarded). However, since we don't have stubs variant for static library, it ends up having no dependency to the library if the link is static. Fixing the issue by skipping the variant selection routine when the link is static. Test: m (apex_test added) Test: build with https://android-review.googlesource.com/c/platform/bionic/+/849044 Change-Id: I21102a31cc5c0b105da2affdd035bd5cc571a6ab --- apex/apex_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++ cc/binary.go | 4 ++-- cc/cc.go | 7 ++++++- cc/cc_test.go | 2 +- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/apex/apex_test.go b/apex/apex_test.go index 77117c550..dd5bf7082 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -41,6 +41,7 @@ func testApex(t *testing.T, bp string) *android.TestContext { ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory)) ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory)) + ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(cc.BinaryFactory)) ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory)) ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory)) ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory)) @@ -614,3 +615,54 @@ func TestUseVendor(t *testing.T) { ensureNotContains(t, inputsString, "android_arm64_armv8-a_core_shared_myapex/mylib.so") ensureNotContains(t, inputsString, "android_arm64_armv8-a_core_shared_myapex/mylib2.so") } + +func TestStaticLinking(t *testing.T) { + 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"], + system_shared_libs: [], + stl: "none", + stubs: { + versions: ["1", "2", "3"], + }, + } + + cc_binary { + name: "not_in_apex", + srcs: ["mylib.cpp"], + static_libs: ["mylib"], + static_executable: true, + system_shared_libs: [], + stl: "none", + } + + cc_object { + name: "crtbegin_static", + stl: "none", + } + + cc_object { + name: "crtend_android", + stl: "none", + } + + `) + + ldFlags := ctx.ModuleForTests("not_in_apex", "android_arm64_armv8-a_core").Rule("ld").Args["libFlags"] + + // Ensure that not_in_apex is linking with the static variant of mylib + ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_core_static/mylib.a") +} diff --git a/cc/binary.go b/cc/binary.go index bc9abfe4b..c9e6cab50 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -51,12 +51,12 @@ type BinaryLinkerProperties struct { } func init() { - android.RegisterModuleType("cc_binary", binaryFactory) + android.RegisterModuleType("cc_binary", BinaryFactory) android.RegisterModuleType("cc_binary_host", binaryHostFactory) } // Module factory for binaries -func binaryFactory() android.Module { +func BinaryFactory() android.Module { module, _ := NewBinary(android.HostAndDeviceSupported) return module.Init() } diff --git a/cc/cc.go b/cc/cc.go index 139e85feb..c3e554cbd 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1419,7 +1419,12 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } if t, ok := depTag.(dependencyTag); ok && t.library { - if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok { + depIsStatic := false + switch depTag { + case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag: + depIsStatic = true + } + if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok && !depIsStatic { depIsStubs := dependentLibrary.buildStubs() depHasStubs := ccDep.HasStubsVariants() depInSameApex := android.DirectlyInApex(c.ApexName(), depName) diff --git a/cc/cc_test.go b/cc/cc_test.go index 29974c99a..96233a10e 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -53,7 +53,7 @@ func TestMain(m *testing.M) { func createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext { ctx := android.NewTestArchContext() - ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(binaryFactory)) + ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(BinaryFactory)) ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory)) ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory)) ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))