Reland "[build] Fix Android build for ARM64 Mac."

Account for simarm_x64 in TargetCpuForArch.

TEST=local
Bug: https://github.com/dart-lang/sdk/issues/48792
Change-Id: I820cb49ee8925c50196cb2472266f9e248c9089d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243642
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2022-05-10 16:11:53 +00:00 committed by Commit Bot
parent 0d636e5543
commit 3c01efcbb0
8 changed files with 134 additions and 85 deletions

10
DEPS
View file

@ -54,7 +54,7 @@ vars = {
# Checkout Android dependencies only on Mac and Linux.
"download_android_deps":
"(host_os == mac or host_os == linux) and host_cpu == x64",
"host_os == mac or (host_os == linux and host_cpu == x64)",
# Checkout extra javascript engines for testing or benchmarking.
# d8, the V8 shell, is always checked out.
@ -528,7 +528,7 @@ deps = {
Var("dart_root") + "/third_party/android_tools/ndk": {
"packages": [
{
"package": "flutter/android/ndk/${{platform}}",
"package": "flutter/android/ndk/${{os}}-amd64",
"version": "version:r21.0.6113669"
}
],
@ -539,7 +539,7 @@ deps = {
Var("dart_root") + "/third_party/android_tools/sdk/build-tools": {
"packages": [
{
"package": "flutter/android/sdk/build-tools/${{platform}}",
"package": "flutter/android/sdk/build-tools/${{os}}-amd64",
"version": "version:30.0.1"
}
],
@ -550,7 +550,7 @@ deps = {
Var("dart_root") + "/third_party/android_tools/sdk/platform-tools": {
"packages": [
{
"package": "flutter/android/sdk/platform-tools/${{platform}}",
"package": "flutter/android/sdk/platform-tools/${{os}}-amd64",
"version": "version:29.0.2"
}
],
@ -572,7 +572,7 @@ deps = {
Var("dart_root") + "/third_party/android_tools/sdk/tools": {
"packages": [
{
"package": "flutter/android/sdk/tools/${{platform}}",
"package": "flutter/android/sdk/tools/${{os}}-amd64",
"version": "version:26.1.1"
}
],

View file

@ -26,6 +26,9 @@ if (is_android) {
# architecture, which is different than the names GN uses.
if (host_cpu == "x64" || host_cpu == "x86") {
android_host_arch = "x86_64"
} else if (host_cpu == "arm64") {
# Run existing Android toolchain via Rosetta.
android_host_arch = "x86_64"
} else {
assert(false, "Need Android toolchain support for your build CPU arch.")
}

View file

@ -339,10 +339,10 @@ struct simd128_value_t {
#endif // !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS)
#elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) || \
defined(TARGET_ARCH_RISCV32)
#if defined(HOST_ARCH_X64) && defined(TARGET_ARCH_ARM)
// This is simarm_x64, which is the only case where host/target architecture
// mismatch is allowed. Unless, we're running FFI unit tests.
#define IS_SIMARM_X64 1
#if defined(ARCH_IS_64_BIT) && defined(TARGET_ARCH_ARM)
// This is simarm_x64 or simarm_arm64, which is the only case where host/target
// architecture mismatch is allowed. Unless, we're running FFI unit tests.
#define IS_SIMARM_HOST64 1
#elif !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
#error Mismatched Host/Target architectures.
#endif // !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
@ -360,7 +360,7 @@ struct simd128_value_t {
#elif defined(TARGET_ARCH_ARM)
#if !defined(HOST_ARCH_ARM)
#define TARGET_HOST_MISMATCH 1
#if !defined(IS_SIMARM_X64)
#if !defined(IS_SIMARM_HOST64)
#define USING_SIMULATOR 1
#endif
#endif

View file

@ -1512,14 +1512,14 @@ void Disassembler::DecodeInstruction(char* hex_buffer,
*object = NULL;
// TODO(36839): Make DecodeLoadObjectFromPoolOrThread work on simarm_x64.
#if !defined(IS_SIMARM_X64)
#if !defined(IS_SIMARM_HOST64)
if (!code.IsNull()) {
*object = &Object::Handle();
if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
*object = NULL;
}
}
#endif // !defined(IS_SIMARM_X64)
#endif // !defined(IS_SIMARM_HOST64)
}
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)

View file

@ -155,7 +155,7 @@ class DartInitializationState {
static DartInitializationState init_state_;
static void CheckOffsets() {
#if !defined(IS_SIMARM_X64)
#if !defined(IS_SIMARM_HOST64)
// These offsets are embedded in precompiled instructions. We need the
// compiler and the runtime to agree.
bool ok = true;
@ -241,7 +241,7 @@ static void CheckOffsets() {
#undef CHECK_CONSTANT
#undef CHECK_OFFSET
#undef CHECK_PAYLOAD_SIZEOF
#endif // !defined(IS_SIMARM_X64)
#endif // !defined(IS_SIMARM_HOST64)
}
char* Dart::DartInit(const Dart_InitializeParams* params) {

View file

@ -112,7 +112,7 @@ const intptr_t kDefaultNewGenSemiMaxSize = (kWordSize <= 4) ? 8 : 16;
#define SUPPORT_TIMELINE 1
#endif
#if defined(ARCH_IS_64_BIT) && !defined(IS_SIMARM_X64)
#if defined(ARCH_IS_64_BIT) && !defined(IS_SIMARM_HOST64)
#define HASH_IN_OBJECT_HEADER 1
#endif

View file

@ -67,61 +67,82 @@ def ToCommandLine(gn_args):
return [merge(x, y) for x, y in gn_args.items()]
# Runs true if the currently executing python interpreter is running under
# Rosetta. I.e., python3 is an x64 executable and we're on an arm64 Mac.
def IsRosetta():
if platform.system() == 'Darwin':
p = subprocess.Popen(['sysctl', '-in', 'sysctl.proc_translated'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
output, _ = p.communicate()
return output.decode('utf-8').strip() == '1'
return False
# The C compiler's host.
def HostCpuForArch(arch):
# Check for Rosetta before checking platform.machine(), as the latter
# returns 'x86_64' when running under Rosetta.
if IsRosetta():
if arch in ['x64', 'x64c']:
# Without this case, we would try to build with
# host_cpu="arm64"
# target_cpu="x64"
# dart_target_arch="x64"
# Which requires the VM to use an x64 simulator in the host
# arm64 binaries, and this simulator is unimplemented.
return 'x64'
else:
return 'arm64'
m = platform.machine()
if m == 'aarch64' or m == 'arm64':
return 'arm64'
if m == 'armv7l':
return 'arm'
if arch in ['ia32', 'arm', 'simarm', 'simarm_x64', 'riscv32', 'simriscv32']:
return 'x86'
if arch in [
'x64', 'arm64', 'simarm64', 'arm_x64', 'x64c', 'arm64c',
'simarm64c', 'riscv64', 'simriscv64'
]:
if arch.endswith('_x64'):
return 'x64'
if arch.endswith('_arm64'):
return 'arm64'
if arch.endswith('_riscv64'):
return 'riscv64'
# For each target architecture, we prefer in descending order
# - using the same architecture for the host (supports all architectures)
# - using a host architecture with the same word size (supports arm and riscv, which have simulators)
# - using a host architecture with a different word size (supports only AOT and only 32-bit target on 64-bit host)
if arch in ['ia32']:
candidates = ['x86']
elif arch in ['x64', 'x64c']:
candidates = ['x64']
elif arch in ['arm', 'simarm']:
candidates = ['arm', 'x86', 'riscv32', 'arm64', 'x64', 'riscv64']
elif arch in ['arm64', 'arm64c', 'simarm64', 'simarm64c']:
candidates = ['arm64', 'x64', 'riscv64']
elif arch in ['riscv32', 'simriscv32']:
candidates = ['riscv32', 'arm', 'x86', 'riscv64', 'arm64', 'x64']
elif arch in ['riscv64', 'simriscv64']:
candidates = ['riscv64', 'arm64', 'x64']
else:
raise Exception("Unknown Dart architecture: %s" % arch)
available = utils.HostArchitectures()
for candidate in candidates:
if candidate in available:
return candidate
raise Exception(
"Failed to find a C host architecture for %s. Need one of %s but only %s are available."
% (arch, candidates, available))
# The C compiler's target.
def TargetCpuForArch(arch, target_os):
if arch in ['ia32', 'simarm', 'simriscv32']:
# Real target architectures
if arch in ['ia32']:
return 'x86'
if arch in [
'x64', 'simarm64', 'simarm_x64', 'simriscv64', 'x64c', 'simarm64c'
]:
elif arch in ['x64', 'x64c']:
return 'x64'
if arch == 'arm_x64':
elif arch in ['arm', 'arm_x64', 'arm_arm64', 'arm_riscv64']:
return 'arm'
if arch == 'arm64c':
elif arch in ['arm64', 'arm64c']:
return 'arm64'
return arch
elif arch in ['riscv32', 'riscv32_x64', 'riscv32_arm64', 'riscv32_riscv64']:
return 'riscv32'
elif arch in ['riscv64']:
return 'riscv64'
# Simulators
if arch in ['simarm_x64', 'simriscv32_x64']:
return 'x64'
elif arch in ['simarm_arm64', 'simriscv32_arm64']:
return 'arm64'
elif arch in ['simarm_riscv64', 'simriscv32_riscv64']:
return 'riscv64'
elif arch in ['simarm', 'simriscv32']:
candidates = ['arm', 'riscv32', 'x86']
elif arch in ['simarm64', 'simarm64c', 'simriscv64']:
candidates = ['arm64', 'riscv64', 'x64']
else:
raise Exception("Unknown Dart architecture: %s" % arch)
available = utils.HostArchitectures()
for candidate in candidates:
if candidate in available:
return candidate
raise Exception(
"Failed to find a C target architecture for %s. Need one of %s but only %s are available."
% (arch, candidates, available))
# The Dart compiler's target.
@ -130,7 +151,10 @@ def DartTargetCpuForArch(arch):
return 'ia32'
if arch in ['x64', 'x64c']:
return 'x64'
if arch in ['arm', 'simarm', 'simarm_x64', 'arm_x64']:
if arch in [
'arm', 'simarm', 'simarm_x64', 'arm_x64', 'simarm_arm64',
'arm_arm64'
]:
return 'arm'
if arch in ['arm64', 'simarm64', 'arm64c', 'simarm64c']:
return 'arm64'

View file

@ -67,9 +67,11 @@ ARCH_FAMILY = {
'arm': 'arm',
'arm64': 'arm',
'arm_x64': 'arm',
'arm_arm64': 'arm',
'simarm': 'ia32',
'simarm64': 'ia32',
'simarm_x64': 'ia32',
'simarm_arm64': 'arm',
'x64c': 'ia32',
'arm64c': 'arm',
'simarm64c': 'ia32',
@ -149,27 +151,44 @@ def GuessOS():
return None
# Runs true if the currently executing python interpreter is running under
# Rosetta. I.e., python3 is an x64 executable and we're on an arm64 Mac.
def IsRosetta():
if platform.system() == 'Darwin':
p = subprocess.Popen(['sysctl', '-in', 'sysctl.proc_translated'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
output, _ = p.communicate()
return output.decode('utf-8').strip() == '1'
return False
# Returns the architectures that can run on the current machine.
def HostArchitectures():
m = platform.machine()
if platform.system() == 'Darwin':
if m == 'arm64' or IsRosetta():
# ARM64 Macs also support X64.
return ['arm64', 'x64']
if m == 'x86_64':
# X64 Macs no longer support IA32.
return ['x64']
else:
if m in ['aarch64', 'arm64', 'arm64e']:
return ['arm64']
if m in ['armv7l']:
return ['arm']
if m in ['i386', 'i686', 'ia32', 'x86']:
return ['x86', 'ia32']
if m in ['x64', 'x86-64', 'x86_64', 'AMD64']:
return ['x64', 'x86', 'ia32']
raise Exception('Failed to determine host architectures for %s %s',
platform.machine(), platform.system())
# Try to guess the host architecture.
def GuessArchitecture():
os_id = platform.machine()
if os_id.startswith('aarch64') or os_id == 'arm64':
return 'arm64'
elif os_id.startswith('arm'):
return 'arm'
elif '64' in os_id:
return 'x64'
elif (not os_id) or (not re.match('(x|i[3-6])86', os_id) is None):
return 'ia32'
elif os_id == 'i86pc':
return 'ia32'
guess_os = GuessOS()
print('Warning: Guessing architecture {} based on os {}\n'.format(
os_id, guess_os))
if guess_os == 'win32':
return 'ia32'
return None
return HostArchitectures()[0]
# Try to guess the number of cpus on this machine.
def GuessCpus():
@ -242,9 +261,13 @@ def ListDartArgCallback(option, value, parser):
def IsCrossBuild(target_os, arch):
host_arch = GuessArchitecture()
return ((GetArchFamily(host_arch) != GetArchFamily(arch)) or
(target_os != GuessOS()))
if (target_os not in [None, 'host']) and (target_os != GuessOS()):
return True
if arch.startswith('sim'):
return False
if arch in HostArchitectures():
return False
return True
def GetBuildConf(mode, arch, conf_os=None, sanitizer=None):
@ -253,9 +276,8 @@ def GetBuildConf(mode, arch, conf_os=None, sanitizer=None):
arch.upper())
# Ask for a cross build if the host and target architectures don't match.
host_arch = GuessArchitecture()
cross_build = ''
if GetArchFamily(host_arch) != GetArchFamily(arch):
if IsCrossBuild(conf_os, arch):
cross_build = 'X'
return '{}{}{}{}'.format(GetBuildMode(mode), GetBuildSanitizer(sanitizer),
cross_build, arch.upper())