diff --git a/packages/flutter_tools/lib/src/build_system/targets/ios.dart b/packages/flutter_tools/lib/src/build_system/targets/ios.dart index 7790e92d109..88fa91b7db3 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/ios.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/ios.dart @@ -9,8 +9,10 @@ import '../../base/build.dart'; import '../../base/common.dart'; import '../../base/file_system.dart'; import '../../base/io.dart'; +import '../../base/process.dart'; import '../../build_info.dart'; import '../../globals.dart' as globals; +import '../../ios/mac.dart'; import '../../macos/xcode.dart'; import '../../project.dart'; import '../../reporting/reporting.dart'; @@ -296,7 +298,7 @@ abstract class UnpackIOS extends Target { if (buildMode == BuildMode.release) { _bitcodeStripFramework(environment, frameworkBinaryPath); } - _signFramework(environment, frameworkBinaryPath, buildMode); + await _signFramework(environment, frameworkBinary, buildMode); } void _copyFramework(Environment environment, String sdkRoot) { @@ -463,7 +465,7 @@ abstract class IosAssetBundle extends Target { } final BuildMode buildMode = BuildMode.fromCliName(environmentBuildMode); final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework'); - final String frameworkBinaryPath = frameworkDirectory.childFile('App').path; + final File frameworkBinary = frameworkDirectory.childFile('App'); final Directory assetDirectory = frameworkDirectory.childDirectory('flutter_assets'); frameworkDirectory.createSync(recursive: true); assetDirectory.createSync(); @@ -474,7 +476,7 @@ abstract class IosAssetBundle extends Target { environment.buildDir .childDirectory('App.framework') .childFile('App') - .copySync(frameworkBinaryPath); + .copySync(frameworkBinary.path); final String vmSnapshotData = environment.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug); final String isolateSnapshotData = environment.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug); @@ -486,7 +488,7 @@ abstract class IosAssetBundle extends Target { .copySync(assetDirectory.childFile('isolate_snapshot_data').path); } else { environment.buildDir.childDirectory('App.framework').childFile('App') - .copySync(frameworkBinaryPath); + .copySync(frameworkBinary.path); } // Copy the dSYM @@ -539,7 +541,7 @@ abstract class IosAssetBundle extends Target { .childDirectory('App.framework') .childFile('Info.plist').path); - _signFramework(environment, frameworkBinaryPath, buildMode); + await _signFramework(environment, frameworkBinary, buildMode); } } @@ -692,10 +694,16 @@ Future _createStubAppFramework(File outputFile, Environment environment, } } - _signFramework(environment, outputFile.path, BuildMode.debug); + await _signFramework(environment, outputFile, BuildMode.debug); } -void _signFramework(Environment environment, String binaryPath, BuildMode buildMode) { +Future _signFramework(Environment environment, File binary, BuildMode buildMode) async { + await removeFinderExtendedAttributes( + binary, + ProcessUtils(processManager: environment.processManager, logger: environment.logger), + environment.logger, + ); + String? codesignIdentity = environment.defines[kCodesignIdentity]; if (codesignIdentity == null || codesignIdentity.isEmpty) { codesignIdentity = '-'; @@ -709,13 +717,13 @@ void _signFramework(Environment environment, String binaryPath, BuildMode buildM // Mimic Xcode's timestamp codesigning behavior on non-release binaries. '--timestamp=none', ], - binaryPath, + binary.path, ]); if (result.exitCode != 0) { final String stdout = (result.stdout as String).trim(); final String stderr = (result.stderr as String).trim(); final StringBuffer output = StringBuffer(); - output.writeln('Failed to codesign $binaryPath with identity $codesignIdentity.'); + output.writeln('Failed to codesign ${binary.path} with identity $codesignIdentity.'); if (stdout.isNotEmpty) { output.writeln(stdout); } diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index 29278ccf104..f0878f38bdc 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -4,7 +4,6 @@ import 'dart:async'; -import 'package:meta/meta.dart'; import 'package:process/process.dart'; import '../artifacts.dart'; @@ -493,8 +492,7 @@ Future buildXcodeProject({ /// Extended attributes applied by Finder can cause code signing errors. Remove them. /// https://developer.apple.com/library/archive/qa/qa1940/_index.html -@visibleForTesting -Future removeFinderExtendedAttributes(Directory projectDirectory, ProcessUtils processUtils, Logger logger) async { +Future removeFinderExtendedAttributes(FileSystemEntity projectDirectory, ProcessUtils processUtils, Logger logger) async { final bool success = await processUtils.exitsHappy( [ 'xattr', diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart index 2e1121f06fe..8d436ca6e9a 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart @@ -104,6 +104,13 @@ void main() { '-o', appFrameworkPath, ]), + FakeCommand(command: [ + 'xattr', + '-r', + '-d', + 'com.apple.FinderInfo', + appFrameworkPath, + ]), FakeCommand(command: [ 'codesign', '--force', @@ -141,6 +148,13 @@ void main() { '-o', appFrameworkPath, ]), + FakeCommand(command: [ + 'xattr', + '-r', + '-d', + 'com.apple.FinderInfo', + appFrameworkPath, + ]), FakeCommand(command: [ 'codesign', '--force', @@ -195,7 +209,14 @@ void main() { final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework'); final File frameworkDirectoryBinary = frameworkDirectory.childFile('App'); - processManager.addCommand( + processManager.addCommands([ + FakeCommand(command: [ + 'xattr', + '-r', + '-d', + 'com.apple.FinderInfo', + frameworkDirectoryBinary.path, + ]), FakeCommand(command: [ 'codesign', '--force', @@ -204,7 +225,7 @@ void main() { '--timestamp=none', frameworkDirectoryBinary.path, ]), - ); + ]); await const DebugIosApplicationBundle().build(environment); expect(processManager, hasNoRemainingExpectations); @@ -267,6 +288,13 @@ void main() { '--include=/', '--include=/./shader_lib', ]), + FakeCommand(command: [ + 'xattr', + '-r', + '-d', + 'com.apple.FinderInfo', + frameworkDirectoryBinary.path, + ]), FakeCommand(command: [ 'codesign', '--force', @@ -323,7 +351,14 @@ void main() { final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework'); final File frameworkDirectoryBinary = frameworkDirectory.childFile('App'); - processManager.addCommand( + processManager.addCommands([ + FakeCommand(command: [ + 'xattr', + '-r', + '-d', + 'com.apple.FinderInfo', + frameworkDirectoryBinary.path, + ]), FakeCommand(command: [ 'codesign', '--force', @@ -331,7 +366,7 @@ void main() { 'ABC123', frameworkDirectoryBinary.path, ]), - ); + ]); await const ReleaseIosApplicationBundle().build(environment); expect(processManager, hasNoRemainingExpectations); @@ -371,7 +406,14 @@ void main() { final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework'); final File frameworkDirectoryBinary = frameworkDirectory.childFile('App'); - processManager.addCommand( + processManager.addCommands([ + FakeCommand(command: [ + 'xattr', + '-r', + '-d', + 'com.apple.FinderInfo', + frameworkDirectoryBinary.path, + ]), FakeCommand(command: [ 'codesign', '--force', @@ -379,7 +421,7 @@ void main() { '-', frameworkDirectoryBinary.path, ]), - ); + ]); await const ReleaseIosApplicationBundle().build(environment); expect(usage.events, contains(const TestUsageEvent('assemble', 'ios-archive', label: 'success'))); @@ -466,6 +508,7 @@ void main() { late FakeCommand copyPhysicalFrameworkCommand; late FakeCommand lipoCommandNonFatResult; late FakeCommand lipoVerifyArm64Command; + late FakeCommand xattrCommand; late FakeCommand adHocCodesignCommand; setUp(() { @@ -495,6 +538,14 @@ void main() { 'arm64', ]); + xattrCommand = FakeCommand(command: [ + 'xattr', + '-r', + '-d', + 'com.apple.FinderInfo', + binary.path, + ]); + adHocCodesignCommand = FakeCommand(command: [ 'codesign', '--force', @@ -538,6 +589,7 @@ void main() { '-verify_arch', 'x86_64', ]), + xattrCommand, adHocCodesignCommand, ]); await const DebugUnpackIOS().build(environment); @@ -684,6 +736,7 @@ void main() { copyPhysicalFrameworkCommand, lipoCommandNonFatResult, lipoVerifyArm64Command, + xattrCommand, adHocCodesignCommand, ]); await const DebugUnpackIOS().build(environment); @@ -733,6 +786,7 @@ void main() { 'armv7', binary.path, ]), + xattrCommand, adHocCodesignCommand, ]); @@ -810,6 +864,7 @@ void main() { copyPhysicalFrameworkCommand, lipoCommandNonFatResult, lipoVerifyArm64Command, + xattrCommand, adHocCodesignCommand, ]); await const DebugUnpackIOS().build(environment); @@ -838,6 +893,7 @@ void main() { copyPhysicalFrameworkCommand, lipoCommandNonFatResult, lipoVerifyArm64Command, + xattrCommand, FakeCommand(command: [ 'codesign', '--force', @@ -885,6 +941,7 @@ void main() { copyPhysicalFrameworkCommand, lipoCommandNonFatResult, lipoVerifyArm64Command, + xattrCommand, FakeCommand(command: [ 'codesign', '--force',