[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)
This commit is contained in:
flutteractionsbot 2025-10-28 10:40:54 -07:00 committed by GitHub
parent 46b0f4eaed
commit d74f2fc56c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 70 additions and 0 deletions

View File

@ -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<bool> _handleIssues(
var requiresProvisioningProfile = false;
var hasProvisioningProfileIssue = false;
var issueDetected = false;
var modifiedPrecompiledSource = false;
String? missingPlatform;
final duplicateModules = <String>[];
final missingModules = <String>[];
@ -962,6 +969,7 @@ Future<bool> _handleIssues(
if (handlingResult.missingModule != null) {
missingModules.add(handlingResult.missingModule!);
}
modifiedPrecompiledSource = handlingResult.modifiedPrecompiledSource;
issueDetected = true;
}
} else if (xcResult != null) {
@ -1032,6 +1040,13 @@ Future<bool> _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';

View File

@ -670,6 +670,56 @@ duplicate symbol '_$s29plugin_1_name23PluginNamePluginC9setDouble3key5valueySS_S
Pub: ThrowingPub.new,
},
);
testWithoutContext('parses file has been modified error', () async {
const buildCommands = <String>['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>[
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', () {