Unverified Commit f8f7b899 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Revert "Generate ELF shared libraries and allow multi-abi libs in APKs and App...

Revert "Generate ELF shared libraries and allow multi-abi libs in APKs and App bundles (#33696)" (#34121)
parent 966b15b4
......@@ -5,7 +5,7 @@ homepage: https://github.com/flutter/flutter
environment:
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
sdk: ">=2.3.0 <3.0.0"
sdk: ">=2.2.2 <3.0.0"
dependencies:
args: 1.5.2
......
......@@ -388,27 +388,18 @@ class AndroidDevice extends Device {
if (!await _checkForSupportedAdbVersion() || !await _checkForSupportedAndroidVersion())
return LaunchResult.failed();
if (!debuggingOptions.buildInfo.isDebug &&
!debuggingOptions.buildInfo.isDynamic) {
printError('Profile and release builds are only supported.');
final TargetPlatform devicePlatform = await targetPlatform;
if (!(devicePlatform == TargetPlatform.android_arm ||
devicePlatform == TargetPlatform.android_arm64) &&
!(debuggingOptions.buildInfo.isDebug ||
debuggingOptions.buildInfo.isDynamic)) {
printError('Profile and release builds are only supported on ARM targets.');
return LaunchResult.failed();
}
final TargetPlatform devicePlatform = await targetPlatform;
AndroidArch androidArch;
switch (devicePlatform) {
case TargetPlatform.android_arm:
androidArch = AndroidArch.armeabi_v7a;
break;
case TargetPlatform.android_arm64:
androidArch = AndroidArch.arm64_v8a;
break;
default:
printError('ARM targets are only supported.');
return LaunchResult.failed();
}
BuildInfo buildInfo = debuggingOptions.buildInfo;
if (buildInfo.targetPlatform == null && devicePlatform == TargetPlatform.android_arm64)
buildInfo = buildInfo.withTargetPlatform(TargetPlatform.android_arm64);
if (!prebuiltApplication || androidSdk.licensesAvailable && androidSdk.latestVersion == null) {
printTrace('Building APK');
......@@ -416,9 +407,7 @@ class AndroidDevice extends Device {
await buildApk(
project: project,
target: mainPath,
androidBuildInfo: AndroidBuildInfo(debuggingOptions.buildInfo,
targetArchs: <AndroidArch>[androidArch]
),
buildInfo: buildInfo,
);
// Package has been built, so we can get the updated application ID and
// activity name from the .apk.
......
......@@ -16,7 +16,7 @@ import 'gradle.dart';
Future<void> buildApk({
@required FlutterProject project,
@required String target,
@required AndroidBuildInfo androidBuildInfo,
BuildInfo buildInfo = BuildInfo.debug,
}) async {
if (!project.android.isUsingGradle) {
throwToolExit(
......@@ -33,7 +33,7 @@ Future<void> buildApk({
await buildGradleProject(
project: project,
androidBuildInfo: androidBuildInfo,
buildInfo: buildInfo,
target: target,
isBuildingBundle: false,
);
......
......@@ -17,7 +17,7 @@ import 'gradle.dart';
Future<void> buildAppBundle({
@required FlutterProject project,
@required String target,
@required AndroidBuildInfo androidBuildInfo,
BuildInfo buildInfo = BuildInfo.debug,
}) async {
if (!project.android.isUsingGradle) {
throwToolExit(
......@@ -42,7 +42,7 @@ Future<void> buildAppBundle({
return buildGradleProject(
project: project,
androidBuildInfo: androidBuildInfo,
buildInfo: buildInfo,
target: target,
isBuildingBundle: true,
);
......
......@@ -15,7 +15,6 @@ import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
......@@ -319,7 +318,7 @@ void _exitIfNoAndroidSdk() {
Future<void> buildGradleProject({
@required FlutterProject project,
@required AndroidBuildInfo androidBuildInfo,
@required BuildInfo buildInfo,
@required String target,
@required bool isBuildingBundle,
}) async {
......@@ -331,7 +330,7 @@ Future<void> buildGradleProject({
// and can be overwritten with flutter build command.
// The default Gradle script reads the version name and number
// from the local.properties file.
updateLocalProperties(project: project, buildInfo: androidBuildInfo.buildInfo);
updateLocalProperties(project: project, buildInfo: buildInfo);
final String gradle = await _ensureGradle(project);
......@@ -343,7 +342,7 @@ Future<void> buildGradleProject({
case FlutterPluginVersion.managed:
// Fall through. Managed plugin builds the same way as plugin v2.
case FlutterPluginVersion.v2:
return _buildGradleProjectV2(project, gradle, androidBuildInfo, target, isBuildingBundle);
return _buildGradleProjectV2(project, gradle, buildInfo, target, isBuildingBundle);
}
}
......@@ -392,12 +391,11 @@ String _calculateSha(File file) {
Future<void> _buildGradleProjectV2(
FlutterProject flutterProject,
String gradle,
AndroidBuildInfo androidBuildInfo,
BuildInfo buildInfo,
String target,
bool isBuildingBundle,
) async {
final GradleProject project = await _gradleProject();
final BuildInfo buildInfo = androidBuildInfo.buildInfo;
String assembleTask;
......@@ -455,13 +453,12 @@ Future<void> _buildGradleProjectV2(
command.add('-Pfilesystem-roots=${buildInfo.fileSystemRoots.join('|')}');
if (buildInfo.fileSystemScheme != null)
command.add('-Pfilesystem-scheme=${buildInfo.fileSystemScheme}');
if (androidBuildInfo.splitPerAbi)
command.add('-Psplit-per-abi=true');
if (androidBuildInfo.targetArchs.isNotEmpty) {
final String targetPlatforms = androidBuildInfo.targetArchs
.map(getPlatformNameForAndroidArch).join(',');
command.add('-Ptarget-platform=$targetPlatforms');
if (buildInfo.buildSharedLibrary) {
command.add('-Pbuild-shared-library=true');
}
if (buildInfo.targetPlatform != null)
command.add('-Ptarget-platform=${getNameForTargetPlatform(buildInfo.targetPlatform)}');
command.add(assembleTask);
bool potentialAndroidXFailure = false;
final Stopwatch sw = Stopwatch()..start();
......@@ -511,27 +508,24 @@ Future<void> _buildGradleProjectV2(
flutterUsage.sendTiming('build', 'gradle-v2', Duration(milliseconds: sw.elapsedMilliseconds));
if (!isBuildingBundle) {
final Iterable<File> apkFiles = _findApkFiles(project, androidBuildInfo);
if (apkFiles.isEmpty)
final File apkFile = _findApkFile(project, buildInfo);
if (apkFile == null)
throwToolExit('Gradle build failed to produce an Android package.');
// Copy the first APK to app.apk, so `flutter run`, `flutter install`, etc. can find it.
// TODO(blasten): Handle multiple APKs.
apkFiles.first.copySync(project.apkDirectory.childFile('app.apk').path);
// Copy the APK to app.apk, so `flutter run`, `flutter install`, etc. can find it.
apkFile.copySync(project.apkDirectory.childFile('app.apk').path);
printTrace('calculateSha: ${project.apkDirectory}/app.apk');
final File apkShaFile = project.apkDirectory.childFile('app.apk.sha1');
apkShaFile.writeAsStringSync(_calculateSha(apkFiles.first));
apkShaFile.writeAsStringSync(_calculateSha(apkFile));
for (File apkFile in apkFiles) {
String appSize;
if (buildInfo.mode == BuildMode.debug) {
appSize = '';
} else {
appSize = ' (${getSizeAsMB(apkFile.lengthSync())})';
}
printStatus('Built ${fs.path.relative(apkFile.path)}$appSize.',
color: TerminalColor.green);
String appSize;
if (buildInfo.mode == BuildMode.debug) {
appSize = '';
} else {
appSize = ' (${getSizeAsMB(apkFile.lengthSync())})';
}
printStatus('Built ${fs.path.relative(apkFile.path)}$appSize.');
} else {
final File bundleFile = _findBundleFile(project, buildInfo);
if (bundleFile == null)
......@@ -543,38 +537,28 @@ Future<void> _buildGradleProjectV2(
} else {
appSize = ' (${getSizeAsMB(bundleFile.lengthSync())})';
}
printStatus('Built ${fs.path.relative(bundleFile.path)}$appSize.',
color: TerminalColor.green);
printStatus('Built ${fs.path.relative(bundleFile.path)}$appSize.');
}
}
Iterable<File> _findApkFiles(GradleProject project, AndroidBuildInfo androidBuildInfo) {
final Iterable<String> apkFileNames = project.apkFilesFor(androidBuildInfo);
if (apkFileNames.isEmpty)
return const <File>[];
return apkFileNames.map<File>((String apkFileName) {
File apkFile = project.apkDirectory.childFile(apkFileName);
if (apkFile.existsSync())
return apkFile;
final BuildInfo buildInfo = androidBuildInfo.buildInfo;
final String modeName = camelCase(buildInfo.modeName);
apkFile = project.apkDirectory
.childDirectory(modeName)
.childFile(apkFileName);
File _findApkFile(GradleProject project, BuildInfo buildInfo) {
final String apkFileName = project.apkFileFor(buildInfo);
if (apkFileName == null)
return null;
File apkFile = fs.file(fs.path.join(project.apkDirectory.path, apkFileName));
if (apkFile.existsSync())
return apkFile;
final String modeName = camelCase(buildInfo.modeName);
apkFile = fs.file(fs.path.join(project.apkDirectory.path, modeName, apkFileName));
if (apkFile.existsSync())
return apkFile;
if (buildInfo.flavor != null) {
// Android Studio Gradle plugin v3 adds flavor to path.
apkFile = fs.file(fs.path.join(project.apkDirectory.path, buildInfo.flavor, modeName, apkFileName));
if (apkFile.existsSync())
return apkFile;
if (buildInfo.flavor != null) {
// Android Studio Gradle plugin v3 adds flavor to path.
apkFile = project.apkDirectory
.childDirectory(buildInfo.flavor)
.childDirectory(modeName)
.childFile(apkFileName);
if (apkFile.existsSync())
return apkFile;
}
return null;
});
}
return null;
}
File _findBundleFile(GradleProject project, BuildInfo buildInfo) {
......@@ -583,12 +567,12 @@ File _findBundleFile(GradleProject project, BuildInfo buildInfo) {
if (bundleFileName == null)
return null;
final String modeName = camelCase(buildInfo.modeName);
File bundleFile = project.bundleDirectory.childDirectory(modeName).childFile(bundleFileName);
File bundleFile = fs.file(fs.path.join(project.bundleDirectory.path, modeName, bundleFileName));
if (bundleFile.existsSync())
return bundleFile;
if (buildInfo.flavor != null) {
// Android Studio Gradle plugin v3 adds the flavor to the path. For the bundle the folder name is the flavor plus the mode name.
bundleFile = project.bundleDirectory.childDirectory(buildInfo.flavor + modeName).childFile(bundleFileName);
bundleFile = fs.file(fs.path.join(project.bundleDirectory.path, buildInfo.flavor + modeName, bundleFileName));
if (bundleFile.existsSync())
return bundleFile;
}
......@@ -677,20 +661,13 @@ class GradleProject {
return 'assemble${toTitleCase(productFlavor)}${toTitleCase(buildType)}';
}
Iterable<String> apkFilesFor(AndroidBuildInfo androidBuildInfo) {
final String buildType = _buildTypeFor(androidBuildInfo.buildInfo);
final String productFlavor = _productFlavorFor(androidBuildInfo.buildInfo);
String apkFileFor(BuildInfo buildInfo) {
final String buildType = _buildTypeFor(buildInfo);
final String productFlavor = _productFlavorFor(buildInfo);
if (buildType == null || productFlavor == null)
return const <String>[];
return null;
final String flavorString = productFlavor.isEmpty ? '' : '-' + productFlavor;
if (androidBuildInfo.splitPerAbi) {
return androidBuildInfo.targetArchs.map<String>((AndroidArch arch) {
final String abi = getNameForAndroidArch(arch);
return 'app$flavorString-$abi-$buildType.apk';
});
}
return <String>['app$flavorString-$buildType.apk'];
return 'app$flavorString-$buildType.apk';
}
String bundleTaskFor(BuildInfo buildInfo) {
......
......@@ -137,7 +137,7 @@ class AOTSnapshotter {
final String aotSharedLibrary = fs.path.join(outputDir.path, 'app.so');
outputPaths.add(aotSharedLibrary);
genSnapshotArgs.add('--snapshot_kind=app-aot-elf');
genSnapshotArgs.add('--elf=$aotSharedLibrary');
genSnapshotArgs.add('--assembly=$aotSharedLibrary');
} else {
// Blob AOT snapshot.
final String vmSnapshotData = fs.path.join(outputDir.path, 'vm_snapshot_data');
......
......@@ -17,6 +17,8 @@ class BuildInfo {
this.compilationTraceFilePath,
this.extraFrontEndOptions,
this.extraGenSnapshotOptions,
this.buildSharedLibrary,
this.targetPlatform,
this.fileSystemRoots,
this.fileSystemScheme,
this.buildNumber,
......@@ -48,6 +50,12 @@ class BuildInfo {
/// Extra command-line options for gen_snapshot.
final String extraGenSnapshotOptions;
/// Whether to prefer AOT compiling to a *so file.
final bool buildSharedLibrary;
/// Target platform for the build (e.g. android_arm versus android_arm64).
final TargetPlatform targetPlatform;
/// Internal version number (not displayed to users).
/// Each build must have a unique number to differentiate it from previous builds.
/// It is used to determine whether one build is more recent than another, with higher numbers indicating more recent build.
......@@ -90,31 +98,15 @@ class BuildInfo {
bool get supportsSimulator => isEmulatorBuildMode(mode);
String get modeName => getModeName(mode);
String get friendlyModeName => getFriendlyModeName(mode);
}
/// Information about an Android build to be performed or used.
class AndroidBuildInfo {
const AndroidBuildInfo(
this.buildInfo, {
this.targetArchs = const <AndroidArch>[
AndroidArch.armeabi_v7a,
AndroidArch.arm64_v8a,
],
this.splitPerAbi = false,
});
// The build info containing the mode and flavor.
final BuildInfo buildInfo;
/// Whether to split the shared library per ABI.
///
/// When this is false, multiple ABIs will be contained within one primary
/// build artifact. When this is true, multiple build artifacts (one per ABI)
/// will be produced.
final bool splitPerAbi;
/// The target platforms for the build.
final Iterable<AndroidArch> targetArchs;
BuildInfo withTargetPlatform(TargetPlatform targetPlatform) =>
BuildInfo(mode, flavor,
trackWidgetCreation: trackWidgetCreation,
compilationTraceFilePath: compilationTraceFilePath,
extraFrontEndOptions: extraFrontEndOptions,
extraGenSnapshotOptions: extraGenSnapshotOptions,
buildSharedLibrary: buildSharedLibrary,
targetPlatform: targetPlatform);
}
/// The type of build.
......@@ -262,13 +254,6 @@ enum IOSArch {
arm64,
}
enum AndroidArch {
armeabi_v7a,
arm64_v8a,
x86,
x86_64,
}
/// The default set of iOS device architectures to build for.
const List<IOSArch> defaultIOSArchs = <IOSArch>[
IOSArch.arm64,
......@@ -350,51 +335,6 @@ TargetPlatform getTargetPlatformForName(String platform) {
return null;
}
AndroidArch getAndroidArchForName(String platform) {
switch (platform) {
case 'android-arm':
return AndroidArch.armeabi_v7a;
case 'android-arm64':
return AndroidArch.arm64_v8a;
case 'android-x64':
return AndroidArch.x86_64;
case 'android-x86':
return AndroidArch.x86;
}
assert(false);
return null;
}
String getNameForAndroidArch(AndroidArch arch) {
switch (arch) {
case AndroidArch.armeabi_v7a:
return 'armeabi-v7a';
case AndroidArch.arm64_v8a:
return 'arm64-v8a';
case AndroidArch.x86_64:
return 'x86_64';
case AndroidArch.x86:
return 'x86';
}
assert(false);
return null;
}
String getPlatformNameForAndroidArch(AndroidArch arch) {
switch (arch) {
case AndroidArch.armeabi_v7a:
return 'android-arm';
case AndroidArch.arm64_v8a:
return 'android-arm64';
case AndroidArch.x86_64:
return 'android-x64';
case AndroidArch.x86:
return 'android-x86';
}
assert(false);
return null;
}
HostPlatform getCurrentHostPlatform() {
if (platform.isMacOS)
return HostPlatform.darwin_x64;
......
......@@ -5,9 +5,6 @@
import 'dart:async';
import '../android/apk.dart';
import '../base/terminal.dart';
import '../build_info.dart';
import '../globals.dart';
import '../project.dart';
import '../runner/flutter_command.dart' show DevelopmentArtifact, FlutterCommandResult;
import 'build.dart';
......@@ -24,14 +21,12 @@ class BuildApkCommand extends BuildSubCommand {
argParser
..addFlag('track-widget-creation', negatable: false, hide: !verboseHelp)
..addFlag('split-per-abi',
..addFlag('build-shared-library',
negatable: false,
help: 'Whether to split the APKs per ABIs.'
'To learn more, see: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split',
help: 'Whether to prefer compiling to a *.so file (android only).',
)
..addMultiOption('target-platform',
splitCommas: true,
defaultsTo: <String>['android-arm', 'android-arm64'],
..addOption('target-platform',
defaultsTo: 'android-arm',
allowed: <String>['android-arm', 'android-arm64', 'android-x86', 'android-x64'],
help: 'The target platform for which the app is compiled.',
);
......@@ -54,33 +49,10 @@ class BuildApkCommand extends BuildSubCommand {
@override
Future<FlutterCommandResult> runCommand() async {
final BuildInfo buildInfo = getBuildInfo();
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(buildInfo,
splitPerAbi: argResults['split-per-abi'],
targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName)
);
if (buildInfo.isRelease && !androidBuildInfo.splitPerAbi && androidBuildInfo.targetArchs.length > 1) {
final String targetPlatforms = argResults['target-platform'].join(', ');
printStatus('You are building a fat APK that includes binaries for '
'$targetPlatforms.', emphasis: true, color: TerminalColor.green);
printStatus('If you are deploying the app to the Play Store, '
'it\'s recommended to use app bundles or split the APK to reduce the APK size.', emphasis: true);
printStatus('To generate an app bundle, run:', emphasis: true, indent: 4);
printStatus('flutter build appbundle '
'--target-platform ${targetPlatforms.replaceAll(' ', '')}',indent: 8);
printStatus('Learn more on: https://developer.android.com/guide/app-bundle',indent: 8);
printStatus('To split the APKs per ABI, run:', emphasis: true, indent: 4);
printStatus('flutter build apk '
'--target-platform ${targetPlatforms.replaceAll(' ', '')} '
'--split-per-abi', indent: 8);
printStatus('Learn more on: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split',indent: 8);
}
await buildApk(
project: FlutterProject.current(),
target: targetFile,
androidBuildInfo: androidBuildInfo,
buildInfo: getBuildInfo(),
);
return null;
}
......
......@@ -5,7 +5,6 @@
import 'dart:async';
import '../android/app_bundle.dart';
import '../build_info.dart';
import '../project.dart';
import '../runner/flutter_command.dart' show FlutterCommandResult;
import 'build.dart';
......@@ -21,11 +20,18 @@ class BuildAppBundleCommand extends BuildSubCommand {
argParser
..addFlag('track-widget-creation', negatable: false, hide: !verboseHelp)
..addMultiOption('target-platform',
splitCommas: true,
defaultsTo: <String>['android-arm', 'android-arm64'],
..addFlag(
'build-shared-library',
negatable: false,
help: 'Whether to prefer compiling to a *.so file (android only).',
)
..addOption(
'target-platform',
allowed: <String>['android-arm', 'android-arm64'],
help: 'The target platform for which the app is compiled.',
help: 'The target platform for which the app is compiled.\n'
'By default, the bundle will include \'arm\' and \'arm64\', '
'which is the recommended configuration for app bundles.\n'
'For more, see https://developer.android.com/distribute/best-practices/develop/64-bit',
);
}
......@@ -41,13 +47,10 @@ class BuildAppBundleCommand extends BuildSubCommand {
@override
Future<FlutterCommandResult> runCommand() async {
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(),
targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName)
);
await buildAppBundle(
project: FlutterProject.current(),
target: targetFile,
androidBuildInfo: androidBuildInfo,
buildInfo: getBuildInfo(),
);
return null;
}
......
......@@ -387,7 +387,8 @@ class IOSSimulator extends Device {
final BuildInfo debugBuildInfo = BuildInfo(BuildMode.debug, buildInfo.flavor,
trackWidgetCreation: buildInfo.trackWidgetCreation,
extraFrontEndOptions: buildInfo.extraFrontEndOptions,
extraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions);
extraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions,
buildSharedLibrary: buildInfo.buildSharedLibrary);
final XcodeBuildResult buildResult = await buildXcodeProject(
app: app,
......
......@@ -320,6 +320,12 @@ abstract class FlutterCommand extends Command<void> {
}
BuildInfo getBuildInfo() {
TargetPlatform targetPlatform;
if (argParser.options.containsKey('target-platform') &&
argResults['target-platform'] != 'default') {
targetPlatform = getTargetPlatformForName(argResults['target-platform']);
}
final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation')
? argResults['track-widget-creation']
: false;
......@@ -356,6 +362,10 @@ abstract class FlutterCommand extends Command<void> {
extraGenSnapshotOptions: argParser.options.containsKey(FlutterOptions.kExtraGenSnapshotOptions)
? argResults[FlutterOptions.kExtraGenSnapshotOptions]
: null,
buildSharedLibrary: argParser.options.containsKey('build-shared-library')
? argResults['build-shared-library']
: false,
targetPlatform: targetPlatform,
fileSystemRoots: argParser.options.containsKey(FlutterOptions.kFileSystemRoot)
? argResults[FlutterOptions.kFileSystemRoot] : null,
fileSystemScheme: argParser.options.containsKey(FlutterOptions.kFileSystemScheme)
......
......@@ -157,102 +157,16 @@ someOtherTask
});
test('should provide apk file name for default build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.apkFilesFor(const AndroidBuildInfo(BuildInfo.debug)).first, 'app-debug.apk');
expect(project.apkFilesFor(const AndroidBuildInfo(BuildInfo.profile)).first, 'app-profile.apk');
expect(project.apkFilesFor(const AndroidBuildInfo(BuildInfo.release)).first, 'app-release.apk');
expect(project.apkFilesFor(const AndroidBuildInfo(BuildInfo(BuildMode.release, 'unknown'))).isEmpty, isTrue);
expect(project.apkFileFor(BuildInfo.debug), 'app-debug.apk');
expect(project.apkFileFor(BuildInfo.profile), 'app-profile.apk');
expect(project.apkFileFor(BuildInfo.release), 'app-release.apk');
expect(project.apkFileFor(const BuildInfo(BuildMode.release, 'unknown')), isNull);
});
test('should provide apk file name for flavored build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>['free', 'paid'], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.apkFilesFor(const AndroidBuildInfo(BuildInfo(BuildMode.debug, 'free'))).first, 'app-free-debug.apk');
expect(project.apkFilesFor(const AndroidBuildInfo(BuildInfo(BuildMode.release, 'paid'))).first, 'app-paid-release.apk');
expect(project.apkFilesFor(const AndroidBuildInfo(BuildInfo(BuildMode.release, 'unknown'))).isEmpty, isTrue);
});
test('should provide apks for default build types and each ABI', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.apkFilesFor(
const AndroidBuildInfo(
BuildInfo.debug,
splitPerAbi: true,
targetArchs: <AndroidArch>[
AndroidArch.armeabi_v7a,
AndroidArch.arm64_v8a,
]
)
),
<String>[
'app-armeabi-v7a-debug.apk',
'app-arm64-v8a-debug.apk',
]);
expect(project.apkFilesFor(
const AndroidBuildInfo(
BuildInfo.release,
splitPerAbi: true,
targetArchs: <AndroidArch>[
AndroidArch.armeabi_v7a,
AndroidArch.arm64_v8a,
]
)
),
<String>[
'app-armeabi-v7a-release.apk',
'app-arm64-v8a-release.apk',
]);
expect(project.apkFilesFor(
const AndroidBuildInfo(
BuildInfo(BuildMode.release, 'unknown'),
splitPerAbi: true,
targetArchs: <AndroidArch>[
AndroidArch.armeabi_v7a,
AndroidArch.arm64_v8a,
]
)
).isEmpty, isTrue);
});
test('should provide apks for each ABI and flavored build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>['free', 'paid'], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.apkFilesFor(
const AndroidBuildInfo(
BuildInfo(BuildMode.debug, 'free'),
splitPerAbi: true,
targetArchs: <AndroidArch>[
AndroidArch.armeabi_v7a,
AndroidArch.arm64_v8a,
]
)
),
<String>[
'app-free-armeabi-v7a-debug.apk',
'app-free-arm64-v8a-debug.apk',
]);
expect(project.apkFilesFor(
const AndroidBuildInfo(
BuildInfo(BuildMode.release, 'paid'),
splitPerAbi: true,
targetArchs: <AndroidArch>[
AndroidArch.armeabi_v7a,
AndroidArch.arm64_v8a,
]
)
),
<String>[
'app-paid-armeabi-v7a-release.apk',
'app-paid-arm64-v8a-release.apk',
]);
expect(project.apkFilesFor(
const AndroidBuildInfo(
BuildInfo(BuildMode.release, 'unknown'),
splitPerAbi: true,
targetArchs: <AndroidArch>[
AndroidArch.armeabi_v7a,
AndroidArch.arm64_v8a,
]
)
).isEmpty, isTrue);
expect(project.apkFileFor(const BuildInfo(BuildMode.debug, 'free')), 'app-free-debug.apk');
expect(project.apkFileFor(const BuildInfo(BuildMode.release, 'paid')), 'app-paid-release.apk');
expect(project.apkFileFor(const BuildInfo(BuildMode.release, 'unknown')), isNull);
});
test('should provide bundle file name for default build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'),fs.directory('/some/dir'));
......
......@@ -80,7 +80,7 @@ void main() {
});
});
group('Snapshotter - AOT', () {
group('Snapshotter - iOS AOT', () {
const String kSnapshotDart = 'snapshot.dart';
String skyEnginePath;
......@@ -395,43 +395,13 @@ void main() {
]);
}, overrides: contextOverrides);
testUsingContext('builds shared library for android-arm', () async {
fs.file('main.dill').writeAsStringSync('binary magic');
testUsingContext('returns failure if buildSharedLibrary is true but no NDK is found', () async {
final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true);
final int genSnapshotExitCode = await snapshotter.build(
platform: TargetPlatform.android_arm,
buildMode: BuildMode.release,
mainPath: 'main.dill',
packagesPath: '.packages',
outputPath: outputPath,
buildSharedLibrary: true,
);
expect(genSnapshotExitCode, 0);
expect(genSnapshot.callCount, 1);
expect(genSnapshot.snapshotType.platform, TargetPlatform.android_arm);
expect(genSnapshot.snapshotType.mode, BuildMode.release);
expect(genSnapshot.additionalArgs, <String>[
'--deterministic',
'--snapshot_kind=app-aot-elf',
'--elf=build/foo/app.so',
'--no-sim-use-hardfp',
'--no-use-integer-division',
'main.dill',
]);
}, overrides: contextOverrides);
testUsingContext('builds shared library for android-arm64', () async {
fs.file('main.dill').writeAsStringSync('binary magic');
final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true);
when(mockAndroidSdk.ndk).thenReturn(null);
final int genSnapshotExitCode = await snapshotter.build(
platform: TargetPlatform.android_arm64,
platform: TargetPlatform.android_arm,
buildMode: BuildMode.release,
mainPath: 'main.dill',
packagesPath: '.packages',
......@@ -439,16 +409,8 @@ void main() {
buildSharedLibrary: true,
);
expect(genSnapshotExitCode, 0);
expect(genSnapshot.callCount, 1);
expect(genSnapshot.snapshotType.platform, TargetPlatform.android_arm64);
expect(genSnapshot.snapshotType.mode, BuildMode.release);
expect(genSnapshot.additionalArgs, <String>[
'--deterministic',
'--snapshot_kind=app-aot-elf',
'--elf=build/foo/app.so',
'main.dill',
]);
expect(genSnapshotExitCode, isNot(0));
expect(genSnapshot.callCount, 0);
}, overrides: contextOverrides);
testUsingContext('builds Android arm release AOT snapshot', () async {
......
......@@ -286,7 +286,7 @@ Information about project "Runner":
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null);
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, targetPlatform: TargetPlatform.ios);
final FlutterProject project = FlutterProject.fromPath('path/to/project');
await updateGeneratedXcodeProperties(
project: project,
......@@ -304,7 +304,7 @@ Information about project "Runner":
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, trackWidgetCreation: true);
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, trackWidgetCreation: true, targetPlatform: TargetPlatform.ios);
final FlutterProject project = FlutterProject.fromPath('path/to/project');
await updateGeneratedXcodeProperties(
project: project,
......@@ -322,7 +322,7 @@ Information about project "Runner":
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile_arm'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null);
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, targetPlatform: TargetPlatform.ios);
final FlutterProject project = FlutterProject.fromPath('path/to/project');
await updateGeneratedXcodeProperties(
project: project,
......@@ -340,7 +340,7 @@ Information about project "Runner":
when(mockArtifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: anyNamed('mode'))).thenReturn('engine');
when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'ios_profile'));
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null);
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, targetPlatform: TargetPlatform.ios);
final FlutterProject project = FlutterProject.fromPath('path/to/project');
await updateGeneratedXcodeProperties(
......
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