Skip to content

Commit c719f03

Browse files
authored
[macOS] codesign native assets during embed (#148310)
Fixes flutter/flutter#148051 Currently only the "embed" phase, which is run during the Runner target build have access to code-signing identity. The flutter assemble target, which does the main build (and also builds native assets) does not have access to the code-signing identity. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [Features we expect every widget to implement]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat [Data Driven Fixes]: https://github.com/flutter/flutter/wiki/Data-driven-Fixes
1 parent 0d22d91 commit c719f03

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

packages/flutter_tools/bin/macos_assemble.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ EmbedFrameworks() {
191191
local native_assets_path="${project_path}/${FLUTTER_BUILD_DIR}/native_assets/macos/"
192192
if [[ -d "$native_assets_path" ]]; then
193193
RunCommand rsync -av --filter "- .DS_Store" --filter "- native_assets.yaml" "${native_assets_path}" "${xcode_frameworks_dir}"
194+
195+
# Iterate through all .frameworks in native assets directory.
196+
for native_asset in "${native_assets_path}"*.framework; do
197+
# Codesign the framework inside the app bundle.
198+
RunCommand codesign --force --verbose --sign "${EXPANDED_CODE_SIGN_IDENTITY}" -- "${xcode_frameworks_dir}/$(basename "$native_asset")"
199+
done
194200
fi
195201
}
196202

packages/flutter_tools/lib/src/isolated/native_assets/macos/native_assets.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,12 @@ Future<void> _copyNativeAssetsMacOS(
304304
));
305305
await setInstallNameDylib(dylibFile);
306306
await createInfoPlist(name, resourcesDir);
307-
await codesignDylib(codesignIdentity, buildMode, frameworkDir);
307+
// Do not code-sign the libraries here with identity. Code-signing
308+
// for bundled dylibs is done in `macos_assemble.sh embed` because the
309+
// "Flutter Assemble" target does not have access to the signing identity.
310+
if (codesignIdentity != null) {
311+
await codesignDylib(codesignIdentity, buildMode, frameworkDir);
312+
}
308313
}
309314
globals.logger.printTrace('Copying native assets done.');
310315
}

packages/flutter_tools/test/integration.shard/isolated/native_assets_test.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ void main() {
207207
switch (buildSubcommand) {
208208
case 'macos':
209209
expectDylibIsBundledMacOS(exampleDirectory, buildMode);
210+
expectDylibIsCodeSignedMacOS(exampleDirectory, buildMode);
210211
case 'ios':
211212
expectDylibIsBundledIos(exampleDirectory, buildMode);
212213
case 'linux':
@@ -290,6 +291,24 @@ void main() {
290291
}
291292
}
292293

294+
void expectDylibIsCodeSignedMacOS(Directory appDirectory, String buildMode) {
295+
final Directory appBundle = appDirectory.childDirectory('build/$hostOs/Build/Products/${buildMode.upperCaseFirst()}/$exampleAppName.app');
296+
final Directory frameworksFolder = appBundle.childDirectory('Contents/Frameworks');
297+
expect(frameworksFolder, exists);
298+
const String frameworkName = packageName;
299+
final Directory frameworkDir = frameworksFolder.childDirectory('$frameworkName.framework');
300+
final ProcessResult codesign =
301+
processManager.runSync(<String>['codesign', '-dv', frameworkDir.absolute.path]);
302+
expect(codesign.exitCode, 0);
303+
304+
// Expect adhoc signature, but not linker-signed (which would mean no code-signing happened after linking).
305+
final List<String> lines = codesign.stderr.toString().split('\n');
306+
final bool isLinkerSigned = lines.any((String line) => line.contains('linker-signed'));
307+
final bool isAdhoc = lines.any((String line) => line.contains('Signature=adhoc'));
308+
expect(isAdhoc, isTrue);
309+
expect(isLinkerSigned, isFalse);
310+
}
311+
293312
/// For `flutter build` we can't easily test whether running the app works.
294313
/// Check that we have the dylibs in the app.
295314
void expectDylibIsBundledMacOS(Directory appDirectory, String buildMode) {

0 commit comments

Comments
 (0)