Create symlink for bionic files

This change creates following symlinks for bionic files.

/system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
/system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
/system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
/system/bin/linker -> /apex/com.android.runtime/bin/linker
...

This allows us to not have mountpoints under /bionic.

Bug: 125549215
Test: m and inspect the symlinks in the system partition.
Change-Id: I3a58bf4f88c967862dbf06065a1af8fc4700dda3
This commit is contained in:
Jiyong Park 2019-02-25 11:05:47 +09:00
parent 33548f07a8
commit f11943527d
6 changed files with 87 additions and 10 deletions

View file

@ -124,6 +124,7 @@ type ModuleContext interface {
InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath
CheckbuildFile(srcPath Path)
AddMissingDependencies(deps []string)
@ -1316,6 +1317,28 @@ func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name strin
return fullInstallPath
}
// installPath/name -> absPath where absPath might be a path that is available only at runtime
// (e.g. /apex/...)
func (a *androidModuleContext) InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath {
fullInstallPath := installPath.Join(a, name)
a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
if !a.skipInstall(fullInstallPath) {
a.Build(pctx, BuildParams{
Rule: Symlink,
Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
Output: fullInstallPath,
Default: !a.Config().EmbeddedInMake(),
Args: map[string]string{
"fromPath": absPath,
},
})
a.installFiles = append(a.installFiles, fullInstallPath)
}
return fullInstallPath
}
func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
}

View file

@ -158,6 +158,9 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
if len(library.Properties.Overrides) > 0 {
fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(library.Properties.Overrides, " "))
}
if len(library.post_install_cmds) > 0 {
fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := "+strings.Join(library.post_install_cmds, "&& "))
}
})
} else if library.header() {
ret.Class = "HEADER_LIBRARIES"
@ -231,6 +234,9 @@ func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.Andr
if len(binary.Properties.Overrides) > 0 {
fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(binary.Properties.Overrides, " "))
}
if len(binary.post_install_cmds) > 0 {
fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := "+strings.Join(binary.post_install_cmds, "&& "))
}
})
}

View file

@ -15,6 +15,8 @@
package cc
import (
"path/filepath"
"github.com/google/blueprint"
"android/soong/android"
@ -91,6 +93,8 @@ type binaryDecorator struct {
// Location of the file that should be copied to dist dir when requested
distFile android.OptionalPath
post_install_cmds []string
}
var _ linker = (*binaryDecorator)(nil)
@ -249,7 +253,7 @@ func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags
} else {
switch ctx.Os() {
case android.Android:
if ctx.bootstrap() {
if ctx.bootstrap() && !ctx.inRecovery() {
flags.DynamicLinker = "/system/bin/bootstrap/linker"
} else {
flags.DynamicLinker = "/system/bin/linker"
@ -413,7 +417,29 @@ func (binary *binaryDecorator) symlinkList() []string {
return binary.symlinks
}
// /system/bin/linker -> /apex/com.android.runtime/bin/linker
func (binary *binaryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) {
dir := binary.baseInstaller.installDir(ctx)
dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir)
target := "/" + filepath.Join("apex", "com.android.runtime", dir.Base(), file.Base())
ctx.InstallAbsoluteSymlink(dir, file.Base(), target)
binary.post_install_cmds = append(binary.post_install_cmds, makeSymlinkCmd(dirOnDevice, file.Base(), target))
for _, symlink := range binary.symlinks {
ctx.InstallAbsoluteSymlink(dir, symlink, target)
binary.post_install_cmds = append(binary.post_install_cmds, makeSymlinkCmd(dirOnDevice, symlink, target))
}
}
func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
// Bionic binaries (e.g. linker) is installed to the bootstrap subdirectory.
// The original path becomes a symlink to the corresponding file in the
// runtime APEX.
if isBionic(ctx.baseModuleName()) && ctx.Arch().Native && ctx.apexName() == "" && !ctx.inRecovery() {
binary.installSymlinkToRuntimeApex(ctx, file)
binary.baseInstaller.subDir = "bootstrap"
}
binary.baseInstaller.install(ctx, file)
for _, symlink := range binary.symlinks {
ctx.InstallSymlink(binary.baseInstaller.installDir(ctx), symlink, binary.baseInstaller.path)

View file

@ -599,6 +599,14 @@ func (c *Module) bootstrap() bool {
return Bool(c.Properties.Bootstrap)
}
func isBionic(name string) bool {
switch name {
case "libc", "libm", "libdl", "linker":
return true
}
return false
}
type baseModuleContext struct {
android.BaseContext
moduleContextImpl

View file

@ -15,6 +15,7 @@
package cc
import (
"path/filepath"
"regexp"
"sort"
"strconv"
@ -290,6 +291,8 @@ type libraryDecorator struct {
versionScriptPath android.ModuleGenPath
post_install_cmds []string
// Decorated interafaces
*baseCompiler
*baseLinker
@ -888,6 +891,14 @@ func (library *libraryDecorator) toc() android.OptionalPath {
return library.tocFile
}
func (library *libraryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) {
dir := library.baseInstaller.installDir(ctx)
dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir)
target := "/" + filepath.Join("apex", "com.android.runtime", dir.Base(), "bionic", file.Base())
ctx.InstallAbsoluteSymlink(dir, file.Base(), target)
library.post_install_cmds = append(library.post_install_cmds, makeSymlinkCmd(dirOnDevice, file.Base(), target))
}
func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
if library.shared() {
if ctx.Device() && ctx.useVndk() {
@ -905,15 +916,11 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
}
}
} else if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
// If a library in an APEX has stable versioned APIs, we basically don't need
// to have the platform variant of the library in /system partition because
// platform components can just use the lib from the APEX without fearing about
// compatibility. However, if the library is required for some early processes
// before the APEX is activated, the platform variant may also be required.
// In that case, it is installed to the subdirectory 'bootstrap' in order to
// be distinguished/isolated from other non-bootstrap libraries in /system/lib
// so that the bootstrap libraries are used only when the APEX isn't ready.
if !library.buildStubs() && ctx.Arch().Native {
// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
// The original path becomes a symlink to the corresponding file in the
// runtime APEX.
if isBionic(ctx.baseModuleName()) && !library.buildStubs() && ctx.Arch().Native && !ctx.inRecovery() {
library.installSymlinkToRuntimeApex(ctx, file)
library.baseInstaller.subDir = "bootstrap"
}
}

View file

@ -133,3 +133,10 @@ func splitFileExt(name string) (string, string, string) {
return root, suffix, ext
}
// linkDirOnDevice/linkName -> target
func makeSymlinkCmd(linkDirOnDevice string, linkName string, target string) string {
dir := filepath.Join("$(PRODUCT_OUT)", linkDirOnDevice)
return "mkdir -p " + dir + " && " +
"ln -sf " + target + " " + filepath.Join(dir, linkName)
}