Toolchain support for Android ARM64 targets (#14394)
diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle
index 55c0380..5c655f8 100644
--- a/packages/flutter_tools/gradle/flutter.gradle
+++ b/packages/flutter_tools/gradle/flutter.gradle
@@ -115,9 +115,14 @@
}
} else {
Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
- debugFlutterJar = baseEnginePath.resolve("android-arm").resolve("flutter.jar").toFile()
- profileFlutterJar = baseEnginePath.resolve("android-arm-profile").resolve("flutter.jar").toFile()
- releaseFlutterJar = baseEnginePath.resolve("android-arm-release").resolve("flutter.jar").toFile()
+ String targetArch = 'arm'
+ if (project.hasProperty('target-platform') &&
+ project.property('target-platform') == 'android-arm64') {
+ targetArch = 'arm64'
+ }
+ debugFlutterJar = baseEnginePath.resolve("android-${targetArch}").resolve("flutter.jar").toFile()
+ profileFlutterJar = baseEnginePath.resolve("android-${targetArch}-profile").resolve("flutter.jar").toFile()
+ releaseFlutterJar = baseEnginePath.resolve("android-${targetArch}-release").resolve("flutter.jar").toFile()
if (!debugFlutterJar.isFile()) {
project.exec {
executable flutterExecutable.absolutePath
@@ -273,6 +278,10 @@
if (project.hasProperty('prefer-shared-library')) {
preferSharedLibraryValue = project.property('prefer-shared-library')
}
+ String targetPlatformValue = null
+ if (project.hasProperty('target-platform')) {
+ targetPlatformValue = project.property('target-platform')
+ }
project.android.applicationVariants.all { variant ->
String flutterBuildMode = buildModeFor(variant.buildType)
@@ -297,6 +306,7 @@
previewDart2 previewDart2Value
strongMode strongModeValue
preferSharedLibrary preferSharedLibraryValue
+ targetPlatform targetPlatformValue
sourceDir project.file(project.flutter.source)
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}")
}
@@ -312,6 +322,7 @@
previewDart2 previewDart2Value
strongMode strongModeValue
preferSharedLibrary preferSharedLibraryValue
+ targetPlatform targetPlatformValue
sourceDir project.file(project.flutter.source)
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}")
extraFrontEndOptions extraFrontEndOptionsValue
@@ -349,6 +360,8 @@
Boolean strongMode
@Optional @Input
Boolean preferSharedLibrary
+ @Optional @Input
+ String targetPlatform
File sourceDir
File intermediateDir
@Optional @Input
@@ -400,6 +413,9 @@
if (preferSharedLibrary) {
args "--prefer-shared-library"
}
+ if (targetPlatform != null) {
+ args "--target-platform", "${targetPlatform}"
+ }
args "--${buildMode}"
}
}
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index 9c9cac6..aef3679 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -126,6 +126,9 @@
if (_platform == null) {
// http://developer.android.com/ndk/guides/abis.html (x86, armeabi-v7a, ...)
switch (await _getProperty('ro.product.cpu.abi')) {
+ case 'arm64-v8a':
+ _platform = TargetPlatform.android_arm64;
+ break;
case 'x86_64':
_platform = TargetPlatform.android_x64;
break;
@@ -355,16 +358,23 @@
if (!await _checkForSupportedAdbVersion() || !await _checkForSupportedAndroidVersion())
return new LaunchResult.failed();
- if (await targetPlatform != TargetPlatform.android_arm && !debuggingOptions.buildInfo.isDebug) {
+ final TargetPlatform devicePlatform = await targetPlatform;
+ if (!(devicePlatform == TargetPlatform.android_arm ||
+ devicePlatform == TargetPlatform.android_arm64) &&
+ !debuggingOptions.buildInfo.isDebug) {
printError('Profile and release builds are only supported on ARM targets.');
return new LaunchResult.failed();
}
+ BuildInfo buildInfo = debuggingOptions.buildInfo;
+ if (devicePlatform == TargetPlatform.android_arm64)
+ buildInfo = buildInfo.withTargetPlatform(TargetPlatform.android_arm64);
+
if (!prebuiltApplication) {
printTrace('Building APK');
await buildApk(
target: mainPath,
- buildInfo: debuggingOptions.buildInfo,
+ buildInfo: buildInfo,
);
// Package has been built, so we can get the updated application ID and
// activity name from the .apk.
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 8d8957a..e22bc8b 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -301,6 +301,8 @@
if (buildInfo.preferSharedLibrary && androidSdk.ndkCompiler != null) {
command.add('-Pprefer-shared-library=true');
}
+ if (buildInfo.targetPlatform == TargetPlatform.android_arm64)
+ command.add('-Ptarget-platform=android-arm64');
command.add(assembleTask);
final int exitCode = await runCommandAndStreamOutput(
diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart
index 14c0310..f734d7a 100644
--- a/packages/flutter_tools/lib/src/application_package.dart
+++ b/packages/flutter_tools/lib/src/application_package.dart
@@ -259,6 +259,7 @@
}) async {
switch (platform) {
case TargetPlatform.android_arm:
+ case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
return applicationBinary == null
@@ -287,6 +288,7 @@
Future<ApplicationPackage> getPackageForPlatform(TargetPlatform platform) async {
switch (platform) {
case TargetPlatform.android_arm:
+ case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
android ??= await AndroidApk.fromCurrentDirectory();
diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
index 3c4bfa3..bfe8963 100644
--- a/packages/flutter_tools/lib/src/artifacts.dart
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -97,6 +97,7 @@
platform ??= _currentHostPlatform;
switch (platform) {
case TargetPlatform.android_arm:
+ case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
return _getAndroidArtifactPath(artifact, platform, mode);
@@ -195,6 +196,7 @@
return fs.path.join(engineDir, platformName);
case TargetPlatform.ios:
case TargetPlatform.android_arm:
+ case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
assert(mode != null, 'Need to specify a build mode for platform $platform.');
diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart
index 63bf145..8ed2b77 100644
--- a/packages/flutter_tools/lib/src/build_info.dart
+++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -15,7 +15,8 @@
this.strongMode,
this.extraFrontEndOptions,
this.extraGenSnapshotOptions,
- this.preferSharedLibrary});
+ this.preferSharedLibrary,
+ this.targetPlatform});
final BuildMode mode;
/// Represents a custom Android product flavor or an Xcode scheme, null for
@@ -41,6 +42,9 @@
// Whether to prefer AOT compiling to a *so file.
final bool preferSharedLibrary;
+ /// Target platform for the build (e.g. android_arm versus android_arm64).
+ final TargetPlatform targetPlatform;
+
static const BuildInfo debug = const BuildInfo(BuildMode.debug, null);
static const BuildInfo profile = const BuildInfo(BuildMode.profile, null);
static const BuildInfo release = const BuildInfo(BuildMode.release, null);
@@ -64,6 +68,15 @@
bool get supportsEmulator => isEmulatorBuildMode(mode);
bool get supportsSimulator => isEmulatorBuildMode(mode);
String get modeName => getModeName(mode);
+
+ BuildInfo withTargetPlatform(TargetPlatform targetPlatform) =>
+ new BuildInfo(mode, flavor,
+ previewDart2: previewDart2,
+ strongMode: strongMode,
+ extraFrontEndOptions: extraFrontEndOptions,
+ extraGenSnapshotOptions: extraGenSnapshotOptions,
+ preferSharedLibrary: preferSharedLibrary,
+ targetPlatform: targetPlatform);
}
/// The type of build - `debug`, `profile`, or `release`.
@@ -114,6 +127,7 @@
enum TargetPlatform {
android_arm,
+ android_arm64,
android_x64,
android_x86,
ios,
@@ -127,6 +141,8 @@
switch (platform) {
case TargetPlatform.android_arm:
return 'android-arm';
+ case TargetPlatform.android_arm64:
+ return 'android-arm64';
case TargetPlatform.android_x64:
return 'android-x64';
case TargetPlatform.android_x86:
@@ -150,6 +166,8 @@
switch (platform) {
case 'android-arm':
return TargetPlatform.android_arm;
+ case 'android-arm64':
+ return TargetPlatform.android_arm64;
case 'android-x64':
return TargetPlatform.android_x64;
case 'android-x86':
diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart
index ba657bf..62083ac 100644
--- a/packages/flutter_tools/lib/src/cache.dart
+++ b/packages/flutter_tools/lib/src/cache.dart
@@ -394,6 +394,8 @@
<String>['linux-x64', 'dart-sdk-linux-x64.zip'],
<String>['android-arm-profile/linux-x64', 'android-arm-profile/linux-x64.zip'],
<String>['android-arm-release/linux-x64', 'android-arm-release/linux-x64.zip'],
+ <String>['android-arm64-profile/linux-x64', 'android-arm64-profile/linux-x64.zip'],
+ <String>['android-arm64-release/linux-x64', 'android-arm64-release/linux-x64.zip'],
];
List<List<String>> get _windowsBinaryDirs => <List<String>>[
@@ -409,6 +411,9 @@
<String>['android-arm', 'android-arm/artifacts.zip'],
<String>['android-arm-profile', 'android-arm-profile/artifacts.zip'],
<String>['android-arm-release', 'android-arm-release/artifacts.zip'],
+ <String>['android-arm64', 'android-arm64/artifacts.zip'],
+ <String>['android-arm64-profile', 'android-arm64-profile/artifacts.zip'],
+ <String>['android-arm64-release', 'android-arm64-release/artifacts.zip'],
];
List<List<String>> get _iosBinaryDirs => <List<String>>[
diff --git a/packages/flutter_tools/lib/src/commands/build_aot.dart b/packages/flutter_tools/lib/src/commands/build_aot.dart
index 9233bbf..dd60d4d 100644
--- a/packages/flutter_tools/lib/src/commands/build_aot.dart
+++ b/packages/flutter_tools/lib/src/commands/build_aot.dart
@@ -35,7 +35,7 @@
..addOption('output-dir', defaultsTo: getAotBuildDirectory())
..addOption('target-platform',
defaultsTo: 'android-arm',
- allowed: <String>['android-arm', 'ios']
+ allowed: <String>['android-arm', 'android-arm64', 'ios']
)
..addFlag('interpreter')
..addFlag('quiet', defaultsTo: false)
@@ -159,7 +159,9 @@
return null;
}
- if (platform != TargetPlatform.android_arm && platform != TargetPlatform.ios) {
+ if (!(platform == TargetPlatform.android_arm ||
+ platform == TargetPlatform.android_arm64 ||
+ platform == TargetPlatform.ios)) {
printError('${getNameForTargetPlatform(platform)} does not support AOT compilation.');
return null;
}
@@ -217,6 +219,7 @@
switch (platform) {
case TargetPlatform.android_arm:
+ case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
if (compileToSharedLibrary) {
@@ -287,6 +290,7 @@
switch (platform) {
case TargetPlatform.android_arm:
+ case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
if (compileToSharedLibrary) {
@@ -300,10 +304,12 @@
'--isolate_snapshot_instructions=$isolateSnapshotInstructions',
]);
}
- genSnapshotCmd.addAll(<String>[
- '--no-sim-use-hardfp', // Android uses the softfloat ABI.
- '--no-use-integer-division', // Not supported by the Pixel in 32-bit mode.
- ]);
+ if (platform == TargetPlatform.android_arm) {
+ genSnapshotCmd.addAll(<String>[
+ '--no-sim-use-hardfp', // Android uses the softfloat ABI.
+ '--no-use-integer-division', // Not supported by the Pixel in 32-bit mode.
+ ]);
+ }
break;
case TargetPlatform.ios:
if (interpreter) {
diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart
index 4636e48..67d8a18 100644
--- a/packages/flutter_tools/lib/src/commands/build_apk.dart
+++ b/packages/flutter_tools/lib/src/commands/build_apk.dart
@@ -18,7 +18,10 @@
..addFlag('preview-dart-2', negatable: false, hide: !verboseHelp)
..addFlag('strong', negatable: false, hide: !verboseHelp)
..addFlag('prefer-shared-library', negatable: false,
- help: 'Whether to prefer compiling to a *.so file (android only).');
+ help: 'Whether to prefer compiling to a *.so file (android only).')
+ ..addOption('target-platform',
+ defaultsTo: 'android-arm',
+ allowed: <String>['android-arm', 'android-arm64']);
}
@override
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index a7c520a..db64ccd 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -886,6 +886,7 @@
String getMissingPackageHintForPlatform(TargetPlatform platform) {
switch (platform) {
case TargetPlatform.android_arm:
+ case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
String manifest = 'android/AndroidManifest.xml';
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index f8962b3..3907599 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -185,7 +185,10 @@
: null,
preferSharedLibrary: argParser.options.containsKey('prefer-shared-library')
? argResults['prefer-shared-library']
- : false);
+ : false,
+ targetPlatform: argParser.options.containsKey('target-platform')
+ ? getTargetPlatformForName(argResults['target-platform'])
+ : null);
}
void setupApplicationPackages() {