From e3867548986027f8430fc9ab17cc12c0b7cdb599 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Thu, 3 Dec 2020 17:28:25 +0900 Subject: [PATCH] target.apex.exclude_[shared|static]_libs to cc_* modules The property is used to exclude some shared and static libs when the module is built for an APEX. Bug: 166468760 Test: m Change-Id: I0dcaa4ae94c01aa00dc5539c60d3054c57fd8824 --- apex/apex.go | 13 +++++++++++++ apex/apex_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++ cc/cc.go | 21 ++++++++++++++++++++ cc/linker.go | 19 ++++++++++++++++++ 4 files changed, 102 insertions(+) diff --git a/apex/apex.go b/apex/apex.go index 7ab74541f..986246fe1 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1681,6 +1681,19 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Don't track further return false } + + // If the dep is not considered to be in the same + // apex, don't add it to filesInfo so that it is not + // included in this APEX. + // TODO(jiyong): move this to at the top of the + // else-if clause for the indirect dependencies. + // Currently, that's impossible because we would + // like to record requiredNativeLibs even when + // DepIsInSameAPex is false. + if !am.DepIsInSameApex(ctx, am) { + return false + } + filesInfo = append(filesInfo, af) return true // track transitive dependencies } diff --git a/apex/apex_test.go b/apex/apex_test.go index 0b67ef577..b6369d3df 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -6237,6 +6237,55 @@ func TestPreferredPrebuiltSharedLibDep(t *testing.T) { ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherlib\n") } +func TestExcludeDependency(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", + apex_available: ["myapex"], + shared_libs: ["mylib2"], + target: { + apex: { + exclude_shared_libs: ["mylib2"], + }, + }, + } + + cc_library { + name: "mylib2", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + } + `) + + // Check if mylib is linked to mylib2 for the non-apex target + ldFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"] + ensureContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") + + // Make sure that the link doesn't occur for the apex target + ldFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] + ensureNotContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared_apex10000/mylib2.so") + + // It shouldn't appear in the copy cmd as well. + copyCmds := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule").Args["copy_commands"] + ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") +} + func TestMain(m *testing.M) { run := func() int { setUp() diff --git a/cc/cc.go b/cc/cc.go index b1c126431..5cd3b04dc 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -129,6 +129,9 @@ type Deps struct { // Used for host bionic LinkerFlagsFile string DynamicLinker string + + // List of libs that need to be excluded for APEX variant + ExcludeLibsForApex []string } // PathDeps is a struct containing file paths to dependencies of a module. @@ -572,6 +575,9 @@ type libraryDependencyTag struct { staticUnwinder bool makeSuffix string + + // Whether or not this dependency has to be followed for the apex variants + excludeInApex bool } // header returns true if the libraryDependencyTag is tagging a header lib dependency. @@ -1950,6 +1956,9 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { if inList(lib, deps.ReexportStaticLibHeaders) { depTag.reexportFlags = true } + if inList(lib, deps.ExcludeLibsForApex) { + depTag.excludeInApex = true + } if impl, ok := syspropImplLibraries[lib]; ok { lib = impl @@ -1987,6 +1996,9 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { if inList(lib, deps.ReexportSharedLibHeaders) { depTag.reexportFlags = true } + if inList(lib, deps.ExcludeLibsForApex) { + depTag.excludeInApex = true + } if impl, ok := syspropImplLibraries[lib]; ok { lib = impl @@ -2416,6 +2428,10 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { return } + if !apexInfo.IsForPlatform() && libDepTag.excludeInApex { + return + } + depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo) var ptr *android.Paths @@ -2435,6 +2451,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } return } + sharedLibraryInfo := ctx.OtherModuleProvider(dep, SharedLibraryInfoProvider).(SharedLibraryInfo) sharedLibraryStubsInfo := ctx.OtherModuleProvider(dep, SharedLibraryImplementationStubsInfoProvider).(SharedLibraryImplementationStubsInfo) @@ -3015,6 +3032,10 @@ func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu // linked; the dependency is used only during the compilation phase. return false } + + if isLibDepTag && libDepTag.excludeInApex { + return false + } } if depTag == stubImplDepTag || depTag == llndkImplDep { // We don't track beyond LLNDK or from an implementation library to its stubs. diff --git a/cc/linker.go b/cc/linker.go index 9d4a643d2..7bc4105c9 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -174,6 +174,15 @@ type BaseLinkerProperties struct { // variants. Shared_libs []string } + Apex struct { + // list of shared libs that should not be used to build the apex variant of + // the C/C++ module. + Exclude_shared_libs []string + + // list of static libs that should not be used to build the apex ramdisk + // variant of the C/C++ module. + Exclude_static_libs []string + } } // make android::build:GetBuildNumber() available containing the build ID. @@ -240,6 +249,16 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Exclude_static_libs) deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Exclude_static_libs) + // Record the libraries that need to be excluded when building for APEX. Unlike other + // target.*.exclude_* properties, SharedLibs and StaticLibs are not modified here because + // this module hasn't yet passed the apexMutator. Therefore, we can't tell whether this is + // an apex variant of not. Record the exclude list in the deps struct for now. The info is + // used to mark the dependency tag when adding dependencies to the deps. Then inside + // GenerateAndroidBuildActions, the marked dependencies are ignored (i.e. not used) for APEX + // variants. + deps.ExcludeLibsForApex = append(deps.ExcludeLibsForApex, linker.Properties.Target.Apex.Exclude_shared_libs...) + deps.ExcludeLibsForApex = append(deps.ExcludeLibsForApex, linker.Properties.Target.Apex.Exclude_static_libs...) + if Bool(linker.Properties.Use_version_lib) { deps.WholeStaticLibs = append(deps.WholeStaticLibs, "libbuildversion") }