Skip to content

Remove Finder extended attributes in build target before code signing iOS frameworks #123896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions packages/flutter_tools/lib/src/build_system/targets/ios.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -463,7 +465,7 @@ abstract class IosAssetBundle extends Target {
}
final BuildMode buildMode = getBuildModeForName(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();
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -692,10 +694,16 @@ Future<void> _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<void> _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 = '-';
Expand All @@ -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);
}
Expand Down
4 changes: 1 addition & 3 deletions packages/flutter_tools/lib/src/ios/mac.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import 'dart:async';

import 'package:meta/meta.dart';
import 'package:process/process.dart';

import '../artifacts.dart';
Expand Down Expand Up @@ -493,8 +492,7 @@ Future<XcodeBuildResult> 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<void> removeFinderExtendedAttributes(Directory projectDirectory, ProcessUtils processUtils, Logger logger) async {
Future<void> removeFinderExtendedAttributes(FileSystemEntity projectDirectory, ProcessUtils processUtils, Logger logger) async {
final bool success = await processUtils.exitsHappy(
<String>[
'xattr',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ void main() {
'-o',
appFrameworkPath,
]),
FakeCommand(command: <String>[
'xattr',
'-r',
'-d',
'com.apple.FinderInfo',
appFrameworkPath,
]),
FakeCommand(command: <String>[
'codesign',
'--force',
Expand Down Expand Up @@ -141,6 +148,13 @@ void main() {
'-o',
appFrameworkPath,
]),
FakeCommand(command: <String>[
'xattr',
'-r',
'-d',
'com.apple.FinderInfo',
appFrameworkPath,
]),
FakeCommand(command: <String>[
'codesign',
'--force',
Expand Down Expand Up @@ -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>[
FakeCommand(command: <String>[
'xattr',
'-r',
'-d',
'com.apple.FinderInfo',
frameworkDirectoryBinary.path,
]),
FakeCommand(command: <String>[
'codesign',
'--force',
Expand All @@ -204,7 +225,7 @@ void main() {
'--timestamp=none',
frameworkDirectoryBinary.path,
]),
);
]);

await const DebugIosApplicationBundle().build(environment);
expect(processManager, hasNoRemainingExpectations);
Expand Down Expand Up @@ -267,6 +288,13 @@ void main() {
'--include=/',
'--include=/./shader_lib',
]),
FakeCommand(command: <String>[
'xattr',
'-r',
'-d',
'com.apple.FinderInfo',
frameworkDirectoryBinary.path,
]),
FakeCommand(command: <String>[
'codesign',
'--force',
Expand Down Expand Up @@ -323,15 +351,22 @@ void main() {

final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
final File frameworkDirectoryBinary = frameworkDirectory.childFile('App');
processManager.addCommand(
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
'xattr',
'-r',
'-d',
'com.apple.FinderInfo',
frameworkDirectoryBinary.path,
]),
FakeCommand(command: <String>[
'codesign',
'--force',
'--sign',
'ABC123',
frameworkDirectoryBinary.path,
]),
);
]);

await const ReleaseIosApplicationBundle().build(environment);
expect(processManager, hasNoRemainingExpectations);
Expand Down Expand Up @@ -371,15 +406,22 @@ void main() {

final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
final File frameworkDirectoryBinary = frameworkDirectory.childFile('App');
processManager.addCommand(
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
'xattr',
'-r',
'-d',
'com.apple.FinderInfo',
frameworkDirectoryBinary.path,
]),
FakeCommand(command: <String>[
'codesign',
'--force',
'--sign',
'-',
frameworkDirectoryBinary.path,
]),
);
]);

await const ReleaseIosApplicationBundle().build(environment);
expect(usage.events, contains(const TestUsageEvent('assemble', 'ios-archive', label: 'success')));
Expand Down Expand Up @@ -466,6 +508,7 @@ void main() {
late FakeCommand copyPhysicalFrameworkCommand;
late FakeCommand lipoCommandNonFatResult;
late FakeCommand lipoVerifyArm64Command;
late FakeCommand xattrCommand;
late FakeCommand adHocCodesignCommand;

setUp(() {
Expand Down Expand Up @@ -495,6 +538,14 @@ void main() {
'arm64',
]);

xattrCommand = FakeCommand(command: <String>[
'xattr',
'-r',
'-d',
'com.apple.FinderInfo',
binary.path,
]);

adHocCodesignCommand = FakeCommand(command: <String>[
'codesign',
'--force',
Expand Down Expand Up @@ -538,6 +589,7 @@ void main() {
'-verify_arch',
'x86_64',
]),
xattrCommand,
adHocCodesignCommand,
]);
await const DebugUnpackIOS().build(environment);
Expand Down Expand Up @@ -684,6 +736,7 @@ void main() {
copyPhysicalFrameworkCommand,
lipoCommandNonFatResult,
lipoVerifyArm64Command,
xattrCommand,
adHocCodesignCommand,
]);
await const DebugUnpackIOS().build(environment);
Expand Down Expand Up @@ -733,6 +786,7 @@ void main() {
'armv7',
binary.path,
]),
xattrCommand,
adHocCodesignCommand,
]);

Expand Down Expand Up @@ -810,6 +864,7 @@ void main() {
copyPhysicalFrameworkCommand,
lipoCommandNonFatResult,
lipoVerifyArm64Command,
xattrCommand,
adHocCodesignCommand,
]);
await const DebugUnpackIOS().build(environment);
Expand Down Expand Up @@ -838,6 +893,7 @@ void main() {
copyPhysicalFrameworkCommand,
lipoCommandNonFatResult,
lipoVerifyArm64Command,
xattrCommand,
FakeCommand(command: <String>[
'codesign',
'--force',
Expand Down Expand Up @@ -885,6 +941,7 @@ void main() {
copyPhysicalFrameworkCommand,
lipoCommandNonFatResult,
lipoVerifyArm64Command,
xattrCommand,
FakeCommand(command: <String>[
'codesign',
'--force',
Expand Down