From d74f2fc56ccb01b62c2bb40313c54c84673b7ddc Mon Sep 17 00:00:00 2001 From: flutteractionsbot <154381524+flutteractionsbot@users.noreply.github.com> Date: Tue, 28 Oct 2025 10:40:54 -0700 Subject: [PATCH] [CP-beta]Add guided error for precompiled cache error (#177607) This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md#automatically-creates-a-cherry-pick-request) Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request. ### Issue Link: What is the link to the issue this cherry-pick is addressing? https://github.com/flutter/flutter/issues/176462 ### Changelog Description: Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/blob/main/docs/releases/Hotfix-Documentation-Best-Practices.md) for examples Provides guided error message when building for iOS fails due to precompiled headers cache error. ### Impact Description: What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch) When using Xcode 26 and switching between branches or upgrading to new beta/stable, it throws an error due to headers of the Flutter framework changing. ### Workaround: Is there a workaround for this issue? Run `flutter clean` ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? ### Validation Steps: What are the steps to validate that this fix works? 1. git checkout 3.35.5 2. `flutter create my_app` 3. `flutter build ios` 4. git checkout main 5. `flutter build ios` (it should error) --- packages/flutter_tools/lib/src/ios/mac.dart | 20 ++++++++ .../test/general.shard/ios/mac_test.dart | 50 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index 200120f8dde..d61c40d1e50 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -918,6 +918,12 @@ _XCResultIssueHandlingResult _handleXCResultIssue({ missingModule: missingModule, ); } + } else if (message.toLowerCase().contains('has been modified since')) { + return _XCResultIssueHandlingResult( + requiresProvisioningProfile: false, + hasProvisioningProfileIssue: false, + modifiedPrecompiledSource: true, + ); } return _XCResultIssueHandlingResult( requiresProvisioningProfile: false, @@ -937,6 +943,7 @@ Future _handleIssues( var requiresProvisioningProfile = false; var hasProvisioningProfileIssue = false; var issueDetected = false; + var modifiedPrecompiledSource = false; String? missingPlatform; final duplicateModules = []; final missingModules = []; @@ -962,6 +969,7 @@ Future _handleIssues( if (handlingResult.missingModule != null) { missingModules.add(handlingResult.missingModule!); } + modifiedPrecompiledSource = handlingResult.modifiedPrecompiledSource; issueDetected = true; } } else if (xcResult != null) { @@ -1032,6 +1040,13 @@ Future _handleIssues( ); } } + } else if (modifiedPrecompiledSource) { + logger.printError( + '════════════════════════════════════════════════════════════════════════════════\n' + 'A precompiled file has been changed since last built. Please run "flutter clean" to clear ' + 'the cache.\n' + '════════════════════════════════════════════════════════════════════════════════', + ); } return issueDetected; } @@ -1169,6 +1184,7 @@ class _XCResultIssueHandlingResult { this.missingPlatform, this.duplicateModule, this.missingModule, + this.modifiedPrecompiledSource = false, }); /// An issue indicates that user didn't provide the provisioning profile. @@ -1186,6 +1202,10 @@ class _XCResultIssueHandlingResult { /// An issue indicates a module was imported but not found, potentially due /// to it being Swift Package Manager compatible only. final String? missingModule; + + /// An issue indicates that a source file, such as a header in the Flutter framework, has + /// changed since last built. This requires "flutter clean" to resolve. + final bool modifiedPrecompiledSource; } const _kResultBundlePath = 'temporary_xcresult_bundle'; diff --git a/packages/flutter_tools/test/general.shard/ios/mac_test.dart b/packages/flutter_tools/test/general.shard/ios/mac_test.dart index b1598f53723..12a2aed2a5f 100644 --- a/packages/flutter_tools/test/general.shard/ios/mac_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/mac_test.dart @@ -670,6 +670,56 @@ duplicate symbol '_$s29plugin_1_name23PluginNamePluginC9setDouble3key5valueySS_S Pub: ThrowingPub.new, }, ); + + testWithoutContext('parses file has been modified error', () async { + const buildCommands = ['xcrun', 'cc', 'blah']; + final buildResult = XcodeBuildResult( + success: false, + stdout: '', + xcodeBuildExecution: XcodeBuildExecution( + buildCommands: buildCommands, + appDirectory: '/blah/blah', + environmentType: EnvironmentType.physical, + buildSettings: buildSettings, + ), + xcResult: XCResult.test( + issues: [ + XCResultIssue.test( + message: + "File 'path/to/Flutter.framework/Headers/FlutterPlugin.h' has been modified since " + "the precompiled header 'path/to/Runner.build/Objects-normal/arm64/Runner-primary-Bridging-header.pch'" + ' was built: size changed (was 18306, now 16886)', + subType: 'Error', + ), + XCResultIssue.test( + message: + "File 'path/to/Flutter.framework/Headers/FlutterEngine.h' has been modified since " + "the precompiled header 'path/to/Runner.build/Objects-normal/arm64/Runner-primary-Bridging-header.pch'" + ' was built: size changed (was 18306, now 16886)', + subType: 'Error', + ), + ], + ), + ); + final fs = MemoryFileSystem.test(); + final project = FakeFlutterProject(fileSystem: fs, usesSwiftPackageManager: true); + project.ios.podfile.createSync(recursive: true); + await diagnoseXcodeBuildFailure( + buildResult, + logger: logger, + analytics: fakeAnalytics, + fileSystem: fs, + platform: FlutterDarwinPlatform.ios, + project: project, + ); + expect( + logger.errorText, + contains( + 'A precompiled file has been changed since last built. Please run "flutter clean" to ' + 'clear the cache.', + ), + ); + }); }); group('Upgrades project.pbxproj for old asset usage', () {