Unverified Commit d5149d44 authored by Jason Simmons's avatar Jason Simmons Committed by GitHub

Toolchain support for Android ARM64 targets (#14394)

parent 26102c91
...@@ -115,9 +115,14 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -115,9 +115,14 @@ class FlutterPlugin implements Plugin<Project> {
} }
} else { } else {
Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine") Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
debugFlutterJar = baseEnginePath.resolve("android-arm").resolve("flutter.jar").toFile() String targetArch = 'arm'
profileFlutterJar = baseEnginePath.resolve("android-arm-profile").resolve("flutter.jar").toFile() if (project.hasProperty('target-platform') &&
releaseFlutterJar = baseEnginePath.resolve("android-arm-release").resolve("flutter.jar").toFile() 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()) { if (!debugFlutterJar.isFile()) {
project.exec { project.exec {
executable flutterExecutable.absolutePath executable flutterExecutable.absolutePath
...@@ -273,6 +278,10 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -273,6 +278,10 @@ class FlutterPlugin implements Plugin<Project> {
if (project.hasProperty('prefer-shared-library')) { if (project.hasProperty('prefer-shared-library')) {
preferSharedLibraryValue = project.property('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 -> project.android.applicationVariants.all { variant ->
String flutterBuildMode = buildModeFor(variant.buildType) String flutterBuildMode = buildModeFor(variant.buildType)
...@@ -297,6 +306,7 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -297,6 +306,7 @@ class FlutterPlugin implements Plugin<Project> {
previewDart2 previewDart2Value previewDart2 previewDart2Value
strongMode strongModeValue strongMode strongModeValue
preferSharedLibrary preferSharedLibraryValue preferSharedLibrary preferSharedLibraryValue
targetPlatform targetPlatformValue
sourceDir project.file(project.flutter.source) sourceDir project.file(project.flutter.source)
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}") intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}")
} }
...@@ -312,6 +322,7 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -312,6 +322,7 @@ class FlutterPlugin implements Plugin<Project> {
previewDart2 previewDart2Value previewDart2 previewDart2Value
strongMode strongModeValue strongMode strongModeValue
preferSharedLibrary preferSharedLibraryValue preferSharedLibrary preferSharedLibraryValue
targetPlatform targetPlatformValue
sourceDir project.file(project.flutter.source) sourceDir project.file(project.flutter.source)
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}") intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}")
extraFrontEndOptions extraFrontEndOptionsValue extraFrontEndOptions extraFrontEndOptionsValue
...@@ -349,6 +360,8 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -349,6 +360,8 @@ abstract class BaseFlutterTask extends DefaultTask {
Boolean strongMode Boolean strongMode
@Optional @Input @Optional @Input
Boolean preferSharedLibrary Boolean preferSharedLibrary
@Optional @Input
String targetPlatform
File sourceDir File sourceDir
File intermediateDir File intermediateDir
@Optional @Input @Optional @Input
...@@ -400,6 +413,9 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -400,6 +413,9 @@ abstract class BaseFlutterTask extends DefaultTask {
if (preferSharedLibrary) { if (preferSharedLibrary) {
args "--prefer-shared-library" args "--prefer-shared-library"
} }
if (targetPlatform != null) {
args "--target-platform", "${targetPlatform}"
}
args "--${buildMode}" args "--${buildMode}"
} }
} }
......
...@@ -126,6 +126,9 @@ class AndroidDevice extends Device { ...@@ -126,6 +126,9 @@ class AndroidDevice extends Device {
if (_platform == null) { if (_platform == null) {
// http://developer.android.com/ndk/guides/abis.html (x86, armeabi-v7a, ...) // http://developer.android.com/ndk/guides/abis.html (x86, armeabi-v7a, ...)
switch (await _getProperty('ro.product.cpu.abi')) { switch (await _getProperty('ro.product.cpu.abi')) {
case 'arm64-v8a':
_platform = TargetPlatform.android_arm64;
break;
case 'x86_64': case 'x86_64':
_platform = TargetPlatform.android_x64; _platform = TargetPlatform.android_x64;
break; break;
...@@ -355,16 +358,23 @@ class AndroidDevice extends Device { ...@@ -355,16 +358,23 @@ class AndroidDevice extends Device {
if (!await _checkForSupportedAdbVersion() || !await _checkForSupportedAndroidVersion()) if (!await _checkForSupportedAdbVersion() || !await _checkForSupportedAndroidVersion())
return new LaunchResult.failed(); 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.'); printError('Profile and release builds are only supported on ARM targets.');
return new LaunchResult.failed(); return new LaunchResult.failed();
} }
BuildInfo buildInfo = debuggingOptions.buildInfo;
if (devicePlatform == TargetPlatform.android_arm64)
buildInfo = buildInfo.withTargetPlatform(TargetPlatform.android_arm64);
if (!prebuiltApplication) { if (!prebuiltApplication) {
printTrace('Building APK'); printTrace('Building APK');
await buildApk( await buildApk(
target: mainPath, target: mainPath,
buildInfo: debuggingOptions.buildInfo, buildInfo: buildInfo,
); );
// Package has been built, so we can get the updated application ID and // Package has been built, so we can get the updated application ID and
// activity name from the .apk. // activity name from the .apk.
......
...@@ -301,6 +301,8 @@ Future<Null> _buildGradleProjectV2(String gradle, BuildInfo buildInfo, String ta ...@@ -301,6 +301,8 @@ Future<Null> _buildGradleProjectV2(String gradle, BuildInfo buildInfo, String ta
if (buildInfo.preferSharedLibrary && androidSdk.ndkCompiler != null) { if (buildInfo.preferSharedLibrary && androidSdk.ndkCompiler != null) {
command.add('-Pprefer-shared-library=true'); command.add('-Pprefer-shared-library=true');
} }
if (buildInfo.targetPlatform == TargetPlatform.android_arm64)
command.add('-Ptarget-platform=android-arm64');
command.add(assembleTask); command.add(assembleTask);
final int exitCode = await runCommandAndStreamOutput( final int exitCode = await runCommandAndStreamOutput(
......
...@@ -259,6 +259,7 @@ Future<ApplicationPackage> getApplicationPackageForPlatform(TargetPlatform platf ...@@ -259,6 +259,7 @@ Future<ApplicationPackage> getApplicationPackageForPlatform(TargetPlatform platf
}) async { }) async {
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
return applicationBinary == null return applicationBinary == null
...@@ -287,6 +288,7 @@ class ApplicationPackageStore { ...@@ -287,6 +288,7 @@ class ApplicationPackageStore {
Future<ApplicationPackage> getPackageForPlatform(TargetPlatform platform) async { Future<ApplicationPackage> getPackageForPlatform(TargetPlatform platform) async {
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
android ??= await AndroidApk.fromCurrentDirectory(); android ??= await AndroidApk.fromCurrentDirectory();
......
...@@ -97,6 +97,7 @@ class CachedArtifacts extends Artifacts { ...@@ -97,6 +97,7 @@ class CachedArtifacts extends Artifacts {
platform ??= _currentHostPlatform; platform ??= _currentHostPlatform;
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
return _getAndroidArtifactPath(artifact, platform, mode); return _getAndroidArtifactPath(artifact, platform, mode);
...@@ -195,6 +196,7 @@ class CachedArtifacts extends Artifacts { ...@@ -195,6 +196,7 @@ class CachedArtifacts extends Artifacts {
return fs.path.join(engineDir, platformName); return fs.path.join(engineDir, platformName);
case TargetPlatform.ios: case TargetPlatform.ios:
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
assert(mode != null, 'Need to specify a build mode for platform $platform.'); assert(mode != null, 'Need to specify a build mode for platform $platform.');
......
...@@ -15,7 +15,8 @@ class BuildInfo { ...@@ -15,7 +15,8 @@ class BuildInfo {
this.strongMode, this.strongMode,
this.extraFrontEndOptions, this.extraFrontEndOptions,
this.extraGenSnapshotOptions, this.extraGenSnapshotOptions,
this.preferSharedLibrary}); this.preferSharedLibrary,
this.targetPlatform});
final BuildMode mode; final BuildMode mode;
/// Represents a custom Android product flavor or an Xcode scheme, null for /// Represents a custom Android product flavor or an Xcode scheme, null for
...@@ -41,6 +42,9 @@ class BuildInfo { ...@@ -41,6 +42,9 @@ class BuildInfo {
// Whether to prefer AOT compiling to a *so file. // Whether to prefer AOT compiling to a *so file.
final bool preferSharedLibrary; 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 debug = const BuildInfo(BuildMode.debug, null);
static const BuildInfo profile = const BuildInfo(BuildMode.profile, null); static const BuildInfo profile = const BuildInfo(BuildMode.profile, null);
static const BuildInfo release = const BuildInfo(BuildMode.release, null); static const BuildInfo release = const BuildInfo(BuildMode.release, null);
...@@ -64,6 +68,15 @@ class BuildInfo { ...@@ -64,6 +68,15 @@ class BuildInfo {
bool get supportsEmulator => isEmulatorBuildMode(mode); bool get supportsEmulator => isEmulatorBuildMode(mode);
bool get supportsSimulator => isEmulatorBuildMode(mode); bool get supportsSimulator => isEmulatorBuildMode(mode);
String get modeName => getModeName(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`. /// The type of build - `debug`, `profile`, or `release`.
...@@ -114,6 +127,7 @@ String getNameForHostPlatform(HostPlatform platform) { ...@@ -114,6 +127,7 @@ String getNameForHostPlatform(HostPlatform platform) {
enum TargetPlatform { enum TargetPlatform {
android_arm, android_arm,
android_arm64,
android_x64, android_x64,
android_x86, android_x86,
ios, ios,
...@@ -127,6 +141,8 @@ String getNameForTargetPlatform(TargetPlatform platform) { ...@@ -127,6 +141,8 @@ String getNameForTargetPlatform(TargetPlatform platform) {
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
return 'android-arm'; return 'android-arm';
case TargetPlatform.android_arm64:
return 'android-arm64';
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
return 'android-x64'; return 'android-x64';
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
...@@ -150,6 +166,8 @@ TargetPlatform getTargetPlatformForName(String platform) { ...@@ -150,6 +166,8 @@ TargetPlatform getTargetPlatformForName(String platform) {
switch (platform) { switch (platform) {
case 'android-arm': case 'android-arm':
return TargetPlatform.android_arm; return TargetPlatform.android_arm;
case 'android-arm64':
return TargetPlatform.android_arm64;
case 'android-x64': case 'android-x64':
return TargetPlatform.android_x64; return TargetPlatform.android_x64;
case 'android-x86': case 'android-x86':
......
...@@ -394,6 +394,8 @@ class FlutterEngine extends CachedArtifact { ...@@ -394,6 +394,8 @@ class FlutterEngine extends CachedArtifact {
<String>['linux-x64', 'dart-sdk-linux-x64.zip'], <String>['linux-x64', 'dart-sdk-linux-x64.zip'],
<String>['android-arm-profile/linux-x64', 'android-arm-profile/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-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>>[ List<List<String>> get _windowsBinaryDirs => <List<String>>[
...@@ -409,6 +411,9 @@ class FlutterEngine extends CachedArtifact { ...@@ -409,6 +411,9 @@ class FlutterEngine extends CachedArtifact {
<String>['android-arm', 'android-arm/artifacts.zip'], <String>['android-arm', 'android-arm/artifacts.zip'],
<String>['android-arm-profile', 'android-arm-profile/artifacts.zip'], <String>['android-arm-profile', 'android-arm-profile/artifacts.zip'],
<String>['android-arm-release', 'android-arm-release/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>>[ List<List<String>> get _iosBinaryDirs => <List<String>>[
......
...@@ -35,7 +35,7 @@ class BuildAotCommand extends BuildSubCommand { ...@@ -35,7 +35,7 @@ class BuildAotCommand extends BuildSubCommand {
..addOption('output-dir', defaultsTo: getAotBuildDirectory()) ..addOption('output-dir', defaultsTo: getAotBuildDirectory())
..addOption('target-platform', ..addOption('target-platform',
defaultsTo: 'android-arm', defaultsTo: 'android-arm',
allowed: <String>['android-arm', 'ios'] allowed: <String>['android-arm', 'android-arm64', 'ios']
) )
..addFlag('interpreter') ..addFlag('interpreter')
..addFlag('quiet', defaultsTo: false) ..addFlag('quiet', defaultsTo: false)
...@@ -159,7 +159,9 @@ Future<String> _buildAotSnapshot( ...@@ -159,7 +159,9 @@ Future<String> _buildAotSnapshot(
return null; 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.'); printError('${getNameForTargetPlatform(platform)} does not support AOT compilation.');
return null; return null;
} }
...@@ -217,6 +219,7 @@ Future<String> _buildAotSnapshot( ...@@ -217,6 +219,7 @@ Future<String> _buildAotSnapshot(
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
if (compileToSharedLibrary) { if (compileToSharedLibrary) {
...@@ -287,6 +290,7 @@ Future<String> _buildAotSnapshot( ...@@ -287,6 +290,7 @@ Future<String> _buildAotSnapshot(
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
if (compileToSharedLibrary) { if (compileToSharedLibrary) {
...@@ -300,10 +304,12 @@ Future<String> _buildAotSnapshot( ...@@ -300,10 +304,12 @@ Future<String> _buildAotSnapshot(
'--isolate_snapshot_instructions=$isolateSnapshotInstructions', '--isolate_snapshot_instructions=$isolateSnapshotInstructions',
]); ]);
} }
genSnapshotCmd.addAll(<String>[ if (platform == TargetPlatform.android_arm) {
'--no-sim-use-hardfp', // Android uses the softfloat ABI. genSnapshotCmd.addAll(<String>[
'--no-use-integer-division', // Not supported by the Pixel in 32-bit mode. '--no-sim-use-hardfp', // Android uses the softfloat ABI.
]); '--no-use-integer-division', // Not supported by the Pixel in 32-bit mode.
]);
}
break; break;
case TargetPlatform.ios: case TargetPlatform.ios:
if (interpreter) { if (interpreter) {
......
...@@ -18,7 +18,10 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -18,7 +18,10 @@ class BuildApkCommand extends BuildSubCommand {
..addFlag('preview-dart-2', negatable: false, hide: !verboseHelp) ..addFlag('preview-dart-2', negatable: false, hide: !verboseHelp)
..addFlag('strong', negatable: false, hide: !verboseHelp) ..addFlag('strong', negatable: false, hide: !verboseHelp)
..addFlag('prefer-shared-library', negatable: false, ..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 @override
......
...@@ -886,6 +886,7 @@ String findMainDartFile([String target]) { ...@@ -886,6 +886,7 @@ String findMainDartFile([String target]) {
String getMissingPackageHintForPlatform(TargetPlatform platform) { String getMissingPackageHintForPlatform(TargetPlatform platform) {
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
String manifest = 'android/AndroidManifest.xml'; String manifest = 'android/AndroidManifest.xml';
......
...@@ -185,7 +185,10 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -185,7 +185,10 @@ abstract class FlutterCommand extends Command<Null> {
: null, : null,
preferSharedLibrary: argParser.options.containsKey('prefer-shared-library') preferSharedLibrary: argParser.options.containsKey('prefer-shared-library')
? argResults['prefer-shared-library'] ? argResults['prefer-shared-library']
: false); : false,
targetPlatform: argParser.options.containsKey('target-platform')
? getTargetPlatformForName(argResults['target-platform'])
: null);
} }
void setupApplicationPackages() { void setupApplicationPackages() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment