Commit 7faf2d73 authored by Jonah Williams's avatar Jonah Williams Committed by Flutter GitHub Bot

[flutter_tools] implement build aot in terms of assemble for iOS (#49224)

parent e2aa9e13
...@@ -14,6 +14,8 @@ import 'base/process.dart'; ...@@ -14,6 +14,8 @@ import 'base/process.dart';
import 'build_info.dart'; import 'build_info.dart';
import 'build_system/build_system.dart'; import 'build_system/build_system.dart';
import 'build_system/targets/dart.dart'; import 'build_system/targets/dart.dart';
import 'build_system/targets/ios.dart';
import 'cache.dart';
import 'dart/package_map.dart'; import 'dart/package_map.dart';
import 'globals.dart' as globals; import 'globals.dart' as globals;
import 'ios/bitcode.dart'; import 'ios/bitcode.dart';
...@@ -39,18 +41,17 @@ class AotBuilder { ...@@ -39,18 +41,17 @@ class AotBuilder {
throwToolExit('No AOT build platform specified'); throwToolExit('No AOT build platform specified');
} }
// This code is currently dead, but will be updated as we move iOS to assemble.
// See also: https://github.com/flutter/flutter/issues/32925
if (_canUseAssemble(platform) if (_canUseAssemble(platform)
&& extraGenSnapshotOptions?.isEmpty != false && extraGenSnapshotOptions?.isEmpty != false
&& extraFrontEndOptions?.isEmpty != false) { && extraFrontEndOptions?.isEmpty != false) {
assert(false);
await _buildWithAssemble( await _buildWithAssemble(
targetFile: mainDartFile, targetFile: mainDartFile,
outputDir: outputPath, outputDir: outputPath,
targetPlatform: platform, targetPlatform: platform,
buildMode: buildMode, buildMode: buildMode,
quiet: quiet, quiet: quiet,
iosArchs: iosBuildArchs ?? defaultIOSArchs,
bitcode: bitcode ?? kBitcodeEnabledDefault,
); );
return; return;
} }
...@@ -175,12 +176,13 @@ class AotBuilder { ...@@ -175,12 +176,13 @@ class AotBuilder {
bool _canUseAssemble(TargetPlatform targetPlatform) { bool _canUseAssemble(TargetPlatform targetPlatform) {
switch (targetPlatform) { switch (targetPlatform) {
case TargetPlatform.ios:
return true;
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_arm64: case TargetPlatform.android_arm64:
case TargetPlatform.android_x86: case TargetPlatform.android_x86:
case TargetPlatform.darwin_x64: case TargetPlatform.darwin_x64:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.ios:
case TargetPlatform.linux_x64: case TargetPlatform.linux_x64:
case TargetPlatform.windows_x64: case TargetPlatform.windows_x64:
case TargetPlatform.fuchsia_arm64: case TargetPlatform.fuchsia_arm64:
...@@ -197,11 +199,10 @@ class AotBuilder { ...@@ -197,11 +199,10 @@ class AotBuilder {
BuildMode buildMode, BuildMode buildMode,
String targetFile, String targetFile,
String outputDir, String outputDir,
bool quiet bool quiet,
Iterable<DarwinArch> iosArchs,
bool bitcode,
}) async { }) async {
// This code is currently dead, but will be updated as we move iOS to assemble.
// See also: https://github.com/flutter/flutter/issues/32925
assert(false);
Status status; Status status;
if (!quiet) { if (!quiet) {
final String typeName = globals.artifacts.getEngineType(targetPlatform, buildMode); final String typeName = globals.artifacts.getEngineType(targetPlatform, buildMode);
...@@ -211,10 +212,14 @@ class AotBuilder { ...@@ -211,10 +212,14 @@ class AotBuilder {
); );
} }
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
const Target target = null; final Target target = buildMode == BuildMode.profile
? const AotAssemblyProfile()
final BuildResult result = await buildSystem.build(target, Environment.test( : const AotAssemblyRelease();
flutterProject.directory,
final BuildResult result = await buildSystem.build(target, Environment(
projectDir: flutterProject.directory,
cacheDir: globals.cache.getRoot(),
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
outputDir: globals.fs.directory(outputDir), outputDir: globals.fs.directory(outputDir),
buildDir: flutterProject.directory buildDir: flutterProject.directory
.childDirectory('.dart_tool') .childDirectory('.dart_tool')
...@@ -223,6 +228,8 @@ class AotBuilder { ...@@ -223,6 +228,8 @@ class AotBuilder {
kBuildMode: getNameForBuildMode(buildMode), kBuildMode: getNameForBuildMode(buildMode),
kTargetPlatform: getNameForTargetPlatform(targetPlatform), kTargetPlatform: getNameForTargetPlatform(targetPlatform),
kTargetFile: targetFile, kTargetFile: targetFile,
kIosArchs: iosArchs.map(getNameForDarwinArch).join(','),
kBitcodeFlag: bitcode.toString()
} }
)); ));
status?.stop(); status?.stop();
......
...@@ -25,7 +25,7 @@ abstract class AotAssemblyBase extends Target { ...@@ -25,7 +25,7 @@ abstract class AotAssemblyBase extends Target {
@override @override
Future<void> build(Environment environment) async { Future<void> build(Environment environment) async {
final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: false); final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: false);
final String buildOutputPath = environment.buildDir.path; final String buildOutputPath = environment.outputDir.path;
if (environment.defines[kBuildMode] == null) { if (environment.defines[kBuildMode] == null) {
throw MissingDefineException(kBuildMode, 'aot_assembly'); throw MissingDefineException(kBuildMode, 'aot_assembly');
} }
...@@ -41,50 +41,37 @@ abstract class AotAssemblyBase extends Target { ...@@ -41,50 +41,37 @@ abstract class AotAssemblyBase extends Target {
throw Exception('aot_assembly is only supported for iOS applications'); throw Exception('aot_assembly is only supported for iOS applications');
} }
// If we're building for a single architecture (common), then skip the lipo. // If we're building multiple iOS archs the binaries need to be lipo'd
if (iosArchs.length == 1) { // together.
final int snapshotExitCode = await snapshotter.build( final List<Future<int>> pending = <Future<int>>[];
for (final DarwinArch iosArch in iosArchs) {
pending.add(snapshotter.build(
platform: targetPlatform, platform: targetPlatform,
buildMode: buildMode, buildMode: buildMode,
mainPath: environment.buildDir.childFile('app.dill').path, mainPath: environment.buildDir.childFile('app.dill').path,
packagesPath: environment.projectDir.childFile('.packages').path, packagesPath: environment.projectDir.childFile('.packages').path,
outputPath: environment.outputDir.path, outputPath: globals.fs.path.join(buildOutputPath, getNameForDarwinArch(iosArch)),
darwinArch: iosArchs.single, darwinArch: iosArch,
bitcode: bitcode, bitcode: bitcode,
); quiet: true,
if (snapshotExitCode != 0) { ));
throw Exception('AOT snapshotter exited with code $snapshotExitCode'); }
} final List<int> results = await Future.wait(pending);
} else { if (results.any((int result) => result != 0)) {
// If we're building multiple iOS archs the binaries need to be lipo'd throw Exception('AOT snapshotter exited with code ${results.join()}');
// together. }
final List<Future<int>> pending = <Future<int>>[]; final String resultPath = globals.fs.path.join(environment.outputDir.path, 'App.framework', 'App');
for (final DarwinArch iosArch in iosArchs) { globals.fs.directory(resultPath).parent.createSync(recursive: true);
pending.add(snapshotter.build( final ProcessResult result = await globals.processManager.run(<String>[
platform: targetPlatform, 'lipo',
buildMode: buildMode, ...iosArchs.map((DarwinArch iosArch) =>
mainPath: environment.buildDir.childFile('app.dill').path, globals.fs.path.join(buildOutputPath, getNameForDarwinArch(iosArch), 'App.framework', 'App')),
packagesPath: environment.projectDir.childFile('.packages').path, '-create',
outputPath: globals.fs.path.join(buildOutputPath, getNameForDarwinArch(iosArch)), '-output',
darwinArch: iosArch, resultPath,
bitcode: bitcode, ]);
)); if (result.exitCode != 0) {
} throw Exception('lipo exited with code ${result.exitCode}.\n${result.stderr}');
final List<int> results = await Future.wait(pending);
if (results.any((int result) => result != 0)) {
throw Exception('AOT snapshotter exited with code ${results.join()}');
}
final ProcessResult result = await globals.processManager.run(<String>[
'lipo',
...iosArchs.map((DarwinArch iosArch) =>
globals.fs.path.join(buildOutputPath, getNameForDarwinArch(iosArch), 'App.framework', 'App')),
'-create',
'-output',
globals.fs.path.join(environment.outputDir.path, 'App.framework', 'App'),
]);
if (result.exitCode != 0) {
throw Exception('lipo exited with code ${result.exitCode}');
}
} }
} }
} }
...@@ -103,10 +90,13 @@ class AotAssemblyRelease extends AotAssemblyBase { ...@@ -103,10 +90,13 @@ class AotAssemblyRelease extends AotAssemblyBase {
Source.pattern('{PROJECT_DIR}/.packages'), Source.pattern('{PROJECT_DIR}/.packages'),
Source.artifact(Artifact.engineDartBinary), Source.artifact(Artifact.engineDartBinary),
Source.artifact(Artifact.skyEnginePath), Source.artifact(Artifact.skyEnginePath),
Source.artifact(Artifact.genSnapshot, // TODO(jonahwilliams): cannot reference gen_snapshot with artifacts since
platform: TargetPlatform.ios, // it resolves to a file (ios/gen_snapshot) that never exists. This was
mode: BuildMode.release, // split into gen_snapshot_arm64 and gen_snapshot_armv7.
), // Source.artifact(Artifact.genSnapshot,
// platform: TargetPlatform.ios,
// mode: BuildMode.release,
// ),
]; ];
@override @override
...@@ -135,10 +125,13 @@ class AotAssemblyProfile extends AotAssemblyBase { ...@@ -135,10 +125,13 @@ class AotAssemblyProfile extends AotAssemblyBase {
Source.pattern('{PROJECT_DIR}/.packages'), Source.pattern('{PROJECT_DIR}/.packages'),
Source.artifact(Artifact.engineDartBinary), Source.artifact(Artifact.engineDartBinary),
Source.artifact(Artifact.skyEnginePath), Source.artifact(Artifact.skyEnginePath),
Source.artifact(Artifact.genSnapshot, // TODO(jonahwilliams): cannot reference gen_snapshot with artifacts since
platform: TargetPlatform.ios, // it resolves to a file (ios/gen_snapshot) that never exists. This was
mode: BuildMode.profile, // split into gen_snapshot_arm64 and gen_snapshot_armv7.
), // Source.artifact(Artifact.genSnapshot,
// platform: TargetPlatform.ios,
// mode: BuildMode.profile,
// ),
]; ];
@override @override
......
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