Merge Coral/Flame into AOSP master
Bug: 141248619
Change-Id: Ie21f494b6c52952165babdcb26d4038f93ff0c0d
Merged-In: I2dbd6791675ed91303dc21d04992e600bb89f0ff
diff --git a/Android.bp b/Android.bp
index 20d45e5..714ce37 100644
--- a/Android.bp
+++ b/Android.bp
@@ -580,104 +580,21 @@
arch: {
arm: {
src: "prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a",
- strip: {
- keep_symbols_list: [
- // unwind-arm.o
- "_Unwind_Complete",
- "_Unwind_DeleteException",
- "_Unwind_GetCFA",
- "_Unwind_VRS_Get",
- "_Unwind_VRS_Pop",
- "_Unwind_VRS_Set",
- "__aeabi_unwind_cpp_pr0",
- "__aeabi_unwind_cpp_pr1",
- "__aeabi_unwind_cpp_pr2",
- "__gnu_Unwind_Backtrace",
- "__gnu_Unwind_ForcedUnwind",
- "__gnu_Unwind_RaiseException",
- "__gnu_Unwind_Resume",
- "__gnu_Unwind_Resume_or_Rethrow",
-
- // libunwind.o
- "_Unwind_Backtrace",
- "_Unwind_ForcedUnwind",
- "_Unwind_RaiseException",
- "_Unwind_Resume",
- "_Unwind_Resume_or_Rethrow",
- "___Unwind_Backtrace",
- "___Unwind_ForcedUnwind",
- "___Unwind_RaiseException",
- "___Unwind_Resume",
- "___Unwind_Resume_or_Rethrow",
- "__gnu_Unwind_Restore_VFP",
- "__gnu_Unwind_Restore_VFP_D",
- "__gnu_Unwind_Restore_VFP_D_16_to_31",
- "__gnu_Unwind_Restore_WMMXC",
- "__gnu_Unwind_Restore_WMMXD",
- "__gnu_Unwind_Save_VFP",
- "__gnu_Unwind_Save_VFP_D",
- "__gnu_Unwind_Save_VFP_D_16_to_31",
- "__gnu_Unwind_Save_WMMXC",
- "__gnu_Unwind_Save_WMMXD",
- "__restore_core_regs",
- "restore_core_regs",
-
- // pr-support.o
- "_Unwind_GetDataRelBase",
- "_Unwind_GetLanguageSpecificData",
- "_Unwind_GetRegionStart",
- "_Unwind_GetTextRelBase",
- "__gnu_unwind_execute",
- "__gnu_unwind_frame",
- ],
- },
+ repack_objects_to_keep: ["unwind-arm.o", "libunwind.o", "pr-support.o"],
},
arm64: {
src: "prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a",
+ repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"],
},
x86: {
src: "prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/lib/gcc/x86_64-linux-android/4.9.x/32/libgcc.a",
-
+ repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"],
},
x86_64: {
src: "prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/lib/gcc/x86_64-linux-android/4.9.x/libgcc.a",
+ repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"],
},
},
- strip: {
- keep_symbols_list: [
- // unwind-dw2.o
- "_Unwind_Backtrace",
- "_Unwind_DeleteException",
- "_Unwind_FindEnclosingFunction",
- "_Unwind_ForcedUnwind",
- "_Unwind_GetCFA",
- "_Unwind_GetDataRelBase",
- "_Unwind_GetGR",
- "_Unwind_GetIP",
- "_Unwind_GetIPInfo",
- "_Unwind_GetLanguageSpecificData",
- "_Unwind_GetRegionStart",
- "_Unwind_GetTextRelBase",
- "_Unwind_RaiseException",
- "_Unwind_Resume",
- "_Unwind_Resume_or_Rethrow",
- "_Unwind_SetGR",
- "_Unwind_SetIP",
- "__frame_state_for",
-
- // unwind-dw2-fde-dip.o
- "_Unwind_Find_FDE",
- "__deregister_frame",
- "__deregister_frame_info",
- "__deregister_frame_info_bases",
- "__register_frame",
- "__register_frame_info",
- "__register_frame_info_bases",
- "__register_frame_info_table",
- "__register_frame_info_table_bases",
- "__register_frame_table",
- ],
- },
}
toolchain_library {
diff --git a/apex/apex.go b/apex/apex.go
index c9b989a..629cbbf 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -126,11 +126,15 @@
}, "image_content_file", "whitelisted_files_file", "apex_module_name")
)
-var imageApexSuffix = ".apex"
-var zipApexSuffix = ".zipapex"
+const (
+ imageApexSuffix = ".apex"
+ zipApexSuffix = ".zipapex"
-var imageApexType = "image"
-var zipApexType = "zip"
+ imageApexType = "image"
+ zipApexType = "zip"
+
+ vndkApexNamePrefix = "com.android.vndk.v"
+)
type dependencyTag struct {
blueprint.BaseDependencyTag
@@ -182,10 +186,7 @@
android.RegisterModuleType("apex_defaults", defaultsFactory)
android.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
- android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator).Parallel()
- ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator).Parallel()
- })
+ android.PreDepsMutators(RegisterPreDepsMutators)
android.PostDepsMutators(RegisterPostDepsMutators)
android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
@@ -195,6 +196,11 @@
})
}
+func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
+ ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
+}
+
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
ctx.TopDown("apex_deps", apexDepsMutator)
ctx.BottomUp("apex", apexMutator).Parallel()
@@ -207,44 +213,39 @@
vndkApexListMutex sync.Mutex
)
-func vndkApexList(config android.Config) map[string]*apexBundle {
+func vndkApexList(config android.Config) map[string]string {
return config.Once(vndkApexListKey, func() interface{} {
- return map[string]*apexBundle{}
- }).(map[string]*apexBundle)
+ return map[string]string{}
+ }).(map[string]string)
}
-// apexVndkGatherMutator gathers "apex_vndk" modules and puts them in a map with vndk_version as a key.
-func apexVndkGatherMutator(mctx android.TopDownMutatorContext) {
+func apexVndkMutator(mctx android.TopDownMutatorContext) {
if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex {
if ab.IsNativeBridgeSupported() {
mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
}
- vndkVersion := proptools.String(ab.vndkProperties.Vndk_version)
+ vndkVersion := ab.vndkVersion(mctx.DeviceConfig())
+ // Ensure VNDK APEX mount point is formatted as com.android.vndk.v###
+ ab.properties.Apex_name = proptools.StringPtr(vndkApexNamePrefix + vndkVersion)
+ // vndk_version should be unique
vndkApexListMutex.Lock()
defer vndkApexListMutex.Unlock()
vndkApexList := vndkApexList(mctx.Config())
if other, ok := vndkApexList[vndkVersion]; ok {
- mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.BaseModuleName())
+ mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other)
}
- vndkApexList[vndkVersion] = ab
+ vndkApexList[vndkVersion] = mctx.ModuleName()
}
}
-// apexVndkAddDepsMutator adds (reverse) dependencies from vndk libs to apex_vndk modules.
-// It filters only libs with matching targets.
-func apexVndkAddDepsMutator(mctx android.BottomUpMutatorContext) {
- if cc, ok := mctx.Module().(*cc.Module); ok && cc.IsVndkOnSystem() {
+func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
+ if m, ok := mctx.Module().(*cc.Module); ok && cc.IsForVndkApex(mctx, m) {
+ vndkVersion := m.VndkVersion()
vndkApexList := vndkApexList(mctx.Config())
- if ab, ok := vndkApexList[cc.VndkVersion()]; ok {
- targetArch := cc.Target().String()
- for _, target := range ab.MultiTargets() {
- if target.String() == targetArch {
- mctx.AddReverseDependency(mctx.Module(), sharedLibTag, ab.Name())
- break
- }
- }
+ if vndkApex, ok := vndkApexList[vndkVersion]; ok {
+ mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApex)
}
}
}
@@ -615,6 +616,12 @@
// intermediate path for apex_manifest.json
manifestOut android.WritablePath
+
+ // list of commands to create symlinks for backward compatibility
+ // these commands will be attached as LOCAL_POST_INSTALL_CMD to
+ // apex package itself(for unflattened build) or apex_manifest.json(for flattened build)
+ // so that compat symlinks are always installed regardless of TARGET_FLATTEN_APEX setting.
+ compatSymlinks []string
}
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -654,7 +661,6 @@
}
func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
-
targets := ctx.MultiTargets()
config := ctx.DeviceConfig()
@@ -824,6 +830,9 @@
}
func (a *apexBundle) getImageVariation(config android.DeviceConfig) string {
+ if a.vndkApex {
+ return "vendor." + a.vndkVersion(config)
+ }
if config.VndkVersion() != "" && proptools.Bool(a.properties.Use_vendor) {
return "vendor." + config.PlatformVndkVersion()
} else {
@@ -1244,7 +1253,7 @@
// prepend the name of this APEX to the module names. These names will be the names of
// modules that will be defined if the APEX is flattened.
for i := range filesInfo {
- filesInfo[i].moduleName = ctx.ModuleName() + "." + filesInfo[i].moduleName
+ filesInfo[i].moduleName = filesInfo[i].moduleName + "." + ctx.ModuleName()
}
a.installDir = android.PathForModuleInstall(ctx, "apex")
@@ -1295,6 +1304,8 @@
a.buildUnflattenedApex(ctx, imageApex)
a.buildFlattenedApex(ctx)
}
+
+ a.compatSymlinks = makeCompatSymlinks(apexName, ctx)
}
func (a *apexBundle) buildNoticeFile(ctx android.ModuleContext, apexFileName string) android.OptionalPath {
@@ -1570,7 +1581,7 @@
if a.installable() {
// For flattened APEX, do nothing but make sure that apex_manifest.json and apex_pubkey are also copied along
// with other ordinary files.
- a.filesInfo = append(a.filesInfo, apexFile{a.manifestOut, ctx.ModuleName() + ".apex_manifest.json", ".", etc, nil, nil})
+ a.filesInfo = append(a.filesInfo, apexFile{a.manifestOut, "apex_manifest.json." + ctx.ModuleName(), ".", etc, nil, nil})
// rename to apex_pubkey
copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
@@ -1579,7 +1590,7 @@
Input: a.public_key_file,
Output: copiedPubkey,
})
- a.filesInfo = append(a.filesInfo, apexFile{copiedPubkey, ctx.ModuleName() + ".apex_pubkey", ".", etc, nil, nil})
+ a.filesInfo = append(a.filesInfo, apexFile{copiedPubkey, "apex_pubkey." + ctx.ModuleName(), ".", etc, nil, nil})
if ctx.Config().FlattenApex() {
apexName := proptools.StringDefault(a.properties.Apex_name, ctx.ModuleName())
@@ -1712,6 +1723,10 @@
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
} else {
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
+ // For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex
+ if !a.isFlattenedVariant() && fi.builtFile.Base() == "apex_manifest.json" && len(a.compatSymlinks) > 0 {
+ fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && "))
+ }
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
}
}
@@ -1762,10 +1777,16 @@
if len(a.externalDeps) > 0 {
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.externalDeps, " "))
}
+ var postInstallCommands []string
if a.prebuiltFileToDelete != "" {
- fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", "rm -rf "+
+ postInstallCommands = append(postInstallCommands, "rm -rf "+
filepath.Join(a.installDir.ToMakePath().String(), a.prebuiltFileToDelete))
}
+ // For unflattened apexes, compat symlinks are attached to apex package itself as LOCAL_POST_INSTALL_CMD
+ postInstallCommands = append(postInstallCommands, a.compatSymlinks...)
+ if len(postInstallCommands) > 0 {
+ fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(postInstallCommands, " && "))
+ }
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
if apexType == imageApex {
@@ -1819,19 +1840,18 @@
}{
proptools.StringPtr("both"),
})
-
- vndkVersion := proptools.StringDefault(bundle.vndkProperties.Vndk_version, "current")
- if vndkVersion == "current" {
- vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
- bundle.vndkProperties.Vndk_version = proptools.StringPtr(vndkVersion)
- }
-
- // Ensure VNDK APEX mount point is formatted as com.android.vndk.v###
- bundle.properties.Apex_name = proptools.StringPtr("com.android.vndk.v" + vndkVersion)
})
return bundle
}
+func (a *apexBundle) vndkVersion(config android.DeviceConfig) string {
+ vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
+ if vndkVersion == "current" {
+ vndkVersion = config.PlatformVndkVersion()
+ }
+ return vndkVersion
+}
+
//
// Defaults
//
@@ -1997,6 +2017,8 @@
if p.installable() {
ctx.InstallFile(p.installDir, p.installFilename, p.inputApex)
}
+
+ // TODO(b/143192278): Add compat symlinks for prebuilt_apex
}
func (p *Prebuilt) Prebuilt() *android.Prebuilt {
@@ -2031,3 +2053,30 @@
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
return module
}
+
+func makeCompatSymlinks(apexName string, ctx android.ModuleContext) (symlinks []string) {
+ // small helper to add symlink commands
+ addSymlink := func(target, dir, linkName string) {
+ outDir := filepath.Join("$(PRODUCT_OUT)", dir)
+ link := filepath.Join(outDir, linkName)
+ symlinks = append(symlinks, "mkdir -p "+outDir+" && rm -rf "+link+" && ln -sf "+target+" "+link)
+ }
+
+ // TODO(b/142911355): [VNDK APEX] Fix hard-coded references to /system/lib/vndk
+ // When all hard-coded references are fixed, remove symbolic links
+ // Note that we should keep following symlinks for older VNDKs (<=29)
+ // Since prebuilt vndk libs still depend on system/lib/vndk path
+ if strings.HasPrefix(apexName, vndkApexNamePrefix) {
+ // the name of vndk apex is formatted "com.android.vndk.v" + version
+ vndkVersion := strings.TrimPrefix(apexName, vndkApexNamePrefix)
+ if ctx.Config().Android64() {
+ addSymlink("/apex/"+apexName+"/lib64", "/system/lib64", "vndk-sp-"+vndkVersion)
+ addSymlink("/apex/"+apexName+"/lib64", "/system/lib64", "vndk-"+vndkVersion)
+ }
+ if !ctx.Config().Android64() || ctx.DeviceConfig().DeviceSecondaryArch() != "" {
+ addSymlink("/apex/"+apexName+"/lib", "/system/lib", "vndk-sp-"+vndkVersion)
+ addSymlink("/apex/"+apexName+"/lib", "/system/lib", "vndk-"+vndkVersion)
+ }
+ }
+ return
+}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 7a51bb6..cf38caa 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -18,6 +18,7 @@
"io/ioutil"
"os"
"reflect"
+ "sort"
"strings"
"testing"
@@ -85,6 +86,10 @@
}
}
+func withBinder32bit(fs map[string][]byte, config android.Config) {
+ config.TestProductVariables.Binder32bit = proptools.BoolPtr(true)
+}
+
func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
config := android.TestArchConfig(buildDir, nil)
config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
@@ -132,13 +137,10 @@
ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
ctx.BottomUp("version", cc.VersionMutator).Parallel()
ctx.BottomUp("begin", cc.BeginMutator).Parallel()
- ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator)
- ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator)
})
+ ctx.PreDepsMutators(RegisterPreDepsMutators)
+ ctx.PostDepsMutators(RegisterPostDepsMutators)
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("apex_deps", apexDepsMutator)
- ctx.BottomUp("apex", apexMutator)
- ctx.BottomUp("apex_uses", apexUsesMutator)
ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
})
@@ -1207,16 +1209,22 @@
mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
// APEX variant has __ANDROID_APEX__=<apexname> defined
mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_myapex").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex")
+ ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
// APEX variant has __ANDROID_APEX__=<apexname> defined
mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_otherapex").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex")
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+ ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
}
func TestHeaderLibsDependency(t *testing.T) {
@@ -1267,6 +1275,74 @@
ensureContains(t, cFlags, "-Imy_include")
}
+func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName string, files []string) {
+ t.Helper()
+ apexRule := ctx.ModuleForTests(moduleName, "android_common_"+moduleName).Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+ imageApexDir := "/image.apex/"
+ dstFiles := []string{}
+ for _, cmd := range strings.Split(copyCmds, "&&") {
+ cmd = strings.TrimSpace(cmd)
+ if cmd == "" {
+ continue
+ }
+ terms := strings.Split(cmd, " ")
+ switch terms[0] {
+ case "mkdir":
+ case "cp":
+ if len(terms) != 3 {
+ t.Fatal("copyCmds contains invalid cp command", cmd)
+ }
+ dst := terms[2]
+ index := strings.Index(dst, imageApexDir)
+ if index == -1 {
+ t.Fatal("copyCmds should copy a file to image.apex/", cmd)
+ }
+ dstFile := dst[index+len(imageApexDir):]
+ dstFiles = append(dstFiles, dstFile)
+ default:
+ t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd)
+ }
+ }
+ sort.Strings(dstFiles)
+ sort.Strings(files)
+ missing := []string{}
+ surplus := []string{}
+ i := 0
+ j := 0
+ for i < len(dstFiles) && j < len(files) {
+ if dstFiles[i] == files[j] {
+ i++
+ j++
+ } else if dstFiles[i] < files[j] {
+ surplus = append(surplus, dstFiles[i])
+ i++
+ } else {
+ missing = append(missing, files[j])
+ j++
+ }
+ }
+ if i < len(dstFiles) {
+ surplus = append(surplus, dstFiles[i:]...)
+ }
+ if j < len(files) {
+ missing = append(missing, files[j:]...)
+ }
+
+ failed := false
+ if len(surplus) > 0 {
+ t.Log("surplus files", surplus)
+ failed = true
+ }
+ if len(missing) > 0 {
+ t.Log("missing files", missing)
+ failed = true
+ }
+ if failed {
+ t.Fail()
+ }
+}
+
func TestVndkApexCurrent(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
@@ -1305,12 +1381,12 @@
}
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
- ensureContains(t, copyCmds, "image.apex/lib/libvndksp.so")
- ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
- ensureContains(t, copyCmds, "image.apex/lib64/libvndksp.so")
+ ensureExactContents(t, ctx, "myapex", []string{
+ "lib/libvndk.so",
+ "lib/libvndksp.so",
+ "lib64/libvndk.so",
+ "lib64/libvndksp.so",
+ })
}
func TestVndkApexWithPrebuilt(t *testing.T) {
@@ -1328,8 +1404,8 @@
}
cc_prebuilt_library_shared {
- name: "libvndkshared",
- srcs: ["libvndkshared.so"],
+ name: "libvndk",
+ srcs: ["libvndk.so"],
vendor_available: true,
vndk: {
enabled: true,
@@ -1337,13 +1413,33 @@
system_shared_libs: [],
stl: "none",
}
+
+ cc_prebuilt_library_shared {
+ name: "libvndk.arm",
+ srcs: ["libvndk.arm.so"],
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ enabled: false,
+ arch: {
+ arm: {
+ enabled: true,
+ },
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
`, withFiles(map[string][]byte{
- "libvndkshared.so": nil,
+ "libvndk.so": nil,
+ "libvndk.arm.so": nil,
}))
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/lib/libvndkshared.so")
+ ensureExactContents(t, ctx, "myapex", []string{
+ "lib/libvndk.so",
+ "lib/libvndk.arm.so",
+ "lib64/libvndk.so",
+ })
}
func TestVndkApexVersion(t *testing.T) {
@@ -1361,15 +1457,22 @@
private_key: "testkey.pem",
}
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
+ vndk_prebuilt_shared {
+ name: "libvndk27",
+ version: "27",
vendor_available: true,
vndk: {
enabled: true,
},
- system_shared_libs: [],
- stl: "none",
+ target_arch: "arm64",
+ arch: {
+ arm: {
+ srcs: ["libvndk27_arm.so"],
+ },
+ arm64: {
+ srcs: ["libvndk27_arm64.so"],
+ },
+ },
}
vndk_prebuilt_shared {
@@ -1379,18 +1482,27 @@
vndk: {
enabled: true,
},
- target_arch: "arm64",
- srcs: ["libvndk27.so"],
- }
+ target_arch: "x86_64",
+ arch: {
+ x86: {
+ srcs: ["libvndk27_x86.so"],
+ },
+ x86_64: {
+ srcs: ["libvndk27_x86_64.so"],
+ },
+ },
+ }
`, withFiles(map[string][]byte{
- "libvndk27.so": nil,
+ "libvndk27_arm.so": nil,
+ "libvndk27_arm64.so": nil,
+ "libvndk27_x86.so": nil,
+ "libvndk27_x86_64.so": nil,
}))
- apexRule := ctx.ModuleForTests("myapex_v27", "android_common_myapex_v27").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/lib/libvndk27.so")
- ensureContains(t, copyCmds, "image.apex/lib64/libvndk27.so")
- ensureNotContains(t, copyCmds, "image.apex/lib/libvndk.so")
+ ensureExactContents(t, ctx, "myapex_v27", []string{
+ "lib/libvndk27_arm.so",
+ "lib64/libvndk27_arm64.so",
+ })
}
func TestVndkApexErrorWithDuplicateVersion(t *testing.T) {
@@ -1505,14 +1617,10 @@
},
}))
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
- ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
-
- // apex
- ensureNotContains(t, copyCmds, "image.apex/lib/x86/libvndk.so")
- ensureNotContains(t, copyCmds, "image.apex/lib64/x86_64/libvndk.so")
+ ensureExactContents(t, ctx, "myapex", []string{
+ "lib/libvndk.so",
+ "lib64/libvndk.so",
+ })
}
func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
@@ -1545,6 +1653,70 @@
`)
}
+func TestVndkApexWithBinder32(t *testing.T) {
+ ctx, _ := testApex(t,
+ `
+ apex_vndk {
+ name: "myapex_v27",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ vndk_version: "27",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ vndk_prebuilt_shared {
+ name: "libvndk27",
+ version: "27",
+ target_arch: "arm",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ arch: {
+ arm: {
+ srcs: ["libvndk27.so"],
+ }
+ },
+ }
+
+ vndk_prebuilt_shared {
+ name: "libvndk27",
+ version: "27",
+ target_arch: "arm",
+ binder32bit: true,
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ arch: {
+ arm: {
+ srcs: ["libvndk27binder32.so"],
+ }
+ },
+ }
+ `,
+ withFiles(map[string][]byte{
+ "libvndk27.so": nil,
+ "libvndk27binder32.so": nil,
+ }),
+ withBinder32bit,
+ withTargets(map[android.OsType][]android.Target{
+ android.Android: []android.Target{
+ {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
+ },
+ }),
+ )
+
+ ensureExactContents(t, ctx, "myapex_v27", []string{
+ "lib/libvndk27binder32.so",
+ })
+}
+
func TestDependenciesInApexManifest(t *testing.T) {
ctx, _ := testApex(t, `
apex {
@@ -2055,12 +2227,12 @@
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest1\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest2\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest3\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := myapex.apex_manifest.json\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := myapex.apex_pubkey\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := mytest.myapex\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := mytest1.myapex\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := mytest2.myapex\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := mytest3.myapex\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.json.myapex\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := apex_pubkey.myapex\n")
ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n")
}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 9a98b0e..9e26fc5 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -93,6 +93,11 @@
fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
if c.isVndk() && !c.static() {
fmt.Fprintln(w, "LOCAL_SOONG_VNDK_VERSION := "+c.vndkVersion())
+ // VNDK libraries available to vendor are not installed because
+ // they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go)
+ if !c.isVndkExt() {
+ fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ }
}
}
},
diff --git a/cc/builder.go b/cc/builder.go
index 0760dd4..491ebc5 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -130,6 +130,17 @@
},
"args", "crossCompile")
+ _ = pctx.SourcePathVariable("archiveRepackPath", "build/soong/scripts/archive_repack.sh")
+
+ archiveRepack = pctx.AndroidStaticRule("archiveRepack",
+ blueprint.RuleParams{
+ Depfile: "${out}.d",
+ Deps: blueprint.DepsGCC,
+ Command: "CLANG_BIN=${config.ClangBin} $archiveRepackPath -i ${in} -o ${out} -d ${out}.d ${objects}",
+ CommandDeps: []string{"$archiveRepackPath"},
+ },
+ "objects")
+
emptyFile = pctx.AndroidStaticRule("emptyFile",
blueprint.RuleParams{
Command: "rm -f $out && touch $out",
@@ -866,6 +877,20 @@
return android.OptionalPath{}
}
+func TransformArchiveRepack(ctx android.ModuleContext, inputFile android.Path,
+ outputFile android.WritablePath, objects []string) {
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: archiveRepack,
+ Description: "Repack archive " + outputFile.Base(),
+ Output: outputFile,
+ Input: inputFile,
+ Args: map[string]string{
+ "objects": strings.Join(objects, " "),
+ },
+ })
+}
+
func gccCmd(toolchain config.Toolchain, cmd string) string {
return filepath.Join(toolchain.GccRoot(), "bin", toolchain.GccTriple()+"-"+cmd)
}
diff --git a/cc/cc.go b/cc/cc.go
index 806a6ed..2a75ba9 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -488,15 +488,6 @@
return ""
}
-// IsVndkOnSystem returns true if a module is supposed to be a vndk library provided by system to vendor
-func (c *Module) IsVndkOnSystem() bool {
- if linker, ok := c.linker.(libraryInterface); ok {
- return linker.shared() && c.isVndk() && c.useVndk() && !c.isVndkExt()
- }
-
- return false
-}
-
func (c *Module) VndkVersion() string {
return c.vndkVersion()
}
diff --git a/cc/compiler.go b/cc/compiler.go
index ffb6ad2..438dee7 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -320,7 +320,9 @@
}
if ctx.apexName() != "" {
+ // TODO(b/142582178): remove the value for __ANDROID_APEX__
flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_APEX__="+ctx.apexName())
+ flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexName())+"__")
}
instructionSet := String(compiler.Properties.Instruction_set)
@@ -528,6 +530,12 @@
return false
}
+// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
+// For example, com.android.foo => COM_ANDROID_FOO
+func makeDefineString(name string) string {
+ return strings.ReplaceAll(strings.ToUpper(name), ".", "_")
+}
+
var gnuToCReplacer = strings.NewReplacer("gnu", "c")
func ndkPathDeps(ctx ModuleContext) android.Paths {
diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go
index fef4508..dfc6f76 100644
--- a/cc/toolchain_library.go
+++ b/cc/toolchain_library.go
@@ -29,6 +29,9 @@
type toolchainLibraryProperties struct {
// the prebuilt toolchain library, as a path from the top of the source tree
Src *string `android:"arch_variant"`
+
+ // Repack the archive with only the selected objects.
+ Repack_objects_to_keep []string `android:"arch_variant"`
}
type toolchainLibraryDecorator struct {
@@ -90,6 +93,14 @@
return outputFile
}
+ if library.Properties.Repack_objects_to_keep != nil {
+ fileName := ctx.ModuleName() + staticLibraryExtension
+ outputFile := android.PathForModuleOut(ctx, fileName)
+ TransformArchiveRepack(ctx, srcPath, outputFile, library.Properties.Repack_objects_to_keep)
+
+ return outputFile
+ }
+
return srcPath
}
diff --git a/cc/vndk.go b/cc/vndk.go
index 14bbf11..2c1856e 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -307,6 +307,31 @@
}
}
+func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
+ if !m.Enabled() {
+ return false
+ }
+
+ if m.Target().NativeBridge == android.NativeBridgeEnabled {
+ return false
+ }
+
+ // prebuilt vndk modules should match with device
+ // TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
+ // When b/142675459 is landed, remove following check
+ if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.matchesWithDevice(mctx.DeviceConfig()) {
+ return false
+ }
+
+ if lib, ok := m.linker.(libraryInterface); ok {
+ useCoreVariant := m.vndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
+ mctx.DeviceConfig().VndkUseCoreVariant() &&
+ !inList(m.BaseModuleName(), config.VndkMustUseVendorVariantList)
+ return lib.shared() && m.useVndk() && m.isVndk() && !m.isVndkExt() && !useCoreVariant
+ }
+ return false
+}
+
// gather list of vndk-core, vndk-sp, and ll-ndk libs
func VndkMutator(mctx android.BottomUpMutatorContext) {
m, ok := mctx.Module().(*Module)
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 2cebb6d..8ed0afb 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -130,13 +130,7 @@
func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
- arches := ctx.DeviceConfig().Arches()
- if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
- ctx.Module().SkipInstall()
- return nil
- }
-
- if ctx.DeviceConfig().BinderBitness() != p.binderBit() {
+ if !p.matchesWithDevice(ctx.DeviceConfig()) {
ctx.Module().SkipInstall()
return nil
}
@@ -153,6 +147,20 @@
return nil
}
+func (p *vndkPrebuiltLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
+ arches := config.Arches()
+ if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
+ return false
+ }
+ if config.BinderBitness() != p.binderBit() {
+ return false
+ }
+ if len(p.properties.Srcs) == 0 {
+ return false
+ }
+ return true
+}
+
func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool {
return false
}
diff --git a/scripts/archive_repack.sh b/scripts/archive_repack.sh
new file mode 100755
index 0000000..f09372d
--- /dev/null
+++ b/scripts/archive_repack.sh
@@ -0,0 +1,87 @@
+#!/bin/bash -e
+
+# Copyright 2019 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Script to extract and repack an archive with specified object files.
+# Inputs:
+# Environment:
+# CLANG_BIN: path to the clang bin directory
+# Arguments:
+# -i ${file}: input file
+# -o ${file}: output file
+# -d ${file}: deps file
+
+set -o pipefail
+
+OPTSTRING=d:i:o:
+
+usage() {
+ cat <<EOF
+Usage: archive_repack.sh [options] <objects to repack>
+
+OPTIONS:
+ -i <file>: input file
+ -o <file>: output file
+ -d <file>: deps file
+EOF
+ exit 1
+}
+
+while getopts $OPTSTRING opt; do
+ case "$opt" in
+ d) depsfile="${OPTARG}" ;;
+ i) infile="${OPTARG}" ;;
+ o) outfile="${OPTARG}" ;;
+ ?) usage ;;
+ esac
+done
+shift "$(($OPTIND -1))"
+
+if [ -z "${infile}" ]; then
+ echo "-i argument is required"
+ usage
+fi
+
+if [ -z "${outfile}" ]; then
+ echo "-o argument is required"
+ usage
+fi
+
+# Produce deps file
+if [ ! -z "${depsfile}" ]; then
+ cat <<EOF > "${depsfile}"
+${outfile}: ${infile} ${CLANG_BIN}/llvm-ar
+EOF
+fi
+
+# Get absolute path for outfile and llvm-ar.
+LLVM_AR="${PWD}/${CLANG_BIN}/llvm-ar"
+if [[ "$outfile" != /* ]]; then
+ outfile="${PWD}/${outfile}"
+fi
+
+tempdir="${outfile}.tmp"
+
+# Clean up any previous temporary files.
+rm -f "${outfile}"
+rm -rf "${tempdir}"
+
+# Do repack
+# We have to change working directory since ar only allows extracting to CWD.
+mkdir "${tempdir}"
+cp "${infile}" "${tempdir}/archive"
+cd "${tempdir}"
+"${LLVM_AR}" x "archive"
+"${LLVM_AR}" --format=gnu qc "${outfile}" "$@"