Add support for symlink_preferred_arch in apex
Some modules rely on symlink_preferred_arch to have expected files present. This change makes apexs include these symlinks. Test: m com.android.runtime.debug pushd $(mktemp -d) mkdir mnt unzip $OUT/apex/system/com.android.runtime.debug.apex sudo mount -o loop,ro apex_payload.img mnt Ensure that mnt/bin/dalvikvm and mnt/bin/dex2oatd both exist and are symlinks to mnt/bin/dalvikvm64 and mnt/bin/dex2oatd32 respectively. Bug: 119942078 Bug: 122373634 Bug: 123079311 Change-Id: I47868fbedc5bdd3141a836c488f79e91e0a6ddfe
This commit is contained in:
parent
62f6fcbbb9
commit
3d67359f2f
23
apex/apex.go
23
apex/apex.go
|
@ -333,6 +333,7 @@ type apexFile struct {
|
||||||
installDir string
|
installDir string
|
||||||
class apexFileClass
|
class apexFileClass
|
||||||
module android.Module
|
module android.Module
|
||||||
|
symlinks []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type apexBundle struct {
|
type apexBundle struct {
|
||||||
|
@ -396,7 +397,8 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
a.properties.Multilib.Both.Binaries, target.String(),
|
a.properties.Multilib.Both.Binaries, target.String(),
|
||||||
a.getImageVariation(config))
|
a.getImageVariation(config))
|
||||||
|
|
||||||
if i == 0 {
|
isPrimaryAbi := i == 0
|
||||||
|
if isPrimaryAbi {
|
||||||
// When multilib.* is omitted for binaries, it implies
|
// When multilib.* is omitted for binaries, it implies
|
||||||
// multilib.first.
|
// multilib.first.
|
||||||
ctx.AddFarVariationDependencies([]blueprint.Variation{
|
ctx.AddFarVariationDependencies([]blueprint.Variation{
|
||||||
|
@ -571,7 +573,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
case sharedLibTag:
|
case sharedLibTag:
|
||||||
if cc, ok := child.(*cc.Module); ok {
|
if cc, ok := child.(*cc.Module); ok {
|
||||||
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
|
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
|
||||||
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeSharedLib, cc})
|
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeSharedLib, cc, nil})
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName)
|
ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName)
|
||||||
|
@ -584,7 +586,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
|
fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
|
||||||
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeExecutable, cc})
|
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeExecutable, cc, cc.Symlinks()})
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
ctx.PropertyErrorf("binaries", "%q is not a cc_binary module", depName)
|
ctx.PropertyErrorf("binaries", "%q is not a cc_binary module", depName)
|
||||||
|
@ -595,7 +597,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
if fileToCopy == nil {
|
if fileToCopy == nil {
|
||||||
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
|
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
|
||||||
} else {
|
} else {
|
||||||
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, java.Arch().ArchType, dirInApex, javaSharedLib, java})
|
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, java.Arch().ArchType, dirInApex, javaSharedLib, java, nil})
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
|
@ -604,7 +606,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
case prebuiltTag:
|
case prebuiltTag:
|
||||||
if prebuilt, ok := child.(*android.PrebuiltEtc); ok {
|
if prebuilt, ok := child.(*android.PrebuiltEtc); ok {
|
||||||
fileToCopy, dirInApex := getCopyManifestForPrebuiltEtc(prebuilt)
|
fileToCopy, dirInApex := getCopyManifestForPrebuiltEtc(prebuilt)
|
||||||
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, prebuilt.Arch().ArchType, dirInApex, etc, prebuilt})
|
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, prebuilt.Arch().ArchType, dirInApex, etc, prebuilt, nil})
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
|
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
|
||||||
|
@ -639,7 +641,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
}
|
}
|
||||||
depName := ctx.OtherModuleName(child)
|
depName := ctx.OtherModuleName(child)
|
||||||
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
|
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
|
||||||
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeSharedLib, cc})
|
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeSharedLib, cc, nil})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -732,6 +734,10 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, keyFile and
|
||||||
dest_path := filepath.Join(android.PathForModuleOut(ctx, "image"+suffix).String(), dest)
|
dest_path := filepath.Join(android.PathForModuleOut(ctx, "image"+suffix).String(), dest)
|
||||||
copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(dest_path))
|
copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(dest_path))
|
||||||
copyCommands = append(copyCommands, "cp "+src.String()+" "+dest_path)
|
copyCommands = append(copyCommands, "cp "+src.String()+" "+dest_path)
|
||||||
|
for _, sym := range a.filesInfo[i].symlinks {
|
||||||
|
symlinkDest := filepath.Join(filepath.Dir(dest_path), sym)
|
||||||
|
copyCommands = append(copyCommands, "ln -s "+filepath.Base(dest)+" "+symlinkDest)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
implicitInputs := append(android.Paths(nil), filesToCopy...)
|
implicitInputs := append(android.Paths(nil), filesToCopy...)
|
||||||
implicitInputs = append(implicitInputs, manifest)
|
implicitInputs = append(implicitInputs, manifest)
|
||||||
|
@ -747,6 +753,9 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, keyFile and
|
||||||
pathInApex := filepath.Join(f.installDir, f.builtFile.Base())
|
pathInApex := filepath.Join(f.installDir, f.builtFile.Base())
|
||||||
if f.installDir == "bin" {
|
if f.installDir == "bin" {
|
||||||
executablePaths = append(executablePaths, pathInApex)
|
executablePaths = append(executablePaths, pathInApex)
|
||||||
|
for _, s := range f.symlinks {
|
||||||
|
executablePaths = append(executablePaths, filepath.Join("bin", s))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
readOnlyPaths = append(readOnlyPaths, pathInApex)
|
readOnlyPaths = append(readOnlyPaths, pathInApex)
|
||||||
}
|
}
|
||||||
|
@ -879,7 +888,7 @@ func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {
|
||||||
Input: manifest,
|
Input: manifest,
|
||||||
Output: copiedManifest,
|
Output: copiedManifest,
|
||||||
})
|
})
|
||||||
a.filesInfo = append(a.filesInfo, apexFile{copiedManifest, ctx.ModuleName() + ".apex_manifest.json", android.Common, ".", etc, nil})
|
a.filesInfo = append(a.filesInfo, apexFile{copiedManifest, ctx.ModuleName() + ".apex_manifest.json", android.Common, ".", etc, nil, nil})
|
||||||
|
|
||||||
for _, fi := range a.filesInfo {
|
for _, fi := range a.filesInfo {
|
||||||
dir := filepath.Join("apex", ctx.ModuleName(), fi.installDir)
|
dir := filepath.Join("apex", ctx.ModuleName(), fi.installDir)
|
||||||
|
|
|
@ -107,6 +107,16 @@ func testApex(t *testing.T, bp string) *android.TestContext {
|
||||||
recovery_available: true,
|
recovery_available: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_object {
|
||||||
|
name: "crtbegin_static",
|
||||||
|
stl: "none",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_object {
|
||||||
|
name: "crtend_android",
|
||||||
|
stl: "none",
|
||||||
|
}
|
||||||
|
|
||||||
llndk_library {
|
llndk_library {
|
||||||
name: "libc",
|
name: "libc",
|
||||||
symbol_file: "",
|
symbol_file: "",
|
||||||
|
@ -194,6 +204,11 @@ func TestBasicApex(t *testing.T) {
|
||||||
name: "myapex",
|
name: "myapex",
|
||||||
key: "myapex.key",
|
key: "myapex.key",
|
||||||
native_shared_libs: ["mylib"],
|
native_shared_libs: ["mylib"],
|
||||||
|
multilib: {
|
||||||
|
both: {
|
||||||
|
binaries: ["foo",],
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apex_key {
|
apex_key {
|
||||||
|
@ -210,6 +225,25 @@ func TestBasicApex(t *testing.T) {
|
||||||
stl: "none",
|
stl: "none",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "foo",
|
||||||
|
srcs: ["mylib.cpp"],
|
||||||
|
compile_multilib: "both",
|
||||||
|
multilib: {
|
||||||
|
lib32: {
|
||||||
|
suffix: "32",
|
||||||
|
},
|
||||||
|
lib64: {
|
||||||
|
suffix: "64",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
symlinks: ["foo_link_"],
|
||||||
|
symlink_preferred_arch: true,
|
||||||
|
system_shared_libs: [],
|
||||||
|
static_executable: true,
|
||||||
|
stl: "none",
|
||||||
|
}
|
||||||
|
|
||||||
cc_library {
|
cc_library {
|
||||||
name: "mylib2",
|
name: "mylib2",
|
||||||
srcs: ["mylib.cpp"],
|
srcs: ["mylib.cpp"],
|
||||||
|
@ -237,6 +271,23 @@ func TestBasicApex(t *testing.T) {
|
||||||
// Ensure that the platform variant ends with _core_shared
|
// Ensure that the platform variant ends with _core_shared
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared")
|
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared")
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared")
|
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared")
|
||||||
|
|
||||||
|
// Ensure that all symlinks are present.
|
||||||
|
found_foo_link_64 := false
|
||||||
|
found_foo := false
|
||||||
|
for _, cmd := range strings.Split(copyCmds, " && ") {
|
||||||
|
if strings.HasPrefix(cmd, "ln -s foo64") {
|
||||||
|
if strings.HasSuffix(cmd, "bin/foo") {
|
||||||
|
found_foo = true
|
||||||
|
} else if strings.HasSuffix(cmd, "bin/foo_link_64") {
|
||||||
|
found_foo_link_64 = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
good := found_foo && found_foo_link_64
|
||||||
|
if !good {
|
||||||
|
t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasicZipApex(t *testing.T) {
|
func TestBasicZipApex(t *testing.T) {
|
||||||
|
@ -671,17 +722,6 @@ func TestStaticLinking(t *testing.T) {
|
||||||
system_shared_libs: [],
|
system_shared_libs: [],
|
||||||
stl: "none",
|
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"]
|
ldFlags := ctx.ModuleForTests("not_in_apex", "android_arm64_armv8-a_core").Rule("ld").Args["libFlags"]
|
||||||
|
|
16
cc/binary.go
16
cc/binary.go
|
@ -382,11 +382,8 @@ func (binary *binaryDecorator) link(ctx ModuleContext,
|
||||||
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
|
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
|
||||||
binary.coverageOutputFile = TransformCoverageFilesToLib(ctx, objs, builderFlags, binary.getStem(ctx))
|
binary.coverageOutputFile = TransformCoverageFilesToLib(ctx, objs, builderFlags, binary.getStem(ctx))
|
||||||
|
|
||||||
return ret
|
// Need to determine symlinks early since some targets (ie APEX) need this
|
||||||
}
|
// information but will not call 'install'
|
||||||
|
|
||||||
func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
|
|
||||||
binary.baseInstaller.install(ctx, file)
|
|
||||||
for _, symlink := range binary.Properties.Symlinks {
|
for _, symlink := range binary.Properties.Symlinks {
|
||||||
binary.symlinks = append(binary.symlinks,
|
binary.symlinks = append(binary.symlinks,
|
||||||
symlink+String(binary.Properties.Suffix)+ctx.toolchain().ExecutableSuffix())
|
symlink+String(binary.Properties.Suffix)+ctx.toolchain().ExecutableSuffix())
|
||||||
|
@ -401,6 +398,15 @@ func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (binary *binaryDecorator) symlinkList() []string {
|
||||||
|
return binary.symlinks
|
||||||
|
}
|
||||||
|
|
||||||
|
func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
|
||||||
|
binary.baseInstaller.install(ctx, file)
|
||||||
for _, symlink := range binary.symlinks {
|
for _, symlink := range binary.symlinks {
|
||||||
ctx.InstallSymlink(binary.baseInstaller.installDir(ctx), symlink, binary.baseInstaller.path)
|
ctx.InstallSymlink(binary.baseInstaller.installDir(ctx), symlink, binary.baseInstaller.path)
|
||||||
}
|
}
|
||||||
|
|
9
cc/cc.go
9
cc/cc.go
|
@ -772,6 +772,15 @@ func (c *Module) Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Module) Symlinks() []string {
|
||||||
|
if p, ok := c.installer.(interface {
|
||||||
|
symlinkList() []string
|
||||||
|
}); ok {
|
||||||
|
return p.symlinkList()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// orderDeps reorders dependencies into a list such that if module A depends on B, then
|
// orderDeps reorders dependencies into a list such that if module A depends on B, then
|
||||||
// A will precede B in the resultant list.
|
// A will precede B in the resultant list.
|
||||||
// This is convenient for passing into a linker.
|
// This is convenient for passing into a linker.
|
||||||
|
|
Loading…
Reference in New Issue