[msbuild] Rework code signing. - #14387
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
dc7d4c4 to
8c377f3
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
So that it's available for code in Xamarin.MacDev.Tasks.Core.
I'm removing the old logic first, because the new logic is so different that a diff just complicates understanding what's happening (there's not much value in comparing textually what's changed when it's pretty much a complete rewrite).
The main theme here is that code signing will be done in the outermost executable project, not in any app extension projects or watch projects, nor during the RID-specific build of a .NET universal app. This makes codesigning easier to reason about and other affected logic (such as strip/dsymutil) easier to handle, in particular for .NET universal apps. Another benefit is that the differences between the iOS and macOS code bases have been eliminated. The first step is to collect all the information we need from the targets files. Every app bundle (be it app extension, watch app or main app) will add its own output app bundle (.app/.appex) to the _CodesignBundle item group. Then every app bundle will load this informarion from referenced app bundles, and finally store this information on disk (in the 'codesign-bundle.items' file). This means that in the end the main app bundle will have a list of all contained app bundles in the app (recursively), in the _CodesignBundle item group. Separately we keep a list of other items that need signing, in the _CodesignItems item group, and we do the same store/load logic for every contained/contained app bundle (in the 'codesign.items' file, so a the end the main app bundle will have a list of all the _CodesignItems for all contained app bundles (recursively). The previous steps occur in the _CollectCodesigningData and _StoreCodesigningData targets. The next step is to use the new ComputeCodesignItems task to compute everything we need to know for code signing. This task takes over the responsibility for listing all the *.dylib and *.metallib files, and the *.framework directories in the app bundles, that need signing (which was previously done in the targets file). This logic is significantly easier to write, debug and test in C# than MSBuild. In addition the ComputeCodesignItems also figures out a stamp file path we use to determine if something needs (re-)signing. Previously .framework directories did not have a stamp location, so they'd always end up resigned in a rebuild, while now we'll automatically skip signing *.framework directories unless something changed in them. I've also tried to comment everything thorougly, for the next poor soul having to deal with any bugs, as well has adding a comprehensive test for the new task. Behavioral differences: * We were always signing *.dylib files for macOS. We're now doing the same thing for all platforms. * We're now always signing *.framework directories for all platforms (like we do for *.dylib files), since frameworks are pretty much like dylibs anyways.
…properties. The CodesignEntitlements and CodesignResourceRules properties can be relative paths, and they might be coming from a referenced project. This means that if they're relative paths, we must resolve them to a full path using the project that defined them (which is specified using the 'SourceProjectPath' metadata).
…ditions as for other platforms. The CompileEntitlements task already handles each platform as it should. This way we have fewer differences in the code between platforms.
This way the property works when exposed to containing projects as well.
f8c39b6 to
71482a9
Compare
|
@rolfbjarne this looks good to me, but the only thing that worries me from Windows is copying empty files to the Mac. I was looking into the Codesign task and that one is not copying any files to the Mac. I think this is because at the point this is executed, all the needed files exist in the Mac and no extra files are needed (https://github.com/xamarin/xamarin-macios/blob/main/msbuild/Xamarin.MacDev.Tasks/Tasks/Codesign.cs#L20). |
❌ [CI Build] Tests failed on VSTS: simulator tests iOS ❌Tests failed on VSTS: simulator tests iOS. Test results2 tests failed, 144 tests passed.Failed tests
Pipeline on Agent XAMBOT-1109.Monterey' |
That's correct, everything needed for the Codesign task should already be on the mac. Are you saying that the new |
|
@rolfbjarne Yeah, so we make sure we don't copy any empty files from Windows. If you implement ITaskCallback I'd also return false for |
Correct, this new task is not creating or changing any files, it's just computing stuff. |
…n macOS and Windows. The ComputeCodesignItems does not touch any files, and all the input files should already exist on the mac, so there's no need to copy files back and forth.
I've changed the task to specifically say files shouldn't be copied back and forth between windows and mac (using ITaskCallback.ShouldCopyToBuildServer and ShouldCreateOutputFile). |
❌ [CI Build] Tests failed on VSTS: simulator tests iOS ❌Tests failed on VSTS: simulator tests iOS. Test results2 tests failed, 144 tests passed.Failed tests
Pipeline on Agent XAMBOT-1107.Monterey' |
|
Test failures are unrelated:
|
|
I got this error when I build my project today. |
|
@suihanhbr - Please file and issue with steps to reproduce/sample so we can look into this. A stack trace in a PR comment thread is insufficient for us to track down any potential bug. |
The main theme here is that code signing will be done in the outermost
executable project, not in any app extension projects or watch projects, nor
during the RID-specific build of a .NET universal app. This makes codesigning
easier to reason about and other affected logic (such as strip/dsymutil)
easier to handle, in particular for .NET universal apps. Another benefit is
that the differences between the iOS and macOS code bases have been
eliminated.
The first step is to collect all the information we need from the targets
files. Every app bundle (be it app extension, watch app or main app) will add
its own output app bundle (.app/.appex) to the _CodesignBundle item group.
Then every app bundle will load this informarion from referenced app bundles,
and finally store this information on disk (in the 'codesign-bundle.items'
file). This means that in the end the main app bundle will have a list of all
contained app bundles in the app (recursively), in the _CodesignBundle item
group.
Separately we keep a list of other items that need signing, in the
_CodesignItems item group, and we do the same store/load logic for every
contained/contained app bundle (in the 'codesign.items' file, so a the end the
main app bundle will have a list of all the _CodesignItems for all contained
app bundles (recursively).
The previous steps occur in the _CollectCodesigningData and
_StoreCodesigningData targets.
The next step is to use the new ComputeCodesignItems task to compute
everything we need to know for code signing. This task takes over the
responsibility for listing all the *.dylib and *.metallib files, and the
*.framework directories in the app bundles, that need signing (which was
previously done in the targets file). This logic is significantly easier to
write, debug and test in C# than MSBuild.
In addition the ComputeCodesignItems also figures out a stamp file path we use
to determine if something needs (re-)signing. Previously .framework
directories did not have a stamp location, so they'd always end up resigned in
a rebuild, while now we'll automatically skip signing *.framework directories
unless something changed in them.
I've also tried to comment everything thorougly, for the next poor soul having
to deal with any bugs.
Behavioral differences:
thing for all platforms.
do for *.dylib files), since frameworks are pretty much like dylibs anyways.
I've verified that this works both by running the submission tests and running
and launching a sample project on device from Windows.
This PR might be easier to review commit-by-commit, because the diff turns out weird otherwise.