Revert "Generate ELF shared libraries and allow multi-abi libs in APKs and App bundles (#33696)" (#34121)
diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle index 66530cb..c06edba 100644 --- a/packages/flutter_tools/gradle/flutter.gradle +++ b/packages/flutter_tools/gradle/flutter.gradle
@@ -2,7 +2,6 @@ import java.nio.file.Paths import com.android.builder.model.AndroidProject -import com.android.build.OutputFile import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.api.DefaultTask import org.gradle.api.GradleException @@ -37,49 +36,6 @@ apply plugin: FlutterPlugin class FlutterPlugin implements Plugin<Project> { - // The platforms that can be passed to the `--Ptarget-platform` flag. - private static final String PLATFORM_ARM32 = "android-arm"; - private static final String PLATFORM_ARM64 = "android-arm64"; - private static final String PLATFORM_X86 = "android-x86"; - private static final String PLATFORM_X86_64 = "android-x64"; - - // The ABI architectures. - private static final String ARCH_ARM32 = "armeabi-v7a"; - private static final String ARCH_ARM64 = "arm64-v8a"; - private static final String ARCH_X86 = "x86"; - private static final String ARCH_X86_64 = "x86_64"; - - // Maps platforms to ABI architectures. - private static final Map PLATFORM_ARCH_MAP = [ - (PLATFORM_ARM32) : ARCH_ARM32, - (PLATFORM_ARM64) : ARCH_ARM64, - (PLATFORM_X86) : ARCH_X86, - (PLATFORM_X86_64) : ARCH_X86_64, - ] - - // The version code that gives each ABI a value. - // For each APK variant, use the following versions to override the version of the Universal APK. - // Otherwise, the Play Store will complain that the APK variants have the same version. - private static final Map ABI_VERSION = [ - (ARCH_ARM32) : 1, - (ARCH_ARM64) : 2, - (ARCH_X86) : 3, - (ARCH_X86_64) : 4, - ] - - // When split is enabled, multiple APKs are generated per each ABI. - private static final List DEFAULT_PLATFORMS = [ - PLATFORM_ARM32, - PLATFORM_ARM64, - ] - - // The name prefix for flutter builds. This is used to identify gradle tasks - // where we expect the flutter tool to provide any error output, and skip the - // standard Gradle error output in the FlutterEventLogger. If you change this, - // be sure to change any instances of this string in symbols in the code below - // to match. - static final String FLUTTER_BUILD_PREFIX = "flutterBuild" - private Path baseEnginePath private File flutterRoot private File flutterExecutable @@ -93,6 +49,29 @@ private File dynamicProfileFlutterJar private File dynamicReleaseFlutterJar + // The name prefix for flutter builds. This is used to identify gradle tasks + // where we expect the flutter tool to provide any error output, and skip the + // standard Gradle error output in the FlutterEventLogger. If you change this, + // be sure to change any instances of this string in symbols in the code below + // to match. + static final String flutterBuildPrefix = "flutterBuild" + + // The platforms (or CPU architectures) for which native code is generated. + static final Map allTargetPlatforms = [ + 'android-arm': 'armeabi-v7a', + 'android-arm64': 'arm64-v8a', + 'android-x64': 'x86_64', + 'android-x86': 'x86', + ] + + // Supports ARM 32 and 64 bits. + // When splits are enabled, multiple APKs are generated per each CPU architecture, + // which helps decrease the size of each APK. + static final Set allArmPlatforms = [ + 'android-arm', + 'android-arm64' + ] + private Properties readPropertiesIfExist(File propertiesFile) { Properties result = new Properties() if (propertiesFile.exists()) { @@ -101,16 +80,11 @@ return result } - private List<String> getTargetPlatforms(Project project) { - if (!project.hasProperty('target-platform')) { - return DEFAULT_PLATFORMS + private String getTargetPlatform(Project project) { + if (project.hasProperty('target-platform')) { + return project.property('target-platform') } - return project.property('target-platform').split(',').collect { - if (!PLATFORM_ARCH_MAP[it]) { - throw new GradleException("Invalid platform: $it.") - } - return it - } + return 'android-arm-all'; } private Boolean getBuildShareLibrary(Project project) { @@ -120,13 +94,6 @@ return false; } - private Boolean splitPerAbi(Project project) { - if (project.hasProperty('split-per-abi')) { - return project.property('split-per-abi').toBoolean() - } - return false; - } - private String resolveProperty(Project project, String name, String defaultValue) { if (localProperties == null) { localProperties = readPropertiesIfExist(new File(project.projectDir.parentFile, "local.properties")) @@ -144,55 +111,21 @@ return result } - /** - * Returns the platform that is used to extract the `libflutter.so` and the .class files. - * - * Note: This is only needed to add the .class files. - * Unfortunately, the engine artifacts include the .class and libflutter.so files. - */ - private String getBasePlatform(Project project) { - if (PLATFORM_ARM64 in getTargetPlatforms(project)) { - return PLATFORM_ARM64; - } - return PLATFORM_ARM32; - } - @Override void apply(Project project) { project.extensions.create("flutter", FlutterExtension) project.afterEvaluate this.&addFlutterTask - // By default, assembling APKs generates fat APKs if multiple platforms are passed. - // Configuring split per ABI allows to generate separate APKs for each abi. - // This is a noop when building a bundle. - if (this.splitPerAbi(project)) { - project.android { - splits { - abi { - // Enables building multiple APKs per ABI. - enable true - // Resets the list of ABIs that Gradle should create APKs for to none. - reset() - // Specifies that we do not want to also generate a universal APK that includes all ABIs. - universalApk false - } - } - } - } - this.getTargetPlatforms(project).each { targetArch -> - String abiValue = PLATFORM_ARCH_MAP[targetArch] + allTargetPlatforms.each { currentTargetPlatformValue, abi -> project.android { packagingOptions { - pickFirst "lib/${abiValue}/libflutter.so" - // Prevent the ELF library from getting corrupted. - doNotStrip "*/${abiValue}/libapp.so" - } - if (this.splitPerAbi(project)) { - splits { - abi { - include abiValue - } - } + pickFirst "lib/${abi}/libflutter.so" + + // Disable warning by *-android-strip: File format not recognized + doNotStrip "*/${abi}/lib_vm_snapshot_data.so" + doNotStrip "*/${abi}/lib_vm_snapshot_instr.so" + doNotStrip "*/${abi}/lib_isolate_snapshot_data.so" + doNotStrip "*/${abi}/lib_isolate_snapshot_instr.so" } } } @@ -240,7 +173,7 @@ baseEnginePath = Paths.get(engineOut.absolutePath) flutterJar = baseEnginePath.resolve("flutter.jar").toFile() if (!flutterJar.isFile()) { - throw new GradleException('Local engine jar not found: ' + flutterJar) + throw new GradleException('File not found: ' + flutterJar) } localEngine = engineOut.name @@ -253,14 +186,14 @@ dynamicProfileFlutterJar = flutterJar dynamicReleaseFlutterJar = flutterJar } else { - String basePlatformArch = getBasePlatform(project) - // This is meant to include the compiled classes only, however it will include `libflutter.so` as well. + String targetPlatform = getTargetPlatform(project) + String targetArch = targetPlatform == 'android-arm64' ? 'arm64' : 'arm' baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine") - debugFlutterJar = baseEnginePath.resolve("${basePlatformArch}").resolve("flutter.jar").toFile() - profileFlutterJar = baseEnginePath.resolve("${basePlatformArch}-profile").resolve("flutter.jar").toFile() - releaseFlutterJar = baseEnginePath.resolve("${basePlatformArch}-release").resolve("flutter.jar").toFile() - dynamicProfileFlutterJar = baseEnginePath.resolve("${basePlatformArch}-dynamic-profile").resolve("flutter.jar").toFile() - dynamicReleaseFlutterJar = baseEnginePath.resolve("${basePlatformArch}-dynamic-release").resolve("flutter.jar").toFile() + 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() + dynamicProfileFlutterJar = baseEnginePath.resolve("android-${targetArch}-dynamic-profile").resolve("flutter.jar").toFile() + dynamicReleaseFlutterJar = baseEnginePath.resolve("android-${targetArch}-dynamic-release").resolve("flutter.jar").toFile() } if (!debugFlutterJar.isFile()) { @@ -276,7 +209,7 @@ // Add x86/x86_64 native library. Debug mode only, for now. File flutterX86Jar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/flutter-x86.jar") - Task debugX86JarTask = project.tasks.create("${FLUTTER_BUILD_PREFIX}X86Jar", Jar) { + Task debugX86JarTask = project.tasks.create("${flutterBuildPrefix}X86Jar", Jar) { destinationDir flutterX86Jar.parentFile archiveName flutterX86Jar.name from("${flutterRoot}/bin/cache/artifacts/engine/android-x86/libflutter.so") { @@ -288,7 +221,7 @@ } // Add flutter.jar dependencies to all <buildType>Api configurations, including custom ones // added after applying the Flutter plugin. - project.android.buildTypes.each { + project.android.buildTypes.each { addFlutterJarApiDependency(project, it, debugX86JarTask) } project.android.buildTypes.whenObjectAdded { @@ -405,19 +338,6 @@ return "release" } - private static String getEngineArtifactDirName(buildType, targetArch) { - if (buildType.name == "profile") { - return "${targetArch}-profile" - } else if (buildType.name == "dynamicProfile") { - return "${targetArch}-dynamic-profile" - } else if (buildType.name == "dynamicRelease") { - return "${targetArch}-dynamic-release" - } else if (buildType.debuggable) { - return "${targetArch}" - } - return "${targetArch}-release" - } - private void addFlutterTask(Project project) { if (project.state.failure) { return @@ -475,24 +395,13 @@ extraGenSnapshotOptionsValue = project.property('extra-gen-snapshot-options') } - def targetPlatforms = this.getTargetPlatforms(project) - def addFlutterDeps = { variant -> - if (this.splitPerAbi(project)) { - variant.outputs.each { output -> - // Assigns the new version code to versionCodeOverride, which changes the version code - // for only the output APK, not for the variant itself. Skipping this step simply - // causes Gradle to use the value of variant.versionCode for the APK. - // For more, see https://developer.android.com/studio/build/configure-apk-splits - def abiVersionCode = ABI_VERSION.get(output.getFilter(OutputFile.ABI)) - if (abiVersionCode != null) { - output.versionCodeOverride = - abiVersionCode * 1000 + variant.versionCode - } - } - } + Boolean buildSharedLibraryValue = this.getBuildShareLibrary(project) + String targetPlatformValue = this.getTargetPlatform(project) + def addFlutterDeps = { variant -> String flutterBuildMode = buildModeFor(variant.buildType) - if (flutterBuildMode == 'debug' && project.tasks.findByName("${FLUTTER_BUILD_PREFIX}X86Jar")) { + + if (flutterBuildMode == 'debug' && project.tasks.findByName('${flutterBuildPrefix}X86Jar')) { Task task = project.tasks.findByName("compile${variant.name.capitalize()}JavaWithJavac") if (task) { task.dependsOn project.flutterBuildX86Jar @@ -504,10 +413,22 @@ } def flutterTasks = [] - targetPlatforms.each { targetArch -> - String abiValue = PLATFORM_ARCH_MAP[targetArch] - String taskName = "compile${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}${targetArch.replace('android-', '').capitalize()}" - FlutterTask compileTask = project.tasks.create(name: taskName, type: FlutterTask) { + def targetPlatforms = [] + + if (targetPlatformValue == 'android-arm-all') { + if (flutterBuildMode == 'release') { + targetPlatforms.addAll(allArmPlatforms) + } else { + targetPlatforms.add('android-arm') + } + } else { + targetPlatforms.add(targetPlatformValue) + } + + targetPlatforms.each { currentTargetPlatformValue -> + String abiValue = allTargetPlatforms[currentTargetPlatformValue] + FlutterTask compileTask = project.tasks.create(name: "compile${flutterBuildPrefix}${variant.name.capitalize()}${currentTargetPlatformValue}", + type: FlutterTask) { flutterRoot this.flutterRoot flutterExecutable this.flutterExecutable buildMode flutterBuildMode @@ -523,53 +444,56 @@ createPatch createPatchValue buildNumber buildNumberValue baselineDir baselineDirValue - targetPlatform targetArch + buildSharedLibrary buildSharedLibraryValue + targetPlatform currentTargetPlatformValue sourceDir project.file(project.flutter.source) - intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/${targetArch}") + intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/${currentTargetPlatformValue}") extraFrontEndOptions extraFrontEndOptionsValue extraGenSnapshotOptions extraGenSnapshotOptionsValue } flutterTasks.add(compileTask) } - def libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar") - Task packFlutterSnapshotsAndLibsTask = project.tasks.create(name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) { + + def libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/libs.jar") + Task packFlutterSnapshotsAndLibsTask = project.tasks.create(name: "packFlutterSnapshotsAndLibs${flutterBuildPrefix}${variant.name.capitalize()}", type: Jar) { destinationDir libJar.parentFile archiveName libJar.name - targetPlatforms.each { targetArch -> - // This check prevents including `libflutter.so` twice, since it's included in the base platform jar. - // Unfortunately, the `pickFirst` setting in `packagingOptions` does not work when the project `:flutter` - // is included as an implementation dependency, which causes duplicated `libflutter.so`. - if (getBasePlatform(project) != targetArch) { - def engineArtifactSubdir = getEngineArtifactDirName(variant.buildType, targetArch); - // Include `libflutter.so`. - // TODO(blasten): The libs should be outside `flutter.jar` when the artifacts are downloaded. - from(project.zipTree("${flutterRoot}/bin/cache/artifacts/engine/${engineArtifactSubdir}/flutter.jar")) { - include 'lib/**' - } + targetPlatforms.each { targetPlatform -> + // Include `libflutter.so` for each abi. + // TODO(blasten): The libs should be outside `flutter.jar` when the artifacts are downloaded. + from(project.zipTree("${flutterRoot}/bin/cache/artifacts/engine/${targetPlatform}-release/flutter.jar")) { + include 'lib/**' } } + dependsOn flutterTasks - // Add the ELF library. - flutterTasks.each { flutterTask -> + // Add the snapshots and rename them as `lib/{abi}/*.so`. + flutterTasks.each { flutterTask -> from(flutterTask.intermediateDir) { - include '*.so' - rename { String filename -> - return "lib/${flutterTask.abi}/lib${filename}" + include 'vm_snapshot_data' + include 'vm_snapshot_instr' + include 'isolate_snapshot_data' + include 'isolate_snapshot_instr' + rename { String filename -> + return "lib/${flutterTask.abi}/lib_${filename}.so" } } } } + // Include the snapshots and libflutter.so in `lib/`. - project.dependencies { - String configuration; - if (project.getConfigurations().findByName("api")) { - configuration = buildType.name + "Api"; - } else { - configuration = buildType.name + "Compile"; + if (flutterBuildMode == 'release' && targetPlatformValue == 'android-arm-all') { + project.dependencies { + String configuration; + if (project.getConfigurations().findByName("api")) { + configuration = buildType.name + "Api"; + } else { + configuration = buildType.name + "Compile"; + } + add(configuration, project.files { + packFlutterSnapshotsAndLibsTask + }) } - add(configuration, project.files { - packFlutterSnapshotsAndLibsTask - }) } // We know that the flutter app is a subproject in another Android app when these tasks exist. Task packageAssets = project.tasks.findByPath(":flutter:package${variant.name.capitalize()}Assets") @@ -586,8 +510,12 @@ variant.mergeAssets.mustRunAfter("clean${variant.mergeAssets.name.capitalize()}") into variant.mergeAssets.outputDir } - flutterTasks.each { flutterTask -> + flutterTasks.each { flutterTask -> with flutterTask.assets + // Include the snapshots in the assets directory. + if (flutterBuildMode != 'release' || targetPlatformValue != 'android-arm-all') { + with flutterTask.snapshots + } } } if (packageAssets) { @@ -648,6 +576,8 @@ @Optional @Input String baselineDir @Optional @Input + Boolean buildSharedLibrary + @Optional @Input String targetPlatform @Input String abi @@ -692,10 +622,8 @@ args "build", "aot" args "--suppress-analytics" args "--quiet" - args "--build-shared-library" args "--target", targetPath args "--output-dir", "${intermediateDir}" - args "--target-platform", "${targetPlatform}" if (trackWidgetCreation) { args "--track-widget-creation" } @@ -705,6 +633,14 @@ if (extraGenSnapshotOptions != null) { args "--extra-gen-snapshot-options", "${extraGenSnapshotOptions}" } + if (buildSharedLibrary) { + args "--build-shared-library" + } + if (targetPlatform == null) { + args "--target-platform", "android-arm" + } else { + args "--target-platform", "${targetPlatform}" + } args "--${buildMode}" } } @@ -719,7 +655,6 @@ args "build", "bundle" args "--suppress-analytics" args "--target", targetPath - args "--target-platform", "${targetPlatform}" if (verbose) { args "--verbose" } @@ -753,6 +688,9 @@ if (extraGenSnapshotOptions != null) { args "--extra-gen-snapshot-options", "${extraGenSnapshotOptions}" } + if (targetPlatform != null) { + args "--target-platform", "${targetPlatform}" + } if (buildMode == "release" || buildMode == "profile") { args "--precompiled" } else { @@ -793,7 +731,14 @@ from "${intermediateDir}" if (buildMode == 'release' || buildMode == 'profile') { - include "app.so" + if (buildSharedLibrary) { + include "app.so" + } else { + include "vm_snapshot_data" + include "vm_snapshot_instr" + include "isolate_snapshot_data" + include "isolate_snapshot_instr" + } } } } @@ -860,7 +805,7 @@ void buildFinished(BuildResult result) { if (result.failure != null) { - if (!(result.failure instanceof GradleException) || !mostRecentTask.startsWith(FlutterPlugin.FLUTTER_BUILD_PREFIX)) { + if (!(result.failure instanceof GradleException) || !mostRecentTask.startsWith(FlutterPlugin.flutterBuildPrefix)) { result.rethrowFailure() } }
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index f215124..e062da5 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -388,27 +388,18 @@ 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 @@ 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.
diff --git a/packages/flutter_tools/lib/src/android/apk.dart b/packages/flutter_tools/lib/src/android/apk.dart index 908c535..8b5b8d9 100644 --- a/packages/flutter_tools/lib/src/android/apk.dart +++ b/packages/flutter_tools/lib/src/android/apk.dart
@@ -16,7 +16,7 @@ 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 @@ await buildGradleProject( project: project, - androidBuildInfo: androidBuildInfo, + buildInfo: buildInfo, target: target, isBuildingBundle: false, );
diff --git a/packages/flutter_tools/lib/src/android/app_bundle.dart b/packages/flutter_tools/lib/src/android/app_bundle.dart index 4f304c1..c1e94ab 100644 --- a/packages/flutter_tools/lib/src/android/app_bundle.dart +++ b/packages/flutter_tools/lib/src/android/app_bundle.dart
@@ -17,7 +17,7 @@ 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 @@ return buildGradleProject( project: project, - androidBuildInfo: androidBuildInfo, + buildInfo: buildInfo, target: target, isBuildingBundle: true, );
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart index bf53166..62f4475 100644 --- a/packages/flutter_tools/lib/src/android/gradle.dart +++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -15,7 +15,6 @@ 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 @@ Future<void> buildGradleProject({ @required FlutterProject project, - @required AndroidBuildInfo androidBuildInfo, + @required BuildInfo buildInfo, @required String target, @required bool isBuildingBundle, }) async { @@ -331,7 +330,7 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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); - 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; - } +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; + } + return null; } File _findBundleFile(GradleProject project, BuildInfo buildInfo) { @@ -583,12 +567,12 @@ 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 @@ 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) {
diff --git a/packages/flutter_tools/lib/src/base/build.dart b/packages/flutter_tools/lib/src/base/build.dart index 1908cb3..4b46edb 100644 --- a/packages/flutter_tools/lib/src/base/build.dart +++ b/packages/flutter_tools/lib/src/base/build.dart
@@ -137,7 +137,7 @@ 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');
diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart index e346019..8379e81 100644 --- a/packages/flutter_tools/lib/src/build_info.dart +++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -17,6 +17,8 @@ this.compilationTraceFilePath, this.extraFrontEndOptions, this.extraGenSnapshotOptions, + this.buildSharedLibrary, + this.targetPlatform, this.fileSystemRoots, this.fileSystemScheme, this.buildNumber, @@ -48,6 +50,12 @@ /// 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 @@ 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 @@ 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 @@ 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;
diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart index 5d9cbe8..1d7fbff 100644 --- a/packages/flutter_tools/lib/src/commands/build_apk.dart +++ b/packages/flutter_tools/lib/src/commands/build_apk.dart
@@ -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 @@ 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 @@ @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; }
diff --git a/packages/flutter_tools/lib/src/commands/build_appbundle.dart b/packages/flutter_tools/lib/src/commands/build_appbundle.dart index 76c5ad1..dcc9d4a 100644 --- a/packages/flutter_tools/lib/src/commands/build_appbundle.dart +++ b/packages/flutter_tools/lib/src/commands/build_appbundle.dart
@@ -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 @@ 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 @@ @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; }
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index 62535d0..9f36386 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -387,7 +387,8 @@ 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,
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 634d4a8..b39e674 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -320,6 +320,12 @@ } 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 @@ 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)
diff --git a/packages/flutter_tools/test/android/gradle_test.dart b/packages/flutter_tools/test/android/gradle_test.dart index 7aafd64..3940e9b 100644 --- a/packages/flutter_tools/test/android/gradle_test.dart +++ b/packages/flutter_tools/test/android/gradle_test.dart
@@ -157,102 +157,16 @@ }); 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'));
diff --git a/packages/flutter_tools/test/base/build_test.dart b/packages/flutter_tools/test/base/build_test.dart index 8c32fd9..60d3724 100644 --- a/packages/flutter_tools/test/base/build_test.dart +++ b/packages/flutter_tools/test/base/build_test.dart
@@ -80,7 +80,7 @@ }); }); - group('Snapshotter - AOT', () { + group('Snapshotter - iOS AOT', () { const String kSnapshotDart = 'snapshot.dart'; String skyEnginePath; @@ -395,11 +395,10 @@ ]); }, 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); + + when(mockAndroidSdk.ndk).thenReturn(null); final int genSnapshotExitCode = await snapshotter.build( platform: TargetPlatform.android_arm, @@ -410,45 +409,8 @@ 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); - - final int genSnapshotExitCode = await snapshotter.build( - platform: TargetPlatform.android_arm64, - 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_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 {
diff --git a/packages/flutter_tools/test/ios/xcodeproj_test.dart b/packages/flutter_tools/test/ios/xcodeproj_test.dart index 6a42162..63685c5 100644 --- a/packages/flutter_tools/test/ios/xcodeproj_test.dart +++ b/packages/flutter_tools/test/ios/xcodeproj_test.dart
@@ -286,7 +286,7 @@ 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 @@ 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 @@ 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 @@ 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(