Rename non-stubs variant of a lib if it is included in APEX

am: b07885714c

Change-Id: I01f9965ce641e561ec8429e037789718c73e951b
This commit is contained in:
Jiyong Park 2019-01-09 19:26:21 -08:00 committed by android-build-merger
commit 8e071293b4
4 changed files with 77 additions and 8 deletions

View file

@ -492,6 +492,19 @@ func getCopyManifestForNativeLibrary(cc *cc.Module) (fileToCopy android.Path, di
if !cc.Arch().Native {
dirInApex = filepath.Join(dirInApex, cc.Arch().ArchType.String())
}
switch cc.Name() {
case "libc", "libm", "libdl":
// Special case for bionic libs. This is to prevent the bionic libs
// from being included in the search path /apex/com.android.apex/lib.
// This exclusion is required because bionic libs in the runtime APEX
// are available via the legacy paths /system/lib/libc.so, etc. By the
// init process, the bionic libs in the APEX are bind-mounted to the
// legacy paths and thus will be loaded into the default linker namespace.
// If the bionic libs are directly in /apex/com.android.apex/lib then
// the same libs will be again loaded to the runtime linker namespace,
// which will result double loading of bionic libs that isn't supported.
dirInApex = filepath.Join(dirInApex, "bionic")
}
fileToCopy = cc.OutputFile().Path()
return

View file

@ -492,6 +492,13 @@ func TestApexWithSystemLibsStubs(t *testing.T) {
versions: ["27", "28", "29"],
},
}
cc_library {
name: "libBootstrap",
srcs: ["mylib.cpp"],
stl: "none",
bootstrap: true,
}
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
@ -499,11 +506,11 @@ func TestApexWithSystemLibsStubs(t *testing.T) {
// Ensure that mylib, libm, libdl are included.
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds, "image.apex/lib64/libm.so")
ensureContains(t, copyCmds, "image.apex/lib64/libdl.so")
ensureContains(t, copyCmds, "image.apex/lib64/bionic/libm.so")
ensureContains(t, copyCmds, "image.apex/lib64/bionic/libdl.so")
// Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
ensureNotContains(t, copyCmds, "image.apex/lib64/libc.so")
ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so")
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_shared_myapex").Rule("ld").Args["libFlags"]
mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_myapex").Rule("cc").Args["cFlags"]
@ -538,6 +545,12 @@ func TestApexWithSystemLibsStubs(t *testing.T) {
// ... Cflags from stub is correctly exported to mylib
ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
// Ensure that libBootstrap is depending on the platform variant of bionic libs
libFlags := ctx.ModuleForTests("libBootstrap", "android_arm64_armv8-a_core_shared").Rule("ld").Args["libFlags"]
ensureContains(t, libFlags, "libc/android_arm64_armv8-a_core_shared/libc.so")
ensureContains(t, libFlags, "libm/android_arm64_armv8-a_core_shared/libm.so")
ensureContains(t, libFlags, "libdl/android_arm64_armv8-a_core_shared/libdl.so")
}
func TestFilesInSubDir(t *testing.T) {

View file

@ -29,9 +29,12 @@ var (
)
type AndroidMkContext interface {
Name() string
Target() android.Target
subAndroidMk(*android.AndroidMkData, interface{})
useVndk() bool
static() bool
inRecovery() bool
}
type subAndroidMkProvider interface {
@ -59,7 +62,11 @@ func (c *Module) AndroidMk() android.AndroidMkData {
ret := android.AndroidMkData{
OutputFile: c.outputFile,
Required: append(c.Properties.AndroidMkRuntimeLibs, c.Properties.ApexesProvidingSharedLibs...),
// TODO(jiyong): add the APEXes providing shared libs to the required modules
// Currently, adding c.Properties.ApexesProvidingSharedLibs is causing multiple
// runtime APEXes (com.android.runtime.debug|release) to be installed. And this
// is breaking some older devices (like marlin) where system.img is small.
Required: c.Properties.AndroidMkRuntimeLibs,
Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
Extra: []android.AndroidMkExtraFunc{
@ -172,13 +179,23 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
}
})
if library.shared() {
if library.shared() && !library.buildStubs() {
ctx.subAndroidMk(ret, library.baseInstaller)
} else {
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
if library.buildStubs() {
fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
}
})
}
if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx.Name()) &&
!ctx.inRecovery() && !ctx.useVndk() && !ctx.static() {
if !library.buildStubs() {
ret.SubName = ".bootstrap"
}
}
}
func (object *objectLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {

View file

@ -201,6 +201,10 @@ type BaseProperties struct {
Recovery_available *bool
InRecovery bool `blueprint:"mutated"`
// Allows this module to use non-APEX version of libraries. Useful
// for building binaries that are started before APEXes are activated.
Bootstrap *bool
}
type VendorProperties struct {
@ -250,6 +254,8 @@ type ModuleContextIntf interface {
isPgoCompile() bool
useClangLld(actx ModuleContext) bool
isApex() bool
hasStubsVariants() bool
isStubs() bool
}
type ModuleContext interface {
@ -676,6 +682,14 @@ func (ctx *moduleContextImpl) isApex() bool {
return ctx.mod.ApexName() != ""
}
func (ctx *moduleContextImpl) hasStubsVariants() bool {
return ctx.mod.HasStubsVariants()
}
func (ctx *moduleContextImpl) isStubs() bool {
return ctx.mod.IsStubs()
}
func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
return &Module{
hod: hod,
@ -855,6 +869,18 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
return
}
c.outputFile = android.OptionalPathForPath(outputFile)
// If a lib is directly included in any of the APEXes, unhide the stubs
// variant having the latest version gets visible to make. In addition,
// the non-stubs variant is renamed to <libname>.bootstrap. This is to
// force anything in the make world to link against the stubs library.
// (unless it is explicitly referenced via .bootstrap suffix or the
// module is marked with 'bootstrap: true').
if c.HasStubsVariants() && android.DirectlyInAnyApex(ctx.baseModuleName()) &&
!c.inRecovery() && !c.useVndk() && !c.static() && c.IsStubs() {
c.Properties.HideFromMake = false // unhide
// Note: this is still non-installable
}
}
if c.installer != nil && !c.Properties.PreventInstall && c.IsForPlatform() && c.outputFile.Valid() {
@ -1446,8 +1472,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// If not building for APEX, use stubs only when it is from
// an APEX (and not from platform)
useThisDep = (depInPlatform != depIsStubs)
if c.inRecovery() {
// However, for recovery modules, since there is no APEX there,
if c.inRecovery() || Bool(c.Properties.Bootstrap) {
// However, for recovery or bootstrap modules,
// always link to non-stub variant
useThisDep = !depIsStubs
}