Unverified Commit 590f22ce authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] restore report timings functionality to build aot (#52918)

parent a0d93f96
......@@ -30,6 +30,7 @@ class AotBuilder {
bool bitcode = kBitcodeEnabledDefault,
bool quiet = true,
Iterable<DarwinArch> iosBuildArchs = defaultIOSArchs,
bool reportTimings,
}) async {
if (platform == null) {
throwToolExit('No AOT build platform specified');
......@@ -106,6 +107,21 @@ class AotBuilder {
throwToolExit('The aot build failed.');
}
// This print output is used by the dart team for build benchmarks.
if (reportTimings) {
final PerformanceMeasurement kernel = result.performance['kernel_snapshot'];
PerformanceMeasurement aot;
if (expectSo) {
aot = result.performance.values.firstWhere(
(PerformanceMeasurement measurement) => measurement.analyicsName == 'android_aot');
} else {
aot = result.performance.values.firstWhere(
(PerformanceMeasurement measurement) => measurement.analyicsName == 'ios_aot');
}
globals.printStatus('frontend(CompileTime): ${kernel.elapsedMilliseconds} ms.');
globals.printStatus('snapshot(CompileTime): ${aot.elapsedMilliseconds} ms.');
}
if (expectSo) {
environment.buildDir.childFile('app.so')
.copySync(globals.fs.path.join(outputPath, 'app.so'));
......
......@@ -114,6 +114,14 @@ abstract class Target {
/// argument to build a particular target.
String get name;
/// A name that measurements can be categorized under for this [Target].
///
/// Unlike [name], this is not expected to be unique, so multiple targets
/// that are conceptually the same can share an analytics name.
///
/// If not provided, defaults to [name]
String get analyticsName => name;
/// The dependencies of this target.
List<Target> get dependencies;
......@@ -594,7 +602,12 @@ class _BuildInstance {
resource.release();
stopwatch.stop();
stepTimings[node.target.name] = PerformanceMeasurement(
node.target.name, stopwatch.elapsedMilliseconds, skipped, passed);
target: node.target.name,
elapsedMilliseconds: stopwatch.elapsedMilliseconds,
skipped: skipped,
passed: passed,
analyicsName: node.target.analyticsName,
);
}
return passed;
}
......@@ -617,11 +630,19 @@ class ExceptionMeasurement {
/// Helper class to collect measurement data.
class PerformanceMeasurement {
PerformanceMeasurement(this.target, this.elapsedMilliseconds, this.skipped, this.passed);
PerformanceMeasurement({
@required this.target,
@required this.elapsedMilliseconds,
@required this.skipped,
@required this.passed,
@required this.analyicsName,
});
final int elapsedMilliseconds;
final String target;
final bool skipped;
final bool passed;
final String analyicsName;
}
/// Check if there are any dependency cycles in the target.
......
......@@ -257,6 +257,9 @@ class KernelSnapshot extends Target {
abstract class AotElfBase extends Target {
const AotElfBase();
@override
String get analyticsName => 'android_aot';
@override
Future<void> build(Environment environment) async {
final AOTSnapshotter snapshotter = AOTSnapshotter(
......
......@@ -26,6 +26,9 @@ import 'icon_tree_shaker.dart';
abstract class AotAssemblyBase extends Target {
const AotAssemblyBase();
@override
String get analyticsName => 'ios_aot';
@override
Future<void> build(Environment environment) async {
final AOTSnapshotter snapshotter = AOTSnapshotter(
......
......@@ -45,7 +45,8 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
defaultsTo: kBitcodeEnabledDefault,
help: 'Build the AOT bundle with bitcode. Requires a compatible bitcode engine.',
hide: true,
);
)
..addFlag('report-timings', hide: true);
}
AotBuilder aotBuilder;
......@@ -76,6 +77,7 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
bitcode: boolArg('bitcode'),
quiet: boolArg('quiet'),
iosBuildArchs: stringsArg('ios-arch').map<DarwinArch>(getIOSArchForName),
reportTimings: boolArg('report-timings'),
);
return FlutterCommandResult.success();
}
......
......@@ -22,6 +22,10 @@ void main() {
Platform: () => FakePlatform(operatingSystem: 'linux', environment: const <String, String>{}),
});
test('Android AOT targets has analyicsName', () {
expect(androidArmProfile.analyticsName, 'android_aot');
});
testbed.test('debug bundle contains expected resources', () async {
final Environment environment = Environment.test(
globals.fs.currentDirectory,
......
......@@ -45,6 +45,11 @@ void main() {
});
});
test('iOS AOT targets has analyicsName', () {
expect(const AotAssemblyRelease().analyticsName, 'ios_aot');
expect(const AotAssemblyProfile().analyticsName, 'ios_aot');
});
test('DebugUniveralFramework creates expected binary with arm64 only arch', () => testbed.run(() async {
environment.defines[kIosArchs] = 'arm64';
processManager = FakeProcessManager.list(<FakeCommand>[
......
......@@ -3,10 +3,12 @@
// found in the LICENSE file.
import 'package:file/memory.dart';
import 'package:flutter_tools/src/aot.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/ios/bitcode.dart';
import 'package:flutter_tools/src/ios/plist_parser.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
......@@ -106,6 +108,48 @@ void main() {
PlistParser: () => mockPlistUtils,
});
testUsingContext('build aot outputs timing info', () async {
globals.fs.file('.dart_tool/flutter_build/cce09742720db17ffec62331bd7e42d5/app.so')
.createSync(recursive: true);
when(buildSystem.build(any, any))
.thenAnswer((Invocation invocation) async {
return BuildResult(success: true, performance: <String, PerformanceMeasurement>{
'kernel_snapshot': PerformanceMeasurement(
analyicsName: 'kernel_snapshot',
target: 'kernel_snapshot',
elapsedMilliseconds: 1000,
passed: true,
skipped: false,
),
'anything': PerformanceMeasurement(
analyicsName: 'android_aot',
target: 'anything',
elapsedMilliseconds: 1000,
passed: true,
skipped: false,
),
});
});
await AotBuilder().build(
platform: TargetPlatform.android_arm64,
outputPath: '/',
buildInfo: BuildInfo.release,
mainDartFile: globals.fs.path.join('lib', 'main.dart'),
reportTimings: true,
);
expect(testLogger.statusText, allOf(
contains('frontend(CompileTime): 1000 ms.'),
contains('snapshot(CompileTime): 1000 ms.'),
));
}, overrides: <Type, Generator>{
BuildSystem: () => MockBuildSystem(),
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('build aot can parse valid Xcode Clang version (11)', () async {
final Directory flutterFramework = memoryFileSystem.directory('ios_profile/Flutter.framework')
..createSync(recursive: true);
......@@ -227,3 +271,4 @@ void main() {
class MockXcode extends Mock implements Xcode {}
class MockPlistUtils extends Mock implements PlistParser {}
class MockBuildSystem extends Mock implements BuildSystem {}
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