Skip to content

Commit 8ea86fb

Browse files
committed
Add iOS build tracing support
- Add --trace option to flutter build ios / flutter build ipa - Pass TRACE_FILE through Xcode build settings to xcode_backend.dart - Instrument buildXcodeProject() in mac.dart with pre-xcode, xcode, and post-xcode spans - Merge flutter assemble trace events from intermediate file - Remove TRACE_FILE from toEnvironmentConfig() since both Android and iOS orchestrators compute intermediate paths directly
1 parent 4288514 commit 8ea86fb

4 files changed

Lines changed: 76 additions & 2 deletions

File tree

packages/flutter_tools/bin/xcode_backend.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,13 @@ class Context {
722722
);
723723
}
724724

725+
if (environment['TRACE_FILE'] != null &&
726+
environment['TRACE_FILE']!.isNotEmpty) {
727+
flutterArgs.add(
728+
'--trace-file=${environment['TRACE_FILE']}',
729+
);
730+
}
731+
725732
if (environment['CODE_SIZE_DIRECTORY'] != null &&
726733
environment['CODE_SIZE_DIRECTORY']!.isNotEmpty) {
727734
flutterArgs.add('-dCodeSizeDirectory=${environment['CODE_SIZE_DIRECTORY']}');

packages/flutter_tools/lib/src/build_info.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,6 @@ class BuildInfo {
359359
'TREE_SHAKE_ICONS': treeShakeIcons.toString(),
360360
if (performanceMeasurementFile != null)
361361
'PERFORMANCE_MEASUREMENT_FILE': performanceMeasurementFile!,
362-
if (traceFilePath != null)
363-
'TRACE_FILE': traceFilePath!,
364362
'PACKAGE_CONFIG': packageConfigPath,
365363
'CODE_SIZE_DIRECTORY': ?codeSizeDirectory,
366364
'FLAVOR': ?flavor,

packages/flutter_tools/lib/src/commands/build_ios.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,7 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand {
907907
usesExtraDartFlagOptions(verboseHelp: verboseHelp);
908908
addEnableExperimentation(hide: !verboseHelp);
909909
addBuildPerformanceFile(hide: !verboseHelp);
910+
usesBuildTraceOption(hide: !verboseHelp);
910911
usesAnalyzeSizeFlag();
911912
argParser.addFlag(
912913
'codesign',

packages/flutter_tools/lib/src/ios/mac.dart

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import '../base/project_migrator.dart';
1818
import '../base/utils.dart';
1919
import '../base/version.dart';
2020
import '../build_info.dart';
21+
import '../build_system/build_trace.dart';
2122
import '../cache.dart';
2223
import '../darwin/darwin.dart';
2324
import '../device.dart';
@@ -353,6 +354,26 @@ Future<XcodeBuildResult> buildXcodeProject({
353354
return XcodeBuildResult(success: true);
354355
}
355356

357+
final int buildStartMicros = DateTime.now().microsecondsSinceEpoch;
358+
final BuildTracer? tracer = buildInfo.traceFilePath != null
359+
? BuildTracer()
360+
: null;
361+
362+
// Pass trace file path as an intermediate location for flutter assemble.
363+
// mac.dart will merge this into the final trace file.
364+
final String? assembleTraceFilePath;
365+
if (buildInfo.traceFilePath != null) {
366+
assembleTraceFilePath = globals.fs.path.join(
367+
globals.fs.currentDirectory.path,
368+
getBuildDirectory(),
369+
'ios',
370+
'flutter_assemble_trace.json',
371+
);
372+
buildCommands.add('TRACE_FILE=$assembleTraceFilePath');
373+
} else {
374+
assembleTraceFilePath = null;
375+
}
376+
356377
if (globals.logger.isVerbose) {
357378
// An environment variable to be passed to xcode_backend.sh determining
358379
// whether to echo back executed commands.
@@ -531,6 +552,16 @@ Future<XcodeBuildResult> buildXcodeProject({
531552
]);
532553
}
533554

555+
final int preXcodeEndMicros = DateTime.now().microsecondsSinceEpoch;
556+
tracer?.addCompleteEvent(
557+
name: 'pre-xcode setup',
558+
cat: 'flutter',
559+
tid: 1,
560+
startMicros: buildStartMicros,
561+
endMicros: preXcodeEndMicros,
562+
);
563+
564+
final int xcodeStartMicros = DateTime.now().microsecondsSinceEpoch;
534565
final sw = Stopwatch()..start();
535566
initialBuildStatus = globals.logger.startProgress('Running Xcode build...');
536567

@@ -555,6 +586,43 @@ Future<XcodeBuildResult> buildXcodeProject({
555586
),
556587
);
557588

589+
// Record Xcode span and merge assemble trace if tracing is enabled.
590+
if (tracer != null) {
591+
final int xcodeEndMicros = DateTime.now().microsecondsSinceEpoch;
592+
tracer.addCompleteEvent(
593+
name: 'xcode ${xcodeBuildActionToString(buildAction)}',
594+
cat: 'xcode',
595+
tid: 2,
596+
startMicros: xcodeStartMicros,
597+
endMicros: xcodeEndMicros,
598+
);
599+
// Merge the assemble trace file that flutter assemble wrote.
600+
if (assembleTraceFilePath != null) {
601+
final File assembleTraceFile = globals.fs.file(assembleTraceFilePath);
602+
tracer.mergeEventsFromFile(assembleTraceFile);
603+
}
604+
tracer.addCompleteEvent(
605+
name: 'post-xcode processing',
606+
cat: 'flutter',
607+
tid: 1,
608+
startMicros: xcodeEndMicros,
609+
endMicros: DateTime.now().microsecondsSinceEpoch,
610+
);
611+
tracer.addCompleteEvent(
612+
name: 'flutter build ios',
613+
cat: 'flutter',
614+
tid: 1,
615+
startMicros: buildStartMicros,
616+
endMicros: DateTime.now().microsecondsSinceEpoch,
617+
);
618+
final File traceFile = globals.fs.file(buildInfo.traceFilePath);
619+
tracer.writeToFile(traceFile);
620+
globals.printStatus(
621+
'Build trace written to ${buildInfo.traceFilePath}. '
622+
'View at https://ui.perfetto.dev',
623+
);
624+
}
625+
558626
if (tempDir.existsSync()) {
559627
// Display additional warning and error message from xcresult bundle.
560628
final Directory resultBundle = tempDir.childDirectory(_kResultBundlePath);

0 commit comments

Comments
 (0)