Merge "uncompressedDex option for android_app_import."
diff --git a/Android.bp b/Android.bp
index 1fdd44e..afac2b5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -276,6 +276,7 @@
"java/plugin.go",
"java/prebuilt_apis.go",
"java/proto.go",
+ "java/robolectric.go",
"java/sdk.go",
"java/sdk_library.go",
"java/support_libraries.go",
@@ -443,6 +444,7 @@
defaults: ["linux_bionic_supported"],
vendor_available: true,
recovery_available: true,
+ native_bridge_supported: true,
arch: {
arm: {
@@ -465,6 +467,7 @@
defaults: ["linux_bionic_supported"],
vendor_available: true,
recovery_available: true,
+ native_bridge_supported: true,
arch: {
arm: {
@@ -483,6 +486,118 @@
}
toolchain_library {
+ name: "libgcc_stripped",
+ defaults: ["linux_bionic_supported"],
+ vendor_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
+
+ 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",
+ ],
+ use_gnu_strip: true,
+ },
+ },
+ arm64: {
+ src: "prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a",
+ },
+ 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",
+
+ },
+ 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",
+ },
+ },
+ 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",
+ ],
+ use_gnu_strip: true,
+ },
+}
+
+toolchain_library {
name: "libwinpthread",
host_supported: true,
enabled: false,
diff --git a/android/androidmk.go b/android/androidmk.go
index 2a3748e..2bbd452 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -28,6 +28,10 @@
"github.com/google/blueprint/bootstrap"
)
+var (
+ NativeBridgeSuffix = ".native_bridge"
+)
+
func init() {
RegisterSingletonType("androidmk", AndroidMkSingleton)
}
@@ -161,6 +165,10 @@
}
}
+ if amod.Target().NativeBridge {
+ a.SubName += NativeBridgeSuffix
+ }
+
fmt.Fprintln(&a.header, "\ninclude $(CLEAR_VARS)")
// Collect make variable assignment entries.
@@ -190,7 +198,22 @@
case Device:
// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
if archStr != "common" {
- a.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
+ if amod.Target().NativeBridge {
+ // TODO: Unhardcode these rules.
+ guestArchStr := archStr
+ hostArchStr := ""
+ if guestArchStr == "arm" {
+ hostArchStr = "x86"
+ } else if guestArchStr == "arm64" {
+ hostArchStr = "x86_64"
+ }
+
+ if hostArchStr != "" {
+ a.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
+ }
+ } else {
+ a.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
+ }
}
a.AddStrings("LOCAL_INIT_RC", amod.commonProperties.Init_rc...)
diff --git a/android/arch.go b/android/arch.go
index 957a659..c68fe46 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -683,13 +683,25 @@
return NoOsType
}
+type NativeBridgeSupport bool
+
+const (
+ NativeBridgeDisabled NativeBridgeSupport = false
+ NativeBridgeEnabled NativeBridgeSupport = true
+)
+
type Target struct {
- Os OsType
- Arch Arch
+ Os OsType
+ Arch Arch
+ NativeBridge NativeBridgeSupport
}
func (target Target) String() string {
- return target.Os.String() + "_" + target.Arch.String()
+ variant := ""
+ if target.NativeBridge {
+ variant = "native_bridge_"
+ }
+ return target.Os.String() + "_" + variant + target.Arch.String()
}
// archMutator splits a module into a variant for each Target requested by the module. Target selection
@@ -750,6 +762,18 @@
continue
}
+ // Filter NativeBridge targets unless they are explicitly supported
+ if os == Android && !Bool(base.commonProperties.Native_bridge_supported) {
+ var targets []Target
+ for _, t := range osTargets {
+ if !t.NativeBridge {
+ targets = append(targets, t)
+ }
+ }
+
+ osTargets = targets
+ }
+
// only the primary arch in the recovery partition
if os == Android && module.InstallInRecovery() {
osTargets = []Target{osTargets[0]}
@@ -1378,7 +1402,8 @@
targets := make(map[OsType][]Target)
var targetErr error
- addTarget := func(os OsType, archName string, archVariant, cpuVariant *string, abi []string) {
+ addTarget := func(os OsType, archName string, archVariant, cpuVariant *string, abi []string,
+ nativeBridgeEnabled NativeBridgeSupport) {
if targetErr != nil {
return
}
@@ -1391,8 +1416,9 @@
targets[os] = append(targets[os],
Target{
- Os: os,
- Arch: arch,
+ Os: os,
+ Arch: arch,
+ NativeBridge: nativeBridgeEnabled,
})
}
@@ -1400,14 +1426,14 @@
return nil, fmt.Errorf("No host primary architecture set")
}
- addTarget(BuildOs, *variables.HostArch, nil, nil, nil)
+ addTarget(BuildOs, *variables.HostArch, nil, nil, nil, NativeBridgeDisabled)
if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" {
- addTarget(BuildOs, *variables.HostSecondaryArch, nil, nil, nil)
+ addTarget(BuildOs, *variables.HostSecondaryArch, nil, nil, nil, NativeBridgeDisabled)
}
if Bool(config.Host_bionic) {
- addTarget(LinuxBionic, "x86_64", nil, nil, nil)
+ addTarget(LinuxBionic, "x86_64", nil, nil, nil, NativeBridgeDisabled)
}
if String(variables.CrossHost) != "" {
@@ -1420,10 +1446,10 @@
return nil, fmt.Errorf("No cross-host primary architecture set")
}
- addTarget(crossHostOs, *variables.CrossHostArch, nil, nil, nil)
+ addTarget(crossHostOs, *variables.CrossHostArch, nil, nil, nil, NativeBridgeDisabled)
if variables.CrossHostSecondaryArch != nil && *variables.CrossHostSecondaryArch != "" {
- addTarget(crossHostOs, *variables.CrossHostSecondaryArch, nil, nil, nil)
+ addTarget(crossHostOs, *variables.CrossHostSecondaryArch, nil, nil, nil, NativeBridgeDisabled)
}
}
@@ -1434,18 +1460,32 @@
}
addTarget(target, *variables.DeviceArch, variables.DeviceArchVariant,
- variables.DeviceCpuVariant, variables.DeviceAbi)
+ variables.DeviceCpuVariant, variables.DeviceAbi, NativeBridgeDisabled)
if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" {
addTarget(Android, *variables.DeviceSecondaryArch,
variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant,
- variables.DeviceSecondaryAbi)
+ variables.DeviceSecondaryAbi, NativeBridgeDisabled)
deviceArches := targets[Android]
if deviceArches[0].Arch.ArchType.Multilib == deviceArches[1].Arch.ArchType.Multilib {
deviceArches[1].Arch.Native = false
}
}
+
+ if variables.NativeBridgeArch != nil && *variables.NativeBridgeArch != "" {
+ addTarget(Android, *variables.NativeBridgeArch,
+ variables.NativeBridgeArchVariant, variables.NativeBridgeCpuVariant,
+ variables.NativeBridgeAbi, NativeBridgeEnabled)
+ }
+
+ if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" &&
+ variables.NativeBridgeSecondaryArch != nil && *variables.NativeBridgeSecondaryArch != "" {
+ addTarget(Android, *variables.NativeBridgeSecondaryArch,
+ variables.NativeBridgeSecondaryArchVariant,
+ variables.NativeBridgeSecondaryCpuVariant,
+ variables.NativeBridgeSecondaryAbi, NativeBridgeEnabled)
+ }
}
if targetErr != nil {
diff --git a/android/config.go b/android/config.go
index 3495ad2..b142042 100644
--- a/android/config.go
+++ b/android/config.go
@@ -234,16 +234,36 @@
return Config{config}
}
+func TestArchConfigNativeBridge(buildDir string, env map[string]string) Config {
+ testConfig := TestConfig(buildDir, env)
+ config := testConfig.config
+
+ config.Targets = map[OsType][]Target{
+ Android: []Target{
+ {Android, Arch{ArchType: X86_64, ArchVariant: "silvermont", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled},
+ {Android, Arch{ArchType: X86, ArchVariant: "silvermont", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled},
+ {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridgeEnabled},
+ {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridgeEnabled},
+ },
+ BuildOs: []Target{
+ {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled},
+ {BuildOs, Arch{ArchType: X86}, NativeBridgeDisabled},
+ },
+ }
+
+ return testConfig
+}
+
func TestArchConfigFuchsia(buildDir string, env map[string]string) Config {
testConfig := TestConfig(buildDir, env)
config := testConfig.config
config.Targets = map[OsType][]Target{
Fuchsia: []Target{
- {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Native: true}},
+ {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Native: true}, NativeBridgeDisabled},
},
BuildOs: []Target{
- {BuildOs, Arch{ArchType: X86_64}},
+ {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled},
},
}
@@ -257,12 +277,12 @@
config.Targets = map[OsType][]Target{
Android: []Target{
- {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}},
- {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}},
+ {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled},
+ {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled},
},
BuildOs: []Target{
- {BuildOs, Arch{ArchType: X86_64}},
- {BuildOs, Arch{ArchType: X86}},
+ {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled},
+ {BuildOs, Arch{ArchType: X86}, NativeBridgeDisabled},
},
}
diff --git a/android/module.go b/android/module.go
index 6743412..fb5c00a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -143,6 +143,7 @@
OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
+ GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
@@ -289,6 +290,9 @@
// Whether this module is installed to recovery partition
Recovery *bool
+ // Whether this module is built for non-native architecures (also known as native bridge binary)
+ Native_bridge_supported *bool `android:"arch_variant"`
+
// init.rc files to be installed if this module is installed
Init_rc []string `android:"path"`
@@ -1093,6 +1097,18 @@
}
}
+func (a *androidModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
+ var deps []Module
+ a.VisitDirectDepsBlueprint(func(m blueprint.Module) {
+ if aModule, _ := m.(Module); aModule != nil {
+ if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
+ deps = append(deps, aModule)
+ }
+ }
+ })
+ return deps
+}
+
func (a *androidModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
m, _ := a.getDirectDepInternal(name, tag)
return m
diff --git a/android/variable.go b/android/variable.go
index d29ba73..c500671 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -165,6 +165,16 @@
DeviceSecondaryCpuVariant *string `json:",omitempty"`
DeviceSecondaryAbi []string `json:",omitempty"`
+ NativeBridgeArch *string `json:",omitempty"`
+ NativeBridgeArchVariant *string `json:",omitempty"`
+ NativeBridgeCpuVariant *string `json:",omitempty"`
+ NativeBridgeAbi []string `json:",omitempty"`
+
+ NativeBridgeSecondaryArch *string `json:",omitempty"`
+ NativeBridgeSecondaryArchVariant *string `json:",omitempty"`
+ NativeBridgeSecondaryCpuVariant *string `json:",omitempty"`
+ NativeBridgeSecondaryAbi []string `json:",omitempty"`
+
HostArch *string `json:",omitempty"`
HostSecondaryArch *string `json:",omitempty"`
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b0cd4be..5276ce4 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -93,6 +93,13 @@
}
toolchain_library {
+ name: "libgcc_stripped",
+ src: "",
+ vendor_available: true,
+ recovery_available: true,
+ }
+
+ toolchain_library {
name: "libclang_rt.builtins-aarch64-android",
src: "",
vendor_available: true,
diff --git a/cc/builder.go b/cc/builder.go
index 7b26d51..c99e461 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -255,6 +255,7 @@
groupStaticLibs bool
stripKeepSymbols bool
+ stripKeepSymbolsList string
stripKeepMiniDebugInfo bool
stripAddGnuDebuglink bool
stripUseGnuStrip bool
@@ -835,6 +836,9 @@
if flags.stripKeepSymbols {
args += " --keep-symbols"
}
+ if flags.stripKeepSymbolsList != "" {
+ args += " -k" + flags.stripKeepSymbolsList
+ }
if flags.stripUseGnuStrip {
args += " --use-gnu-strip"
}
diff --git a/cc/cc.go b/cc/cc.go
index 0f5c68a..bb24942 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1804,6 +1804,8 @@
return libName + vendorPublicLibrarySuffix
} else if ccDep.inRecovery() && !ccDep.onlyInRecovery() {
return libName + recoverySuffix
+ } else if ccDep.Target().NativeBridge == android.NativeBridgeEnabled {
+ return libName + android.NativeBridgeSuffix
} else {
return libName
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 05d74b9..f3d5e60 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -1833,13 +1833,13 @@
// Check the shared version of lib2.
variant := "android_arm64_armv8-a_core_shared"
module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
- checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
+ checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
// Check the static version of lib2.
variant = "android_arm64_armv8-a_core_static"
module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
// libc++_static is linked additionally.
- checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
+ checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
}
var compilerFlagsTestCases = []struct {
diff --git a/cc/installer.go b/cc/installer.go
index bd8f9e7..cb261b7 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -66,7 +66,7 @@
if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
dir = installer.dir64
}
- if !ctx.Host() && !ctx.Arch().Native {
+ if (!ctx.Host() && !ctx.Arch().Native) || ctx.Target().NativeBridge == android.NativeBridgeEnabled {
dir = filepath.Join(dir, ctx.Arch().ArchType.String())
}
if installer.location == InstallInData && ctx.useVndk() {
diff --git a/cc/linker.go b/cc/linker.go
index e724df6..986a562 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -228,10 +228,10 @@
// libclang_rt.builtins, libgcc and libatomic have to be last on the command line
if !Bool(linker.Properties.No_libcrt) {
deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
- }
-
- deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
- if !Bool(linker.Properties.No_libgcc) {
+ deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
+ deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc_stripped")
+ } else if !Bool(linker.Properties.No_libgcc) {
+ deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
}
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index 2a7e657..8451295 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -64,6 +64,10 @@
return deps
}
+// ndk_prebuilt_object exports a precompiled ndk object file for linking
+// operations. Soong's module name format is ndk_<NAME>.o.<sdk_version> where
+// the object is located under
+// ./prebuilts/ndk/current/platforms/android-<sdk_version>/arch-$(HOST_ARCH)/usr/lib/<NAME>.o.
func ndkPrebuiltObjectFactory() android.Module {
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
module.linker = &ndkPrebuiltObjectLinker{
@@ -98,6 +102,10 @@
return deps
}
+// ndk_prebuilt_shared_stl exports a precompiled ndk shared standard template
+// library (stl) library for linking operation. The soong's module name format
+// is ndk_<NAME>.so where the library is located under
+// ./prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs/$(HOST_ARCH)/<NAME>.so.
func ndkPrebuiltSharedStlFactory() android.Module {
module, library := NewLibrary(android.DeviceSupported)
library.BuildOnlyShared()
@@ -113,6 +121,10 @@
return module.Init()
}
+// ndk_prebuilt_static_stl exports a precompiled ndk static standard template
+// library (stl) library for linking operation. The soong's module name format
+// is ndk_<NAME>.a where the library is located under
+// ./prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs/$(HOST_ARCH)/<NAME>.a.
func ndkPrebuiltStaticStlFactory() android.Module {
module, library := NewLibrary(android.DeviceSupported)
library.BuildOnlyStatic()
diff --git a/cc/strip.go b/cc/strip.go
index 02397f4..7122585 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -15,15 +15,19 @@
package cc
import (
+ "strings"
+
"android/soong/android"
)
type StripProperties struct {
Strip struct {
- None *bool
- All *bool
- Keep_symbols *bool
- }
+ None *bool `android:"arch_variant"`
+ All *bool `android:"arch_variant"`
+ Keep_symbols *bool `android:"arch_variant"`
+ Keep_symbols_list []string `android:"arch_variant"`
+ Use_gnu_strip *bool `android:"arch_variant"`
+ } `android:"arch_variant"`
}
type stripper struct {
@@ -42,9 +46,14 @@
} else {
if Bool(stripper.StripProperties.Strip.Keep_symbols) {
flags.stripKeepSymbols = true
+ } else if len(stripper.StripProperties.Strip.Keep_symbols_list) > 0 {
+ flags.stripKeepSymbolsList = strings.Join(stripper.StripProperties.Strip.Keep_symbols_list, ",")
} else if !Bool(stripper.StripProperties.Strip.All) {
flags.stripKeepMiniDebugInfo = true
}
+ if Bool(stripper.StripProperties.Strip.Use_gnu_strip) {
+ flags.stripUseGnuStrip = true
+ }
if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo {
flags.stripAddGnuDebuglink = true
}
diff --git a/cc/testing.go b/cc/testing.go
index 2f41de1..8d76c2f 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -69,6 +69,13 @@
src: "",
}
+ toolchain_library {
+ name: "libgcc_stripped",
+ vendor_available: true,
+ recovery_available: true,
+ src: "",
+ }
+
cc_library {
name: "libc",
no_libgcc: true,
diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go
index 6494a26..b4c51ab 100644
--- a/cc/toolchain_library.go
+++ b/cc/toolchain_library.go
@@ -34,6 +34,8 @@
type toolchainLibraryDecorator struct {
*libraryDecorator
+ stripper
+
Properties toolchainLibraryProperties
}
@@ -45,7 +47,7 @@
func (library *toolchainLibraryDecorator) linkerProps() []interface{} {
var props []interface{}
props = append(props, library.libraryDecorator.linkerProps()...)
- return append(props, &library.Properties)
+ return append(props, &library.Properties, &library.stripper.StripProperties)
}
// toolchain_library is used internally by the build tool to link the specified
@@ -78,7 +80,17 @@
return android.PathForSource(ctx, "")
}
- return android.PathForSource(ctx, *library.Properties.Src)
+ srcPath := android.PathForSource(ctx, *library.Properties.Src)
+
+ if library.stripper.StripProperties.Strip.Keep_symbols_list != nil {
+ fileName := ctx.ModuleName() + staticLibraryExtension
+ outputFile := android.PathForModuleOut(ctx, fileName)
+ buildFlags := flagsToBuilderFlags(flags)
+ library.stripper.strip(ctx, srcPath, outputFile, buildFlags)
+ return outputFile
+ }
+
+ return srcPath
}
func (library *toolchainLibraryDecorator) nativeCoverage() bool {
diff --git a/java/aar.go b/java/aar.go
index 6d40a8a..5e1f88e 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -81,7 +81,7 @@
extraAaptPackagesFile android.Path
mergedManifestFile android.Path
isLibrary bool
- uncompressedJNI bool
+ useEmbeddedNativeLibs bool
useEmbeddedDex bool
usesNonSdkApis bool
@@ -201,7 +201,7 @@
manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext,
- a.isLibrary, a.uncompressedJNI, a.usesNonSdkApis, a.useEmbeddedDex)
+ a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex)
a.transitiveManifestPaths = append(android.Paths{manifestPath}, transitiveStaticLibManifests...)
diff --git a/java/android_manifest.go b/java/android_manifest.go
index ea7c2dd..7b378cd 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -43,7 +43,7 @@
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext,
- isLibrary, uncompressedJNI, usesNonSdkApis, useEmbeddedDex bool) android.Path {
+ isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex bool) android.Path {
var args []string
if isLibrary {
@@ -54,8 +54,8 @@
ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
}
if minSdkVersion >= 23 {
- args = append(args, fmt.Sprintf("--extract-native-libs=%v", !uncompressedJNI))
- } else if uncompressedJNI {
+ args = append(args, fmt.Sprintf("--extract-native-libs=%v", !useEmbeddedNativeLibs))
+ } else if useEmbeddedNativeLibs {
ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%d doesn't support it",
minSdkVersion)
}
diff --git a/java/app.go b/java/app.go
index 2280c3f..ec021fc 100644
--- a/java/app.go
+++ b/java/app.go
@@ -162,14 +162,14 @@
}
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- a.aapt.uncompressedJNI = a.shouldUncompressJNI(ctx)
+ a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
a.generateAndroidBuildActions(ctx)
}
-// shouldUncompressJNI returns true if the native libraries should be stored in the APK uncompressed and the
+// Returns true if the native libraries should be stored in the APK uncompressed and the
// extractNativeLibs application flag should be set to false in the manifest.
-func (a *AndroidApp) shouldUncompressJNI(ctx android.ModuleContext) bool {
+func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
minSdkVersion, err := sdkVersionToNumber(ctx, a.minSdkVersion())
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.minSdkVersion(), err)
@@ -288,7 +288,7 @@
a.appProperties.AlwaysPackageNativeLibs
if embedJni {
jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
- TransformJniLibsToJar(ctx, jniJarFile, jniLibs, a.shouldUncompressJNI(ctx))
+ TransformJniLibsToJar(ctx, jniJarFile, jniLibs, a.useEmbeddedNativeLibs(ctx))
} else {
a.installJniLibs = jniLibs
}
@@ -482,6 +482,8 @@
a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
}
}
+ a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
+ a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
a.generateAndroidBuildActions(ctx)
a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites)
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index a7938c8..08fd06e 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -111,7 +111,9 @@
if len(archs) == 0 {
// assume this is a java library, dexpreopt for all arches for now
for _, target := range ctx.Config().Targets[android.Android] {
- archs = append(archs, target.Arch.ArchType)
+ if target.NativeBridge == android.NativeBridgeDisabled {
+ archs = append(archs, target.Arch.ArchType)
+ }
}
if inList(ctx.ModuleName(), global.SystemServerJars) && !d.isSDKLibrary {
// If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index cb2ea9f..092a133 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -197,8 +197,10 @@
}
for _, target := range targets {
- files := buildBootImageRuleForArch(ctx, image, target.Arch.ArchType, profile, missingDeps)
- allFiles = append(allFiles, files.Paths()...)
+ if target.NativeBridge == android.NativeBridgeDisabled {
+ files := buildBootImageRuleForArch(ctx, image, target.Arch.ArchType, profile, missingDeps)
+ allFiles = append(allFiles, files.Paths()...)
+ }
}
}
diff --git a/java/robolectric.go b/java/robolectric.go
new file mode 100644
index 0000000..26f1e9d
--- /dev/null
+++ b/java/robolectric.go
@@ -0,0 +1,110 @@
+// 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.
+
+package java
+
+import (
+ "fmt"
+ "io"
+ "strings"
+
+ "android/soong/android"
+)
+
+func init() {
+ android.RegisterModuleType("android_robolectric_test", RobolectricTestFactory)
+}
+
+var robolectricDefaultLibs = []string{
+ "robolectric_android-all-stub",
+ "Robolectric_all-target",
+ "mockito-robolectric-prebuilt",
+ "truth-prebuilt",
+}
+
+type robolectricProperties struct {
+ // The name of the android_app module that the tests will run against.
+ Instrumentation_for *string
+
+ Test_options struct {
+ // Timeout in seconds when running the tests.
+ Timeout *string
+ }
+}
+
+type robolectricTest struct {
+ Library
+
+ robolectricProperties robolectricProperties
+
+ libs []string
+}
+
+func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
+ r.Library.DepsMutator(ctx)
+
+ if r.robolectricProperties.Instrumentation_for != nil {
+ ctx.AddVariationDependencies(nil, instrumentationForTag, String(r.robolectricProperties.Instrumentation_for))
+ } else {
+ ctx.PropertyErrorf("instrumentation_for", "missing required instrumented module")
+ }
+
+ ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
+}
+
+func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ r.Library.GenerateAndroidBuildActions(ctx)
+
+ for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
+ r.libs = append(r.libs, ctx.OtherModuleName(dep))
+ }
+}
+
+func (r *robolectricTest) AndroidMk() android.AndroidMkData {
+ data := r.Library.AndroidMk()
+
+ data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+ android.WriteAndroidMkData(w, data)
+
+ fmt.Fprintln(w, "")
+ fmt.Fprintln(w, "include $(CLEAR_VARS)")
+ fmt.Fprintln(w, "LOCAL_MODULE := Run"+name)
+ fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES :=", name)
+ fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES += ", strings.Join(r.libs, " "))
+ fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for))
+ if t := r.robolectricProperties.Test_options.Timeout; t != nil {
+ fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
+ }
+ fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
+ }
+
+ return data
+}
+
+// An android_robolectric_test module compiles tests against the Robolectric framework that can run on the local host
+// instead of on a device. It also generates a rule with the name of the module prefixed with "Run" that can be
+// used to run the tests. Running the tests with build rule will eventually be deprecated and replaced with atest.
+func RobolectricTestFactory() android.Module {
+ module := &robolectricTest{}
+
+ module.AddProperties(
+ &module.Module.properties,
+ &module.Module.protoProperties,
+ &module.robolectricProperties)
+
+ module.Module.dexpreopter.isTest = true
+
+ InitJavaModule(module, android.DeviceSupported)
+ return module
+}
diff --git a/scripts/strip.sh b/scripts/strip.sh
index d536907..0f77da8 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -24,6 +24,7 @@
# -i ${file}: input file (required)
# -o ${file}: output file (required)
# -d ${file}: deps file (required)
+# -k symbols: Symbols to keep (optional)
# --add-gnu-debuglink
# --keep-mini-debug-info
# --keep-symbols
@@ -32,11 +33,11 @@
set -o pipefail
-OPTSTRING=d:i:o:-:
+OPTSTRING=d:i:o:k:-:
usage() {
cat <<EOF
-Usage: strip.sh [options] -i in-file -o out-file -d deps-file
+Usage: strip.sh [options] -k symbols -i in-file -o out-file -d deps-file
Options:
--add-gnu-debuglink Add a gnu-debuglink section to out-file
--keep-mini-debug-info Keep compressed debug info in out-file
@@ -71,6 +72,20 @@
fi
}
+do_strip_keep_symbol_list() {
+ if [ -z "${use_gnu_strip}" ]; then
+ echo "do_strip_keep_symbol_list does not work with llvm-objcopy"
+ echo "http://b/131631155"
+ usage
+ fi
+
+ echo "${symbols_to_keep}" | tr ',' '\n' > "${outfile}.symbolList"
+ KEEP_SYMBOLS="-w --strip-unneeded-symbol=* --keep-symbols="
+ KEEP_SYMBOLS+="${outfile}.symbolList"
+
+ "${CROSS_COMPILE}objcopy" "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS}
+}
+
do_strip_keep_mini_debug_info() {
rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
local fail=
@@ -124,19 +139,21 @@
while getopts $OPTSTRING opt; do
case "$opt" in
- d) depsfile="${OPTARG}" ;;
- i) infile="${OPTARG}" ;;
- o) outfile="${OPTARG}" ;;
- -)
- case "${OPTARG}" in
- add-gnu-debuglink) add_gnu_debuglink=true ;;
- keep-mini-debug-info) keep_mini_debug_info=true ;;
- keep-symbols) keep_symbols=true ;;
- remove-build-id) remove_build_id=true ;;
- *) echo "Unknown option --${OPTARG}"; usage ;;
- esac;;
- ?) usage ;;
- *) echo "'${opt}' '${OPTARG}'"
+ d) depsfile="${OPTARG}" ;;
+ i) infile="${OPTARG}" ;;
+ o) outfile="${OPTARG}" ;;
+ k) symbols_to_keep="${OPTARG}" ;;
+ -)
+ case "${OPTARG}" in
+ add-gnu-debuglink) add_gnu_debuglink=true ;;
+ keep-mini-debug-info) keep_mini_debug_info=true ;;
+ keep-symbols) keep_symbols=true ;;
+ remove-build-id) remove_build_id=true ;;
+ use-gnu-strip) use_gnu_strip=true ;;
+ *) echo "Unknown option --${OPTARG}"; usage ;;
+ esac;;
+ ?) usage ;;
+ *) echo "'${opt}' '${OPTARG}'"
esac
done
@@ -160,6 +177,11 @@
usage
fi
+if [ ! -z "${symbols_to_keep}" -a ! -z "${keep_symbols}" ]; then
+ echo "--keep-symbols and -k cannot be used together"
+ usage
+fi
+
if [ ! -z "${add_gnu_debuglink}" -a ! -z "${keep_mini_debug_info}" ]; then
echo "--add-gnu-debuglink cannot be used with --keep-mini-debug-info"
usage
@@ -169,6 +191,8 @@
if [ ! -z "${keep_symbols}" ]; then
do_strip_keep_symbols
+elif [ ! -z "${symbols_to_keep}" ]; then
+ do_strip_keep_symbol_list
elif [ ! -z "${keep_mini_debug_info}" ]; then
do_strip_keep_mini_debug_info
else
diff --git a/ui/build/build.go b/ui/build/build.go
index 0ae06d6..59d1474 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -166,11 +166,13 @@
runMakeProductConfig(ctx, config)
}
- if inList("installclean", config.Arguments()) {
+ if inList("installclean", config.Arguments()) ||
+ inList("install-clean", config.Arguments()) {
installClean(ctx, config, what)
ctx.Println("Deleted images and staging directories.")
return
- } else if inList("dataclean", config.Arguments()) {
+ } else if inList("dataclean", config.Arguments()) ||
+ inList("data-clean", config.Arguments()) {
dataClean(ctx, config, what)
ctx.Println("Deleted data files.")
return
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index ed2d9ca..54006d2 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -74,13 +74,16 @@
}
var Configuration = map[string]PathConfig{
- "bash": Allowed,
- "bc": Allowed,
+ "bash": Allowed,
+ "bc": Allowed,
+ // We need bzip2 here even though we provide a bzip2 binary because
+ // GNU tar seems to avoid calling ours.
"bzip2": Allowed,
"date": Allowed,
"dd": Allowed,
"diff": Allowed,
"egrep": Allowed,
+ "expr": Allowed,
"find": Allowed,
"fuser": Allowed,
"getopt": Allowed,
@@ -104,7 +107,6 @@
"timeout": Allowed,
"tr": Allowed,
"unzip": Allowed,
- "xz": Allowed,
"zip": Allowed,
"zipinfo": Allowed,
@@ -134,7 +136,6 @@
"du": LinuxOnlyPrebuilt,
"echo": LinuxOnlyPrebuilt,
"env": LinuxOnlyPrebuilt,
- "expr": LinuxOnlyPrebuilt,
"head": LinuxOnlyPrebuilt,
"getconf": LinuxOnlyPrebuilt,
"hostname": LinuxOnlyPrebuilt,