mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
[flutter_tools] refactor AotBuilder, removing globals and duplicated kernel compilation (#52896)
Reland of #52091
This commit is contained in:
parent
11efa00f9f
commit
b21e780aee
|
@ -6,15 +6,18 @@ import 'dart:async';
|
|||
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import 'base/build.dart';
|
||||
import 'base/common.dart';
|
||||
import 'base/io.dart';
|
||||
import 'base/logger.dart';
|
||||
import 'base/process.dart';
|
||||
import 'build_info.dart';
|
||||
import 'dart/package_map.dart';
|
||||
import 'build_system/build_system.dart';
|
||||
import 'build_system/targets/dart.dart';
|
||||
import 'build_system/targets/icon_tree_shaker.dart';
|
||||
import 'build_system/targets/ios.dart';
|
||||
import 'cache.dart';
|
||||
import 'convert.dart';
|
||||
import 'globals.dart' as globals;
|
||||
import 'ios/bitcode.dart';
|
||||
import 'project.dart';
|
||||
|
||||
/// Builds AOT snapshots given a platform, build mode and a path to a Dart
|
||||
/// library.
|
||||
|
@ -26,18 +29,41 @@ class AotBuilder {
|
|||
@required String mainDartFile,
|
||||
bool bitcode = kBitcodeEnabledDefault,
|
||||
bool quiet = true,
|
||||
bool reportTimings = false,
|
||||
Iterable<DarwinArch> iosBuildArchs = defaultIOSArchs,
|
||||
}) async {
|
||||
if (platform == null) {
|
||||
throwToolExit('No AOT build platform specified');
|
||||
}
|
||||
|
||||
if (bitcode) {
|
||||
if (platform != TargetPlatform.ios) {
|
||||
throwToolExit('Bitcode is only supported on iOS (TargetPlatform is $platform).');
|
||||
}
|
||||
await validateBitcode(buildInfo.mode, platform);
|
||||
Target target;
|
||||
bool expectSo = false;
|
||||
switch (platform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.darwin_x64:
|
||||
case TargetPlatform.linux_x64:
|
||||
case TargetPlatform.windows_x64:
|
||||
case TargetPlatform.fuchsia_arm64:
|
||||
case TargetPlatform.tester:
|
||||
case TargetPlatform.web_javascript:
|
||||
case TargetPlatform.android_x86:
|
||||
throwToolExit('$platform is not supported in AOT.');
|
||||
break;
|
||||
case TargetPlatform.fuchsia_x64:
|
||||
throwToolExit(
|
||||
"To build release for fuchsia, use 'flutter build fuchsia --release'"
|
||||
);
|
||||
break;
|
||||
case TargetPlatform.ios:
|
||||
target = buildInfo.isRelease
|
||||
? const AotAssemblyRelease()
|
||||
: const AotAssemblyProfile();
|
||||
break;
|
||||
case TargetPlatform.android_arm:
|
||||
case TargetPlatform.android_arm64:
|
||||
case TargetPlatform.android_x64:
|
||||
expectSo = true;
|
||||
target = buildInfo.isRelease
|
||||
? const AotElfRelease()
|
||||
: const AotElfProfile();
|
||||
}
|
||||
|
||||
Status status;
|
||||
|
@ -48,102 +74,46 @@ class AotBuilder {
|
|||
timeout: timeoutConfiguration.slowOperation,
|
||||
);
|
||||
}
|
||||
try {
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: reportTimings);
|
||||
|
||||
// Compile to kernel.
|
||||
final String kernelOut = await snapshotter.compileKernel(
|
||||
platform: platform,
|
||||
buildMode: buildInfo.mode,
|
||||
mainPath: mainDartFile,
|
||||
packagesPath: PackageMap.globalPackagesPath,
|
||||
trackWidgetCreation: buildInfo.trackWidgetCreation,
|
||||
outputPath: outputPath,
|
||||
extraFrontEndOptions: buildInfo.extraFrontEndOptions,
|
||||
dartDefines: buildInfo.dartDefines
|
||||
);
|
||||
if (kernelOut == null) {
|
||||
throwToolExit('Compiler terminated unexpectedly.');
|
||||
return;
|
||||
final Environment environment = Environment(
|
||||
projectDir: globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory(outputPath),
|
||||
buildDir: FlutterProject.current().dartTool.childDirectory('flutter_build'),
|
||||
cacheDir: null,
|
||||
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
|
||||
defines: <String, String>{
|
||||
kTargetFile: mainDartFile ?? globals.fs.path.join('lib', 'main.dart'),
|
||||
kBuildMode: getNameForBuildMode(buildInfo.mode),
|
||||
kTargetPlatform: getNameForTargetPlatform(platform),
|
||||
kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(),
|
||||
kDartDefines: jsonEncode(buildInfo.dartDefines),
|
||||
kBitcodeFlag: bitcode.toString(),
|
||||
if (buildInfo?.extraGenSnapshotOptions?.isNotEmpty ?? false)
|
||||
kExtraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions.join(','),
|
||||
if (buildInfo?.extraFrontEndOptions?.isNotEmpty ?? false)
|
||||
kExtraFrontEndOptions: buildInfo.extraFrontEndOptions.join(','),
|
||||
if (platform == TargetPlatform.ios)
|
||||
kIosArchs: iosBuildArchs.map(getNameForDarwinArch).join(' ')
|
||||
}
|
||||
|
||||
// Build AOT snapshot.
|
||||
if (platform == TargetPlatform.ios) {
|
||||
// Determine which iOS architectures to build for.
|
||||
final Map<DarwinArch, String> iosBuilds = <DarwinArch, String>{};
|
||||
for (final DarwinArch arch in iosBuildArchs) {
|
||||
iosBuilds[arch] = globals.fs.path.join(outputPath, getNameForDarwinArch(arch));
|
||||
}
|
||||
|
||||
// Generate AOT snapshot and compile to arch-specific App.framework.
|
||||
final Map<DarwinArch, Future<int>> exitCodes = <DarwinArch, Future<int>>{};
|
||||
iosBuilds.forEach((DarwinArch iosArch, String outputPath) {
|
||||
exitCodes[iosArch] = snapshotter.build(
|
||||
platform: platform,
|
||||
darwinArch: iosArch,
|
||||
buildMode: buildInfo.mode,
|
||||
mainPath: kernelOut,
|
||||
packagesPath: PackageMap.globalPackagesPath,
|
||||
outputPath: outputPath,
|
||||
extraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions,
|
||||
bitcode: bitcode,
|
||||
quiet: quiet,
|
||||
splitDebugInfo: null,
|
||||
dartObfuscation: false,
|
||||
).then<int>((int buildExitCode) {
|
||||
return buildExitCode;
|
||||
});
|
||||
});
|
||||
|
||||
// Merge arch-specific App.frameworks into a multi-arch App.framework.
|
||||
if ((await Future.wait<int>(exitCodes.values)).every((int buildExitCode) => buildExitCode == 0)) {
|
||||
final Iterable<String> dylibs = iosBuilds.values.map<String>(
|
||||
(String outputDir) => globals.fs.path.join(outputDir, 'App.framework', 'App'));
|
||||
globals.fs.directory(globals.fs.path.join(outputPath, 'App.framework')).createSync();
|
||||
await processUtils.run(
|
||||
<String>[
|
||||
'lipo',
|
||||
...dylibs,
|
||||
'-create',
|
||||
'-output', globals.fs.path.join(outputPath, 'App.framework', 'App'),
|
||||
],
|
||||
throwOnError: true,
|
||||
);
|
||||
} else {
|
||||
status?.cancel();
|
||||
exitCodes.forEach((DarwinArch iosArch, Future<int> exitCodeFuture) async {
|
||||
final int buildExitCode = await exitCodeFuture;
|
||||
globals.printError('Snapshotting ($iosArch) exited with non-zero exit code: $buildExitCode');
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Android AOT snapshot.
|
||||
final int snapshotExitCode = await snapshotter.build(
|
||||
platform: platform,
|
||||
buildMode: buildInfo.mode,
|
||||
mainPath: kernelOut,
|
||||
packagesPath: PackageMap.globalPackagesPath,
|
||||
outputPath: outputPath,
|
||||
extraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
dartObfuscation: false,
|
||||
);
|
||||
if (snapshotExitCode != 0) {
|
||||
status?.cancel();
|
||||
throwToolExit('Snapshotting exited with non-zero exit code: $snapshotExitCode');
|
||||
}
|
||||
}
|
||||
} on ProcessException catch (error) {
|
||||
// Catch the String exceptions thrown from the `runSync` methods below.
|
||||
status?.cancel();
|
||||
globals.printError(error.toString());
|
||||
return;
|
||||
}
|
||||
);
|
||||
final BuildResult result = await buildSystem.build(target, environment);
|
||||
status?.stop();
|
||||
|
||||
if (outputPath == null) {
|
||||
throwToolExit(null);
|
||||
if (!result.success) {
|
||||
for (final ExceptionMeasurement measurement in result.exceptions.values) {
|
||||
globals.printError(measurement.exception.toString());
|
||||
}
|
||||
throwToolExit('The aot build failed.');
|
||||
}
|
||||
|
||||
if (expectSo) {
|
||||
environment.buildDir.childFile('app.so')
|
||||
.copySync(globals.fs.path.join(outputPath, 'app.so'));
|
||||
} else {
|
||||
globals.fs.directory(globals.fs.path.join(outputPath, 'App.framework'))
|
||||
.createSync(recursive: true);
|
||||
environment.buildDir.childDirectory('App.framework').childFile('App')
|
||||
.copySync(globals.fs.path.join(outputPath, 'App.framework', 'App'));
|
||||
}
|
||||
|
||||
final String builtMessage = 'Built to $outputPath${globals.fs.path.separator}.';
|
||||
|
|
|
@ -3,23 +3,17 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../build_info.dart';
|
||||
import '../bundle.dart';
|
||||
import '../compile.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../macos/xcode.dart';
|
||||
import '../project.dart';
|
||||
|
||||
import 'context.dart';
|
||||
import 'file_system.dart';
|
||||
import 'logger.dart';
|
||||
import 'process.dart';
|
||||
|
||||
GenSnapshot get genSnapshot => context.get<GenSnapshot>();
|
||||
|
||||
/// A snapshot build configuration.
|
||||
class SnapshotType {
|
||||
SnapshotType(this.platform, this.mode)
|
||||
|
@ -34,10 +28,18 @@ class SnapshotType {
|
|||
|
||||
/// Interface to the gen_snapshot command-line tool.
|
||||
class GenSnapshot {
|
||||
const GenSnapshot();
|
||||
GenSnapshot({
|
||||
@required Artifacts artifacts,
|
||||
@required ProcessManager processManager,
|
||||
@required Logger logger,
|
||||
}) : _artifacts = artifacts,
|
||||
_processUtils = ProcessUtils(logger: logger, processManager: processManager);
|
||||
|
||||
static String getSnapshotterPath(SnapshotType snapshotType) {
|
||||
return globals.artifacts.getArtifactPath(
|
||||
final Artifacts _artifacts;
|
||||
final ProcessUtils _processUtils;
|
||||
|
||||
String getSnapshotterPath(SnapshotType snapshotType) {
|
||||
return _artifacts.getArtifactPath(
|
||||
Artifact.genSnapshot, platform: snapshotType.platform, mode: snapshotType.mode);
|
||||
}
|
||||
|
||||
|
@ -51,6 +53,7 @@ class GenSnapshot {
|
|||
'Warning: This VM has been configured to obfuscate symbol information which violates the Dart standard.',
|
||||
' See dartbug.com/30524 for more information.',
|
||||
};
|
||||
|
||||
Future<int> run({
|
||||
@required SnapshotType snapshotType,
|
||||
DarwinArch darwinArch,
|
||||
|
@ -68,7 +71,7 @@ class GenSnapshot {
|
|||
snapshotterPath += '_' + getNameForDarwinArch(darwinArch);
|
||||
}
|
||||
|
||||
return processUtils.stream(
|
||||
return _processUtils.stream(
|
||||
<String>[snapshotterPath, ...args],
|
||||
mapFunction: (String line) => kIgnoredWarnings.contains(line) ? null : line,
|
||||
);
|
||||
|
@ -76,7 +79,26 @@ class GenSnapshot {
|
|||
}
|
||||
|
||||
class AOTSnapshotter {
|
||||
AOTSnapshotter({this.reportTimings = false});
|
||||
AOTSnapshotter({
|
||||
this.reportTimings = false,
|
||||
@required Logger logger,
|
||||
@required FileSystem fileSystem,
|
||||
@required Xcode xcode,
|
||||
@required ProcessManager processManager,
|
||||
@required Artifacts artifacts,
|
||||
}) : _logger = logger,
|
||||
_fileSystem = fileSystem,
|
||||
_xcode = xcode,
|
||||
_genSnapshot = GenSnapshot(
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
logger: logger,
|
||||
);
|
||||
|
||||
final Logger _logger;
|
||||
final FileSystem _fileSystem;
|
||||
final Xcode _xcode;
|
||||
final GenSnapshot _genSnapshot;
|
||||
|
||||
/// If true then AOTSnapshotter would report timings for individual building
|
||||
/// steps (Dart front-end parsing and snapshot generation) in a stable
|
||||
|
@ -97,40 +119,43 @@ class AOTSnapshotter {
|
|||
@required bool dartObfuscation,
|
||||
bool quiet = false,
|
||||
}) async {
|
||||
// TODO(cbracken): replace IOSArch with TargetPlatform.ios_{armv7,arm64}.
|
||||
assert(platform != TargetPlatform.ios || darwinArch != null);
|
||||
if (bitcode && platform != TargetPlatform.ios) {
|
||||
globals.printError('Bitcode is only supported for iOS.');
|
||||
_logger.printError('Bitcode is only supported for iOS.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!_isValidAotPlatform(platform, buildMode)) {
|
||||
globals.printError('${getNameForTargetPlatform(platform)} does not support AOT compilation.');
|
||||
_logger.printError('${getNameForTargetPlatform(platform)} does not support AOT compilation.');
|
||||
return 1;
|
||||
}
|
||||
// TODO(cbracken): replace IOSArch with TargetPlatform.ios_{armv7,arm64}.
|
||||
assert(platform != TargetPlatform.ios || darwinArch != null);
|
||||
|
||||
final Directory outputDir = globals.fs.directory(outputPath);
|
||||
final Directory outputDir = _fileSystem.directory(outputPath);
|
||||
outputDir.createSync(recursive: true);
|
||||
|
||||
final List<String> genSnapshotArgs = <String>[
|
||||
'--deterministic',
|
||||
];
|
||||
if (extraGenSnapshotOptions != null && extraGenSnapshotOptions.isNotEmpty) {
|
||||
globals.printTrace('Extra gen_snapshot options: $extraGenSnapshotOptions');
|
||||
_logger.printTrace('Extra gen_snapshot options: $extraGenSnapshotOptions');
|
||||
genSnapshotArgs.addAll(extraGenSnapshotOptions);
|
||||
}
|
||||
|
||||
final String assembly = globals.fs.path.join(outputDir.path, 'snapshot_assembly.S');
|
||||
final String assembly = _fileSystem.path.join(outputDir.path, 'snapshot_assembly.S');
|
||||
if (platform == TargetPlatform.ios || platform == TargetPlatform.darwin_x64) {
|
||||
// Assembly AOT snapshot.
|
||||
genSnapshotArgs.add('--snapshot_kind=app-aot-assembly');
|
||||
genSnapshotArgs.add('--assembly=$assembly');
|
||||
genSnapshotArgs.add('--strip');
|
||||
genSnapshotArgs.addAll(<String>[
|
||||
'--snapshot_kind=app-aot-assembly',
|
||||
'--assembly=$assembly',
|
||||
'--strip'
|
||||
]);
|
||||
} else {
|
||||
final String aotSharedLibrary = globals.fs.path.join(outputDir.path, 'app.so');
|
||||
genSnapshotArgs.add('--snapshot_kind=app-aot-elf');
|
||||
genSnapshotArgs.add('--elf=$aotSharedLibrary');
|
||||
genSnapshotArgs.add('--strip');
|
||||
final String aotSharedLibrary = _fileSystem.path.join(outputDir.path, 'app.so');
|
||||
genSnapshotArgs.addAll(<String>[
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=$aotSharedLibrary',
|
||||
'--strip'
|
||||
]);
|
||||
}
|
||||
|
||||
if (platform == TargetPlatform.android_arm || darwinArch == DarwinArch.armv7) {
|
||||
|
@ -150,7 +175,7 @@ class AOTSnapshotter {
|
|||
final String debugFilename = 'app.$archName.symbols';
|
||||
final bool shouldSplitDebugInfo = splitDebugInfo?.isNotEmpty ?? false;
|
||||
if (shouldSplitDebugInfo) {
|
||||
globals.fs.directory(splitDebugInfo)
|
||||
_fileSystem.directory(splitDebugInfo)
|
||||
.createSync(recursive: true);
|
||||
}
|
||||
|
||||
|
@ -161,7 +186,7 @@ class AOTSnapshotter {
|
|||
'--lazy-async-stacks',
|
||||
if (shouldSplitDebugInfo) ...<String>[
|
||||
'--dwarf-stack-traces',
|
||||
'--save-debugging-info=${globals.fs.path.join(splitDebugInfo, debugFilename)}'
|
||||
'--save-debugging-info=${_fileSystem.path.join(splitDebugInfo, debugFilename)}'
|
||||
],
|
||||
if (dartObfuscation)
|
||||
'--obfuscate',
|
||||
|
@ -170,15 +195,13 @@ class AOTSnapshotter {
|
|||
genSnapshotArgs.add(mainPath);
|
||||
|
||||
final SnapshotType snapshotType = SnapshotType(platform, buildMode);
|
||||
final int genSnapshotExitCode =
|
||||
await _timedStep('snapshot(CompileTime)', 'aot-snapshot',
|
||||
() => genSnapshot.run(
|
||||
final int genSnapshotExitCode = await _genSnapshot.run(
|
||||
snapshotType: snapshotType,
|
||||
additionalArgs: genSnapshotArgs,
|
||||
darwinArch: darwinArch,
|
||||
));
|
||||
);
|
||||
if (genSnapshotExitCode != 0) {
|
||||
globals.printError('Dart snapshot generator failed with exit code $genSnapshotExitCode');
|
||||
_logger.printError('Dart snapshot generator failed with exit code $genSnapshotExitCode');
|
||||
return genSnapshotExitCode;
|
||||
}
|
||||
|
||||
|
@ -212,7 +235,7 @@ class AOTSnapshotter {
|
|||
}) async {
|
||||
final String targetArch = getNameForDarwinArch(appleArch);
|
||||
if (!quiet) {
|
||||
globals.printStatus('Building App.framework for $targetArch...');
|
||||
_logger.printStatus('Building App.framework for $targetArch...');
|
||||
}
|
||||
|
||||
final List<String> commonBuildOptions = <String>[
|
||||
|
@ -222,15 +245,15 @@ class AOTSnapshotter {
|
|||
];
|
||||
|
||||
const String embedBitcodeArg = '-fembed-bitcode';
|
||||
final String assemblyO = globals.fs.path.join(outputPath, 'snapshot_assembly.o');
|
||||
final String assemblyO = _fileSystem.path.join(outputPath, 'snapshot_assembly.o');
|
||||
List<String> isysrootArgs;
|
||||
if (isIOS) {
|
||||
final String iPhoneSDKLocation = await globals.xcode.sdkLocation(SdkType.iPhone);
|
||||
final String iPhoneSDKLocation = await _xcode.sdkLocation(SdkType.iPhone);
|
||||
if (iPhoneSDKLocation != null) {
|
||||
isysrootArgs = <String>['-isysroot', iPhoneSDKLocation];
|
||||
}
|
||||
}
|
||||
final RunResult compileResult = await globals.xcode.cc(<String>[
|
||||
final RunResult compileResult = await _xcode.cc(<String>[
|
||||
'-arch', targetArch,
|
||||
if (isysrootArgs != null) ...isysrootArgs,
|
||||
if (bitcode) embedBitcodeArg,
|
||||
|
@ -240,13 +263,13 @@ class AOTSnapshotter {
|
|||
assemblyO,
|
||||
]);
|
||||
if (compileResult.exitCode != 0) {
|
||||
globals.printError('Failed to compile AOT snapshot. Compiler terminated with exit code ${compileResult.exitCode}');
|
||||
_logger.printError('Failed to compile AOT snapshot. Compiler terminated with exit code ${compileResult.exitCode}');
|
||||
return compileResult;
|
||||
}
|
||||
|
||||
final String frameworkDir = globals.fs.path.join(outputPath, 'App.framework');
|
||||
globals.fs.directory(frameworkDir).createSync(recursive: true);
|
||||
final String appLib = globals.fs.path.join(frameworkDir, 'App');
|
||||
final String frameworkDir = _fileSystem.path.join(outputPath, 'App.framework');
|
||||
_fileSystem.directory(frameworkDir).createSync(recursive: true);
|
||||
final String appLib = _fileSystem.path.join(frameworkDir, 'App');
|
||||
final List<String> linkArgs = <String>[
|
||||
...commonBuildOptions,
|
||||
'-dynamiclib',
|
||||
|
@ -258,64 +281,13 @@ class AOTSnapshotter {
|
|||
'-o', appLib,
|
||||
assemblyO,
|
||||
];
|
||||
final RunResult linkResult = await globals.xcode.clang(linkArgs);
|
||||
final RunResult linkResult = await _xcode.clang(linkArgs);
|
||||
if (linkResult.exitCode != 0) {
|
||||
globals.printError('Failed to link AOT snapshot. Linker terminated with exit code ${compileResult.exitCode}');
|
||||
_logger.printError('Failed to link AOT snapshot. Linker terminated with exit code ${compileResult.exitCode}');
|
||||
}
|
||||
return linkResult;
|
||||
}
|
||||
|
||||
/// Compiles a Dart file to kernel.
|
||||
///
|
||||
/// Returns the output kernel file path, or null on failure.
|
||||
Future<String> compileKernel({
|
||||
@required TargetPlatform platform,
|
||||
@required BuildMode buildMode,
|
||||
@required String mainPath,
|
||||
@required String packagesPath,
|
||||
@required String outputPath,
|
||||
@required bool trackWidgetCreation,
|
||||
@required List<String> dartDefines,
|
||||
List<String> extraFrontEndOptions = const <String>[],
|
||||
}) async {
|
||||
final FlutterProject flutterProject = FlutterProject.current();
|
||||
final Directory outputDir = globals.fs.directory(outputPath);
|
||||
outputDir.createSync(recursive: true);
|
||||
|
||||
globals.printTrace('Compiling Dart to kernel: $mainPath');
|
||||
|
||||
if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty) {
|
||||
globals.printTrace('Extra front-end options: $extraFrontEndOptions');
|
||||
}
|
||||
|
||||
final String depfilePath = globals.fs.path.join(outputPath, 'kernel_compile.d');
|
||||
final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(flutterProject);
|
||||
final CompilerOutput compilerOutput =
|
||||
await _timedStep('frontend(CompileTime)', 'aot-kernel',
|
||||
() => kernelCompiler.compile(
|
||||
sdkRoot: globals.artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
|
||||
mainPath: mainPath,
|
||||
packagesPath: packagesPath,
|
||||
outputFilePath: getKernelPathForTransformerOptions(
|
||||
globals.fs.path.join(outputPath, 'app.dill'),
|
||||
trackWidgetCreation: trackWidgetCreation,
|
||||
),
|
||||
depFilePath: depfilePath,
|
||||
extraFrontEndOptions: extraFrontEndOptions,
|
||||
linkPlatformKernelIn: true,
|
||||
aot: true,
|
||||
buildMode: buildMode,
|
||||
trackWidgetCreation: trackWidgetCreation,
|
||||
dartDefines: dartDefines,
|
||||
));
|
||||
|
||||
// Write path to frontend_server, since things need to be re-generated when that changes.
|
||||
final String frontendPath = globals.artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk);
|
||||
globals.fs.directory(outputPath).childFile('frontend_server.d').writeAsStringSync('frontend_server.d: $frontendPath\n');
|
||||
|
||||
return compilerOutput?.outputFilename;
|
||||
}
|
||||
|
||||
bool _isValidAotPlatform(TargetPlatform platform, BuildMode buildMode) {
|
||||
if (buildMode == BuildMode.debug) {
|
||||
return false;
|
||||
|
@ -328,19 +300,4 @@ class AOTSnapshotter {
|
|||
TargetPlatform.darwin_x64,
|
||||
].contains(platform);
|
||||
}
|
||||
|
||||
/// This method is used to measure duration of an action and emit it into
|
||||
/// verbose output from flutter_tool for other tools (e.g. benchmark runner)
|
||||
/// to find.
|
||||
/// Important: external performance tracking tools expect format of this
|
||||
/// output to be stable.
|
||||
Future<T> _timedStep<T>(String marker, String analyticsVar, FutureOr<T> Function() action) async {
|
||||
final Stopwatch sw = Stopwatch()..start();
|
||||
final T value = await action();
|
||||
if (reportTimings) {
|
||||
globals.printStatus('$marker: ${sw.elapsedMilliseconds} ms.');
|
||||
}
|
||||
globals.flutterUsage.sendTiming('build', analyticsVar, Duration(milliseconds: sw.elapsedMilliseconds));
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -697,7 +697,7 @@ abstract class Status {
|
|||
@required Duration timeout,
|
||||
@required TimeoutConfiguration timeoutConfiguration,
|
||||
@required Stopwatch stopwatch,
|
||||
@required AnsiTerminal terminal,
|
||||
@required Terminal terminal,
|
||||
VoidCallback onFinish,
|
||||
SlowWarningCallback slowWarningCallback,
|
||||
}) {
|
||||
|
@ -877,7 +877,7 @@ class AnsiSpinner extends Status {
|
|||
@required Duration timeout,
|
||||
@required TimeoutConfiguration timeoutConfiguration,
|
||||
@required Stopwatch stopwatch,
|
||||
@required AnsiTerminal terminal,
|
||||
@required Terminal terminal,
|
||||
VoidCallback onFinish,
|
||||
this.slowWarningCallback,
|
||||
Stdio stdio,
|
||||
|
@ -893,7 +893,7 @@ class AnsiSpinner extends Status {
|
|||
final String _backspaceChar = '\b';
|
||||
final String _clearChar = ' ';
|
||||
final Stdio _stdio;
|
||||
final AnsiTerminal _terminal;
|
||||
final Terminal _terminal;
|
||||
|
||||
bool timedOut = false;
|
||||
|
||||
|
|
|
@ -210,7 +210,14 @@ class AndroidAot extends AotElfBase {
|
|||
|
||||
@override
|
||||
Future<void> build(Environment environment) async {
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: false);
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(
|
||||
reportTimings: false,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
xcode: globals.xcode,
|
||||
processManager: globals.processManager,
|
||||
artifacts: globals.artifacts,
|
||||
);
|
||||
final Directory output = environment.buildDir.childDirectory(_androidAbiName);
|
||||
final String splitDebugInfo = environment.defines[kSplitDebugInfo];
|
||||
if (environment.defines[kBuildMode] == null) {
|
||||
|
|
|
@ -204,9 +204,7 @@ class KernelSnapshot extends Target {
|
|||
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
|
||||
|
||||
// This configuration is all optional.
|
||||
final List<String> extraFrontEndOptions = <String>[
|
||||
...?environment.defines[kExtraFrontEndOptions]?.split(',')
|
||||
];
|
||||
final List<String> extraFrontEndOptions = environment.defines[kExtraFrontEndOptions]?.split(',');
|
||||
final List<String> fileSystemRoots = environment.defines[kFileSystemRoots]?.split(',');
|
||||
final String fileSystemScheme = environment.defines[kFileSystemScheme];
|
||||
|
||||
|
@ -261,7 +259,14 @@ abstract class AotElfBase extends Target {
|
|||
|
||||
@override
|
||||
Future<void> build(Environment environment) async {
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: false);
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(
|
||||
reportTimings: false,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
xcode: globals.xcode,
|
||||
processManager: globals.processManager,
|
||||
artifacts: globals.artifacts,
|
||||
);
|
||||
final String outputPath = environment.buildDir.path;
|
||||
if (environment.defines[kBuildMode] == null) {
|
||||
throw MissingDefineException(kBuildMode, 'aot_elf');
|
||||
|
|
|
@ -28,7 +28,14 @@ abstract class AotAssemblyBase extends Target {
|
|||
|
||||
@override
|
||||
Future<void> build(Environment environment) async {
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: false);
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(
|
||||
reportTimings: false,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
xcode: globals.xcode,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: globals.processManager,
|
||||
);
|
||||
final String buildOutputPath = environment.buildDir.path;
|
||||
if (environment.defines[kBuildMode] == null) {
|
||||
throw MissingDefineException(kBuildMode, 'aot_assembly');
|
||||
|
@ -36,6 +43,8 @@ abstract class AotAssemblyBase extends Target {
|
|||
if (environment.defines[kTargetPlatform] == null) {
|
||||
throw MissingDefineException(kTargetPlatform, 'aot_assembly');
|
||||
}
|
||||
final List<String> extraGenSnapshotOptions = environment
|
||||
.defines[kExtraGenSnapshotOptions]?.split(',') ?? const <String>[];
|
||||
final bool bitcode = environment.defines[kBitcodeFlag] == 'true';
|
||||
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
|
||||
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
|
||||
|
@ -65,6 +74,7 @@ abstract class AotAssemblyBase extends Target {
|
|||
quiet: true,
|
||||
splitDebugInfo: splitDebugInfo,
|
||||
dartObfuscation: dartObfuscation,
|
||||
extraGenSnapshotOptions: extraGenSnapshotOptions,
|
||||
));
|
||||
}
|
||||
final List<int> results = await Future.wait(pending);
|
||||
|
|
|
@ -202,7 +202,15 @@ class CompileMacOSFramework extends Target {
|
|||
}
|
||||
final String splitDebugInfo = environment.defines[kSplitDebugInfo];
|
||||
final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true';
|
||||
final int result = await AOTSnapshotter(reportTimings: false).build(
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(
|
||||
reportTimings: false,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
xcode: globals.xcode,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: globals.processManager
|
||||
);
|
||||
final int result = await snapshotter.build(
|
||||
bitcode: false,
|
||||
buildMode: buildMode,
|
||||
mainPath: environment.buildDir.childFile('app.dill').path,
|
||||
|
|
|
@ -27,11 +27,6 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
|
|||
allowed: <String>['android-arm', 'android-arm64', 'ios', 'android-x64'],
|
||||
)
|
||||
..addFlag('quiet', defaultsTo: false)
|
||||
..addFlag('report-timings',
|
||||
negatable: false,
|
||||
defaultsTo: false,
|
||||
help: 'Report timing information about build steps in machine readable form,',
|
||||
)
|
||||
..addMultiOption('ios-arch',
|
||||
splitCommas: true,
|
||||
defaultsTo: defaultIOSArchs.map<String>(getNameForDarwinArch),
|
||||
|
@ -80,7 +75,6 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
|
|||
mainDartFile: findMainDartFile(targetFile),
|
||||
bitcode: boolArg('bitcode'),
|
||||
quiet: boolArg('quiet'),
|
||||
reportTimings: boolArg('report-timings'),
|
||||
iosBuildArchs: stringsArg('ios-arch').map<DarwinArch>(getIOSArchForName),
|
||||
);
|
||||
return FlutterCommandResult.success();
|
||||
|
|
|
@ -436,7 +436,6 @@ end
|
|||
mainDartFile: globals.fs.path.absolute(targetFile),
|
||||
quiet: true,
|
||||
bitcode: true,
|
||||
reportTimings: false,
|
||||
iosBuildArchs: <DarwinArch>[DarwinArch.armv7, DarwinArch.arm64],
|
||||
);
|
||||
} finally {
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'android/gradle_utils.dart';
|
|||
import 'application_package.dart';
|
||||
import 'artifacts.dart';
|
||||
import 'asset.dart';
|
||||
import 'base/build.dart';
|
||||
import 'base/config.dart';
|
||||
import 'base/context.dart';
|
||||
import 'base/io.dart';
|
||||
|
@ -125,7 +124,6 @@ Future<T> runInContext<T>(
|
|||
FuchsiaDeviceTools: () => FuchsiaDeviceTools(),
|
||||
FuchsiaSdk: () => FuchsiaSdk(),
|
||||
FuchsiaWorkflow: () => FuchsiaWorkflow(),
|
||||
GenSnapshot: () => const GenSnapshot(),
|
||||
GradleUtils: () => GradleUtils(),
|
||||
HotRunnerConfig: () => HotRunnerConfig(),
|
||||
IMobileDevice: () => IMobileDevice(),
|
||||
|
|
|
@ -249,7 +249,7 @@ class XcodeProjectInterpreter {
|
|||
@required ProcessManager processManager,
|
||||
@required Logger logger,
|
||||
@required FileSystem fileSystem,
|
||||
@required AnsiTerminal terminal,
|
||||
@required Terminal terminal,
|
||||
}) : _platform = platform,
|
||||
_fileSystem = fileSystem,
|
||||
_terminal = terminal,
|
||||
|
@ -259,7 +259,7 @@ class XcodeProjectInterpreter {
|
|||
final Platform _platform;
|
||||
final FileSystem _fileSystem;
|
||||
final ProcessUtils _processUtils;
|
||||
final AnsiTerminal _terminal;
|
||||
final Terminal _terminal;
|
||||
final Logger _logger;
|
||||
|
||||
static const String _executable = '/usr/bin/xcodebuild';
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,6 @@
|
|||
import 'package:flutter_tools/src/base/build.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/process.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/dart.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/macos.dart';
|
||||
|
@ -49,7 +48,6 @@ void main() {
|
|||
Testbed testbed;
|
||||
Environment environment;
|
||||
MockPlatform mockPlatform;
|
||||
MockXcode mockXcode;
|
||||
|
||||
setUpAll(() {
|
||||
Cache.disableLocking();
|
||||
|
@ -57,7 +55,6 @@ void main() {
|
|||
});
|
||||
|
||||
setUp(() {
|
||||
mockXcode = MockXcode();
|
||||
mockPlatform = MockPlatform();
|
||||
when(mockPlatform.isWindows).thenReturn(false);
|
||||
when(mockPlatform.isMacOS).thenReturn(true);
|
||||
|
@ -193,35 +190,6 @@ void main() {
|
|||
|
||||
expect(outputFramework.readAsStringSync(), 'DEF');
|
||||
}));
|
||||
|
||||
test('release/profile macOS compilation uses correct gen_snapshot', () => testbed.run(() async {
|
||||
when(genSnapshot.run(
|
||||
snapshotType: anyNamed('snapshotType'),
|
||||
additionalArgs: anyNamed('additionalArgs'),
|
||||
darwinArch: anyNamed('darwinArch'),
|
||||
)).thenAnswer((Invocation invocation) {
|
||||
environment.buildDir.childFile('snapshot_assembly.o').createSync();
|
||||
environment.buildDir.childFile('snapshot_assembly.S').createSync();
|
||||
return Future<int>.value(0);
|
||||
});
|
||||
when(mockXcode.cc(any)).thenAnswer((Invocation invocation) {
|
||||
return Future<RunResult>.value(RunResult(FakeProcessResult()..exitCode = 0, <String>['test']));
|
||||
});
|
||||
when(mockXcode.clang(any)).thenAnswer((Invocation invocation) {
|
||||
return Future<RunResult>.value(RunResult(FakeProcessResult()..exitCode = 0, <String>['test']));
|
||||
});
|
||||
environment.buildDir.childFile('app.dill').createSync(recursive: true);
|
||||
globals.fs.file('.packages')
|
||||
..createSync()
|
||||
..writeAsStringSync('''
|
||||
# Generated
|
||||
sky_engine:file:///bin/cache/pkg/sky_engine/lib/
|
||||
flutter_tools:lib/''');
|
||||
await const CompileMacOSFramework().build(environment..defines[kBuildMode] = 'release');
|
||||
}, overrides: <Type, Generator>{
|
||||
GenSnapshot: () => MockGenSnapshot(),
|
||||
Xcode: () => mockXcode,
|
||||
}));
|
||||
}
|
||||
|
||||
class MockPlatform extends Mock implements Platform {}
|
||||
|
|
Loading…
Reference in a new issue