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

This commit is contained in:
Jonah Williams 2020-01-23 20:03:01 -08:00 committed by Flutter GitHub Bot
parent e2aa9e13ce
commit 7faf2d73c7
2 changed files with 59 additions and 59 deletions

View file

@ -14,6 +14,8 @@ import 'base/process.dart';
import 'build_info.dart';
import 'build_system/build_system.dart';
import 'build_system/targets/dart.dart';
import 'build_system/targets/ios.dart';
import 'cache.dart';
import 'dart/package_map.dart';
import 'globals.dart' as globals;
import 'ios/bitcode.dart';
@ -39,18 +41,17 @@ class AotBuilder {
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)
&& extraGenSnapshotOptions?.isEmpty != false
&& extraFrontEndOptions?.isEmpty != false) {
assert(false);
await _buildWithAssemble(
targetFile: mainDartFile,
outputDir: outputPath,
targetPlatform: platform,
buildMode: buildMode,
quiet: quiet,
iosArchs: iosBuildArchs ?? defaultIOSArchs,
bitcode: bitcode ?? kBitcodeEnabledDefault,
);
return;
}
@ -175,12 +176,13 @@ class AotBuilder {
bool _canUseAssemble(TargetPlatform targetPlatform) {
switch (targetPlatform) {
case TargetPlatform.ios:
return true;
case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x86:
case TargetPlatform.darwin_x64:
case TargetPlatform.android_x64:
case TargetPlatform.ios:
case TargetPlatform.linux_x64:
case TargetPlatform.windows_x64:
case TargetPlatform.fuchsia_arm64:
@ -197,11 +199,10 @@ class AotBuilder {
BuildMode buildMode,
String targetFile,
String outputDir,
bool quiet
bool quiet,
Iterable<DarwinArch> iosArchs,
bool bitcode,
}) 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;
if (!quiet) {
final String typeName = globals.artifacts.getEngineType(targetPlatform, buildMode);
@ -211,10 +212,14 @@ class AotBuilder {
);
}
final FlutterProject flutterProject = FlutterProject.current();
const Target target = null;
final Target target = buildMode == BuildMode.profile
? const AotAssemblyProfile()
: const AotAssemblyRelease();
final BuildResult result = await buildSystem.build(target, Environment.test(
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),
buildDir: flutterProject.directory
.childDirectory('.dart_tool')
@ -223,6 +228,8 @@ class AotBuilder {
kBuildMode: getNameForBuildMode(buildMode),
kTargetPlatform: getNameForTargetPlatform(targetPlatform),
kTargetFile: targetFile,
kIosArchs: iosArchs.map(getNameForDarwinArch).join(','),
kBitcodeFlag: bitcode.toString()
}
));
status?.stop();

View file

@ -25,7 +25,7 @@ abstract class AotAssemblyBase extends Target {
@override
Future<void> build(Environment environment) async {
final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: false);
final String buildOutputPath = environment.buildDir.path;
final String buildOutputPath = environment.outputDir.path;
if (environment.defines[kBuildMode] == null) {
throw MissingDefineException(kBuildMode, 'aot_assembly');
}
@ -41,50 +41,37 @@ abstract class AotAssemblyBase extends Target {
throw Exception('aot_assembly is only supported for iOS applications');
}
// If we're building for a single architecture (common), then skip the lipo.
if (iosArchs.length == 1) {
final int snapshotExitCode = await snapshotter.build(
// If we're building multiple iOS archs the binaries need to be lipo'd
// together.
final List<Future<int>> pending = <Future<int>>[];
for (final DarwinArch iosArch in iosArchs) {
pending.add(snapshotter.build(
platform: targetPlatform,
buildMode: buildMode,
mainPath: environment.buildDir.childFile('app.dill').path,
packagesPath: environment.projectDir.childFile('.packages').path,
outputPath: environment.outputDir.path,
darwinArch: iosArchs.single,
outputPath: globals.fs.path.join(buildOutputPath, getNameForDarwinArch(iosArch)),
darwinArch: iosArch,
bitcode: bitcode,
);
if (snapshotExitCode != 0) {
throw Exception('AOT snapshotter exited with code $snapshotExitCode');
}
} else {
// If we're building multiple iOS archs the binaries need to be lipo'd
// together.
final List<Future<int>> pending = <Future<int>>[];
for (final DarwinArch iosArch in iosArchs) {
pending.add(snapshotter.build(
platform: targetPlatform,
buildMode: buildMode,
mainPath: environment.buildDir.childFile('app.dill').path,
packagesPath: environment.projectDir.childFile('.packages').path,
outputPath: globals.fs.path.join(buildOutputPath, getNameForDarwinArch(iosArch)),
darwinArch: iosArch,
bitcode: bitcode,
));
}
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}');
}
quiet: true,
));
}
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 String resultPath = globals.fs.path.join(environment.outputDir.path, 'App.framework', 'App');
globals.fs.directory(resultPath).parent.createSync(recursive: true);
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',
resultPath,
]);
if (result.exitCode != 0) {
throw Exception('lipo exited with code ${result.exitCode}.\n${result.stderr}');
}
}
}
@ -103,10 +90,13 @@ class AotAssemblyRelease extends AotAssemblyBase {
Source.pattern('{PROJECT_DIR}/.packages'),
Source.artifact(Artifact.engineDartBinary),
Source.artifact(Artifact.skyEnginePath),
Source.artifact(Artifact.genSnapshot,
platform: TargetPlatform.ios,
mode: BuildMode.release,
),
// TODO(jonahwilliams): cannot reference gen_snapshot with artifacts since
// it resolves to a file (ios/gen_snapshot) that never exists. This was
// split into gen_snapshot_arm64 and gen_snapshot_armv7.
// Source.artifact(Artifact.genSnapshot,
// platform: TargetPlatform.ios,
// mode: BuildMode.release,
// ),
];
@override
@ -135,10 +125,13 @@ class AotAssemblyProfile extends AotAssemblyBase {
Source.pattern('{PROJECT_DIR}/.packages'),
Source.artifact(Artifact.engineDartBinary),
Source.artifact(Artifact.skyEnginePath),
Source.artifact(Artifact.genSnapshot,
platform: TargetPlatform.ios,
mode: BuildMode.profile,
),
// TODO(jonahwilliams): cannot reference gen_snapshot with artifacts since
// it resolves to a file (ios/gen_snapshot) that never exists. This was
// split into gen_snapshot_arm64 and gen_snapshot_armv7.
// Source.artifact(Artifact.genSnapshot,
// platform: TargetPlatform.ios,
// mode: BuildMode.profile,
// ),
];
@override