From 1f33e40972c18255188ca02877fb44e633cf2782 Mon Sep 17 00:00:00 2001 From: dimitry Date: Tue, 26 Mar 2019 12:39:31 +0100 Subject: [PATCH] Add native_bridge target to Android.bp This allows us to build guest libraries for the native bridge for arm/arm64 architectures. Bug: http://b/77159578 Test: make Change-Id: I35520ca456105ddadd456c78a4eb1e6de39147c5 --- Android.bp | 2 ++ android/androidmk.go | 25 ++++++++++++++- android/arch.go | 66 ++++++++++++++++++++++++++++++-------- android/config.go | 32 ++++++++++++++---- android/module.go | 3 ++ android/variable.go | 10 ++++++ cc/cc.go | 2 ++ cc/installer.go | 2 +- java/dexpreopt.go | 4 ++- java/dexpreopt_bootjars.go | 6 ++-- 10 files changed, 128 insertions(+), 24 deletions(-) diff --git a/Android.bp b/Android.bp index 25e2796c7..365c5bf96 100644 --- a/Android.bp +++ b/Android.bp @@ -444,6 +444,7 @@ toolchain_library { defaults: ["linux_bionic_supported"], vendor_available: true, recovery_available: true, + native_bridge_supported: true, arch: { arm: { @@ -466,6 +467,7 @@ toolchain_library { defaults: ["linux_bionic_supported"], vendor_available: true, recovery_available: true, + native_bridge_supported: true, arch: { arm: { diff --git a/android/androidmk.go b/android/androidmk.go index 2a3748e3a..2bbd452b1 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -28,6 +28,10 @@ import ( "github.com/google/blueprint/bootstrap" ) +var ( + NativeBridgeSuffix = ".native_bridge" +) + func init() { RegisterSingletonType("androidmk", AndroidMkSingleton) } @@ -161,6 +165,10 @@ func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod bluep } } + if amod.Target().NativeBridge { + a.SubName += NativeBridgeSuffix + } + fmt.Fprintln(&a.header, "\ninclude $(CLEAR_VARS)") // Collect make variable assignment entries. @@ -190,7 +198,22 @@ func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod bluep 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 957a659c6..c68fe4667 100644 --- a/android/arch.go +++ b/android/arch.go @@ -683,13 +683,25 @@ func osByName(name string) OsType { 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 @@ func archMutator(mctx BottomUpMutatorContext) { 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 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { 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 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { targets[os] = append(targets[os], Target{ - Os: os, - Arch: arch, + Os: os, + Arch: arch, + NativeBridge: nativeBridgeEnabled, }) } @@ -1400,14 +1426,14 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { 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 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { 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 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { } 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 3495ad28a..b14204288 100644 --- a/android/config.go +++ b/android/config.go @@ -234,16 +234,36 @@ func TestConfig(buildDir string, env map[string]string) Config { 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 @@ func TestArchConfig(buildDir string, env map[string]string) Config { 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 e3c37bb2e..fb5c00acb 100644 --- a/android/module.go +++ b/android/module.go @@ -290,6 +290,9 @@ type commonProperties struct { // 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"` diff --git a/android/variable.go b/android/variable.go index d29ba73be..c5006716f 100644 --- a/android/variable.go +++ b/android/variable.go @@ -165,6 +165,16 @@ type productVariables struct { 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/cc/cc.go b/cc/cc.go index 0f5c68a6b..bb24942a2 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1804,6 +1804,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { 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/installer.go b/cc/installer.go index bd8f9e791..cb261b739 100644 --- a/cc/installer.go +++ b/cc/installer.go @@ -66,7 +66,7 @@ func (installer *baseInstaller) installDir(ctx ModuleContext) android.OutputPath 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/java/dexpreopt.go b/java/dexpreopt.go index a7938c82c..08fd06ed6 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -111,7 +111,9 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo 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 cb2ea9f0a..092a1332e 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -197,8 +197,10 @@ func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootI } 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()...) + } } }