From 1613e5541fd5aa5d22f093d8a53787b503aed624 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 14 Sep 2020 19:43:17 +0900 Subject: [PATCH] HostCross is an attribute of a Target, not OsType A host target is considered as being cross-compiled when the target can't run natively on the build machine. For example, linux_glibc/x86_64 is a non-cross target on a standard x86/Linux machine, but is a cross host on Mac. Previously, whether cross or not was a static attribute of an OsType. For example, Windows was always considered as cross host, while linux_bionic was not. This becomes a problem when we support more host targets like linux_bionic/arm64 which should be cross-host on standard x86/Linux machines. This change removes HostCross from the OsClass type and instead adds a property HostCross to the Target type. When a target is being added, it is initialized to true when the target can't run natively on the current build machine. Bug: 168086242 Test: m Change-Id: Ic37c8db918873ddf324c86b12b5412952b0f2be2 --- android/androidmk.go | 35 ++++++++++++--------- android/arch.go | 68 ++++++++++++++++++++++++++-------------- android/config.go | 20 ++++++------ android/module.go | 48 +++++++++++++++------------- android/prebuilt_test.go | 2 +- apex/androidmk.go | 15 ++++----- cc/cc.go | 4 +-- java/app.go | 2 +- python/binary.go | 2 +- python/library.go | 2 +- sdk/testing.go | 6 ++-- sdk/update.go | 12 +++---- 12 files changed, 124 insertions(+), 92 deletions(-) diff --git a/android/androidmk.go b/android/androidmk.go index fafbfd61e..e90e5f0e0 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -304,15 +304,16 @@ func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod bluep host := false switch amod.Os().Class { case Host: - // Make cannot identify LOCAL_MODULE_HOST_ARCH:= common. - if amod.Arch().ArchType != Common { - a.SetString("LOCAL_MODULE_HOST_ARCH", archStr) - } - host = true - case HostCross: - // Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common. - if amod.Arch().ArchType != Common { - a.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr) + if amod.Target().HostCross { + // Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common. + if amod.Arch().ArchType != Common { + a.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr) + } + } else { + // Make cannot identify LOCAL_MODULE_HOST_ARCH:= common. + if amod.Arch().ArchType != Common { + a.SetString("LOCAL_MODULE_HOST_ARCH", archStr) + } } host = true case Device: @@ -359,9 +360,11 @@ func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod bluep if amod.ArchSpecific() { switch amod.Os().Class { case Host: - prefix = "HOST_" - case HostCross: - prefix = "HOST_CROSS_" + if amod.Target().HostCross { + prefix = "HOST_CROSS_" + } else { + prefix = "HOST_" + } case Device: prefix = "TARGET_" @@ -563,9 +566,11 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Mod if amod.ArchSpecific() { switch amod.Os().Class { case Host: - prefix = "HOST_" - case HostCross: - prefix = "HOST_CROSS_" + if amod.Target().HostCross { + prefix = "HOST_CROSS_" + } else { + prefix = "HOST_" + } case Device: prefix = "TARGET_" diff --git a/android/arch.go b/android/arch.go index 414113893..655257076 100644 --- a/android/arch.go +++ b/android/arch.go @@ -578,7 +578,7 @@ var ( Linux = NewOsType("linux_glibc", Host, false) Darwin = NewOsType("darwin", Host, false) LinuxBionic = NewOsType("linux_bionic", Host, false) - Windows = NewOsType("windows", HostCross, true) + Windows = NewOsType("windows", Host, true) Android = NewOsType("android", Device, false) Fuchsia = NewOsType("fuchsia", Device, false) @@ -609,7 +609,6 @@ const ( Generic OsClass = iota Device Host - HostCross ) func (class OsClass) String() string { @@ -620,8 +619,6 @@ func (class OsClass) String() string { return "device" case Host: return "host" - case HostCross: - return "host cross" default: panic(fmt.Errorf("unknown class %d", class)) } @@ -681,6 +678,11 @@ type Target struct { NativeBridge NativeBridgeSupport NativeBridgeHostArchName string NativeBridgeRelativePath string + + // HostCross is true when the target cannot run natively on the current build host. + // For example, linux_glibc_x86 returns true on a regular x86/i686/Linux machines, but returns false + // on Mac (different OS), or on 64-bit only i686/Linux machines (unsupported arch). + HostCross bool } func (target Target) String() string { @@ -739,26 +741,15 @@ func osMutator(bpctx blueprint.BottomUpMutatorContext) { return } - osClasses := base.OsClassSupported() - var moduleOSList []OsType for _, os := range OsTypeList { - supportedClass := false - for _, osClass := range osClasses { - if os.Class == osClass { - supportedClass = true + for _, t := range mctx.Config().Targets[os] { + if base.supportsTarget(t, mctx.Config()) { + moduleOSList = append(moduleOSList, os) + break } } - if !supportedClass { - continue - } - - if len(mctx.Config().Targets[os]) == 0 { - continue - } - - moduleOSList = append(moduleOSList, os) } if len(moduleOSList) == 0 { @@ -913,7 +904,7 @@ func archMutator(bpctx blueprint.BottomUpMutatorContext) { prefer32 := false if base.prefer32 != nil { - prefer32 = base.prefer32(mctx, base, os.Class) + prefer32 = base.prefer32(mctx, base, os) } multilib, extraMultilib := decodeMultilib(base, os.Class) @@ -964,7 +955,7 @@ func decodeMultilib(base *ModuleBase, class OsClass) (multilib, extraMultilib st switch class { case Device: multilib = String(base.commonProperties.Target.Android.Compile_multilib) - case Host, HostCross: + case Host: multilib = String(base.commonProperties.Target.Host.Compile_multilib) } if multilib == "" { @@ -1240,7 +1231,7 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { // key: value, // }, // }, - if os.Class == Host || os.Class == HostCross { + if os.Class == Host { field := "Host" prefix := "target.host" m.appendProperties(ctx, genProps, targetProp, field, prefix) @@ -1280,7 +1271,7 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { prefix := "target." + os.Name m.appendProperties(ctx, genProps, targetProp, field, prefix) - if (os.Class == Host || os.Class == HostCross) && os != Windows { + if os.Class == Host && os != Windows { field := "Not_windows" prefix := "target.not_windows" m.appendProperties(ctx, genProps, targetProp, field, prefix) @@ -1508,6 +1499,36 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { nativeBridgeRelativePathStr = arch.ArchType.String() } + // A target is considered as HostCross if it's a host target which can't run natively on + // the currently configured build machine (either because the OS is different or because of + // the unsupported arch) + hostCross := false + if os.Class == Host { + var osSupported bool + if os == BuildOs { + osSupported = true + } else if BuildOs.Linux() && os.Linux() { + // LinuxBionic and Linux are compatible + osSupported = true + } else { + osSupported = false + } + + var archSupported bool + if arch.ArchType == Common { + archSupported = true + } else if arch.ArchType.Name == *variables.HostArch { + archSupported = true + } else if variables.HostSecondaryArch != nil && arch.ArchType.Name == *variables.HostSecondaryArch { + archSupported = true + } else { + archSupported = false + } + if !osSupported || !archSupported { + hostCross = true + } + } + targets[os] = append(targets[os], Target{ Os: os, @@ -1515,6 +1536,7 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { NativeBridge: nativeBridgeEnabled, NativeBridgeHostArchName: nativeBridgeHostArchNameStr, NativeBridgeRelativePath: nativeBridgeRelativePathStr, + HostCross: hostCross, }) } diff --git a/android/config.go b/android/config.go index 1c06e8c55..f8c8821fa 100644 --- a/android/config.go +++ b/android/config.go @@ -260,10 +260,10 @@ func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp strin config := testConfig.config config.Targets[Android] = []Target{ - {Android, Arch{ArchType: X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", ""}, - {Android, Arch{ArchType: X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", ""}, - {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeEnabled, "x86_64", "arm64"}, - {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeEnabled, "x86", "arm"}, + {Android, Arch{ArchType: X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, + {Android, Arch{ArchType: X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false}, + {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeEnabled, "x86_64", "arm64", false}, + {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeEnabled, "x86", "arm", false}, } return testConfig @@ -275,10 +275,10 @@ func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs config.Targets = map[OsType][]Target{ Fuchsia: []Target{ - {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", ""}, + {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, }, BuildOs: []Target{ - {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", ""}, + {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false}, }, } @@ -292,12 +292,12 @@ func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[st config.Targets = map[OsType][]Target{ Android: []Target{ - {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", ""}, - {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", ""}, + {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, + {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false}, }, BuildOs: []Target{ - {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", ""}, - {BuildOs, Arch{ArchType: X86}, NativeBridgeDisabled, "", ""}, + {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false}, + {BuildOs, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false}, }, } diff --git a/android/module.go b/android/module.go index 5bc7a17b6..e1b98f657 100644 --- a/android/module.go +++ b/android/module.go @@ -923,7 +923,7 @@ type ModuleBase struct { initRcPaths Paths vintfFragmentsPaths Paths - prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool + prefer32 func(ctx BaseModuleContext, base *ModuleBase, os OsType) bool } func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {} @@ -950,7 +950,7 @@ func (m *ModuleBase) VariablesForTests() map[string]string { return m.variables } -func (m *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) { +func (m *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, os OsType) bool) { m.prefer32 = prefer32 } @@ -1046,7 +1046,7 @@ func (m *ModuleBase) Os() OsType { } func (m *ModuleBase) Host() bool { - return m.Os().Class == Host || m.Os().Class == HostCross + return m.Os().Class == Host } func (m *ModuleBase) Device() bool { @@ -1066,28 +1066,28 @@ func (m *ModuleBase) IsCommonOSVariant() bool { return m.commonProperties.CommonOSVariant } -func (m *ModuleBase) OsClassSupported() []OsClass { +func (m *ModuleBase) supportsTarget(target Target, config Config) bool { switch m.commonProperties.HostOrDeviceSupported { case HostSupported: - return []OsClass{Host, HostCross} + return target.Os.Class == Host case HostSupportedNoCross: - return []OsClass{Host} + return target.Os.Class == Host && !target.HostCross case DeviceSupported: - return []OsClass{Device} + return target.Os.Class == Device case HostAndDeviceSupported, HostAndDeviceDefault: - var supported []OsClass + supported := false if Bool(m.hostAndDeviceProperties.Host_supported) || (m.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault && m.hostAndDeviceProperties.Host_supported == nil) { - supported = append(supported, Host, HostCross) + supported = supported || target.Os.Class == Host } if m.hostAndDeviceProperties.Device_supported == nil || *m.hostAndDeviceProperties.Device_supported { - supported = append(supported, Device) + supported = supported || target.Os.Class == Device } return supported default: - return nil + return false } } @@ -2075,7 +2075,7 @@ func (b *baseModuleContext) Os() OsType { } func (b *baseModuleContext) Host() bool { - return b.os.Class == Host || b.os.Class == HostCross + return b.os.Class == Host } func (b *baseModuleContext) Device() bool { @@ -2535,30 +2535,36 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { } // Create (host|host-cross|target)- phony rules to build a reduced checkbuild. - osDeps := map[OsType]Paths{} + type osAndCross struct { + os OsType + hostCross bool + } + osDeps := map[osAndCross]Paths{} ctx.VisitAllModules(func(module Module) { if module.Enabled() { - os := module.Target().Os - osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...) + key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross} + osDeps[key] = append(osDeps[key], module.base().checkbuildFiles...) } }) osClass := make(map[string]Paths) - for os, deps := range osDeps { + for key, deps := range osDeps { var className string - switch os.Class { + switch key.os.Class { case Host: - className = "host" - case HostCross: - className = "host-cross" + if key.hostCross { + className = "host-cross" + } else { + className = "host" + } case Device: className = "target" default: continue } - name := className + "-" + os.Name + name := className + "-" + key.os.Name osClass[className] = append(osClass[className], PathForPhony(ctx, name)) ctx.Phony(name, deps...) diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index 6c3cd9eef..854395e64 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -285,7 +285,7 @@ func TestPrebuilts(t *testing.T) { t.Errorf("windows is assumed to be disabled by default") } config.config.Targets[Windows] = []Target{ - {Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", ""}, + {Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", true}, } ctx := NewTestArchContext() diff --git a/apex/androidmk.go b/apex/androidmk.go index 1b53a672b..c4fe3a36a 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -157,13 +157,14 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo host := false switch fi.module.Target().Os.Class { case android.Host: - if fi.module.Target().Arch.ArchType != android.Common { - fmt.Fprintln(w, "LOCAL_MODULE_HOST_ARCH :=", archStr) - } - host = true - case android.HostCross: - if fi.module.Target().Arch.ArchType != android.Common { - fmt.Fprintln(w, "LOCAL_MODULE_HOST_CROSS_ARCH :=", archStr) + if fi.module.Target().HostCross { + if fi.module.Target().Arch.ArchType != android.Common { + fmt.Fprintln(w, "LOCAL_MODULE_HOST_CROSS_ARCH :=", archStr) + } + } else { + if fi.module.Target().Arch.ArchType != android.Common { + fmt.Fprintln(w, "LOCAL_MODULE_HOST_ARCH :=", archStr) + } } host = true case android.Device: diff --git a/cc/cc.go b/cc/cc.go index 6584380aa..d0d6427bd 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -950,9 +950,9 @@ func (c *Module) Init() android.Module { c.AddProperties(feature.props()...) } - c.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool { + c.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, os android.OsType) bool { // Windows builds always prefer 32-bit - return class == android.HostCross + return os == android.Windows }) android.InitAndroidArchModule(c, c.hod, c.multilib) android.InitApexModule(c) diff --git a/java/app.go b/java/app.go index ae7373fc7..9ffb6b4a1 100755 --- a/java/app.go +++ b/java/app.go @@ -678,7 +678,7 @@ func (a *AndroidApp) noticeBuildActions(ctx android.ModuleContext) { seenModules[child] = true // Skip host modules. - if child.Target().Os.Class == android.Host || child.Target().Os.Class == android.HostCross { + if child.Target().Os.Class == android.Host { return false } diff --git a/python/binary.go b/python/binary.go index 5a7492648..1d2400efd 100644 --- a/python/binary.go +++ b/python/binary.go @@ -79,7 +79,7 @@ func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { } func PythonBinaryHostFactory() android.Module { - module, _ := NewBinary(android.HostSupportedNoCross) + module, _ := NewBinary(android.HostSupported) return module.Init() } diff --git a/python/library.go b/python/library.go index 65c1352e7..0c8d61313 100644 --- a/python/library.go +++ b/python/library.go @@ -26,7 +26,7 @@ func init() { } func PythonLibraryHostFactory() android.Module { - module := newModule(android.HostSupportedNoCross, android.MultilibFirst) + module := newModule(android.HostSupported, android.MultilibFirst) return module.Init() } diff --git a/sdk/testing.go b/sdk/testing.go index b53558d9f..e57f1f79d 100644 --- a/sdk/testing.go +++ b/sdk/testing.go @@ -68,14 +68,14 @@ func testSdkContext(bp string, fs map[string][]byte, extraOsTypes []android.OsTy // Add windows as a default disable OS to test behavior when some OS variants // are disabled. config.Targets[android.Windows] = []android.Target{ - {android.Windows, android.Arch{ArchType: android.X86_64}, android.NativeBridgeDisabled, "", ""}, + {android.Windows, android.Arch{ArchType: android.X86_64}, android.NativeBridgeDisabled, "", "", true}, } for _, extraOsType := range extraOsTypes { switch extraOsType { case android.LinuxBionic: config.Targets[android.LinuxBionic] = []android.Target{ - {android.LinuxBionic, android.Arch{ArchType: android.X86_64}, android.NativeBridgeDisabled, "", ""}, + {android.LinuxBionic, android.Arch{ArchType: android.X86_64}, android.NativeBridgeDisabled, "", "", false}, } } } @@ -89,7 +89,7 @@ func testSdkContext(bp string, fs map[string][]byte, extraOsTypes []android.OsTy android.RegisterAndroidMkBuildComponents(ctx) android.SetInMakeForTests(config) config.Targets[android.CommonOS] = []android.Target{ - {android.CommonOS, android.Arch{ArchType: android.Common}, android.NativeBridgeDisabled, "", ""}, + {android.CommonOS, android.Arch{ArchType: android.Common}, android.NativeBridgeDisabled, "", "", true}, } // from android package diff --git a/sdk/update.go b/sdk/update.go index 537ab13cb..3c4309cf3 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -371,8 +371,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro osPropertySet := targetPropertySet.AddPropertySet(sdkVariant.Target().Os.Name) // Enable the variant explicitly when we've disabled it by default on host. - if hasHostOsDependentMember && - (osType.Class == android.Host || osType.Class == android.HostCross) { + if hasHostOsDependentMember && osType.Class == android.Host { osPropertySet.AddProperty("enabled", true) } @@ -731,7 +730,7 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType for _, variant := range member.Variants() { osClass := variant.Target().Os.Class - if osClass == android.Host || osClass == android.HostCross { + if osClass == android.Host { hostSupported = true } else if osClass == android.Device { deviceSupported = true @@ -1061,8 +1060,7 @@ func (osInfo *osTypeSpecificInfo) addToPropertySet(ctx *memberContext, bpModule archPropertySet = targetPropertySet // Enable the variant explicitly when we've disabled it by default on host. - if ctx.memberType.IsHostOsDependent() && - (osType.Class == android.Host || osType.Class == android.HostCross) { + if ctx.memberType.IsHostOsDependent() && osType.Class == android.Host { osPropertySet.AddProperty("enabled", true) } @@ -1086,7 +1084,7 @@ func (osInfo *osTypeSpecificInfo) addToPropertySet(ctx *memberContext, bpModule func (osInfo *osTypeSpecificInfo) isHostVariant() bool { osClass := osInfo.osType.Class - return osClass == android.Host || osClass == android.HostCross + return osClass == android.Host } var _ isHostVariant = (*osTypeSpecificInfo)(nil) @@ -1323,7 +1321,7 @@ func (s *sdk) getPossibleOsTypes() []android.OsType { } } if s.HostSupported() { - if osType.Class == android.Host || osType.Class == android.HostCross { + if osType.Class == android.Host { osTypes = append(osTypes, osType) } }