Skip to content
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

[maccatalyst] NativeReference results in "bundle format is ambiguous (could be app or framework)" #12369

Closed
mattleibow opened this issue Aug 6, 2021 · 1 comment · Fixed by #12656
Assignees
Labels
bug If an issue is a bug or a pull request a bug fix dotnet An issue or pull request related to .NET (6) dotnet-pri0 .NET 6: required for stable release
Milestone

Comments

@mattleibow
Copy link
Contributor

mattleibow commented Aug 6, 2021

Steps to Reproduce

  1. Create a new net6.0-maccatalyst app
  2. Add a <NativeReference> to a Mac Catalyst dynamic .framework
  3. Observe a compiler error: bundle format is ambiguous (could be app or framework)

I did notice that my framework has symlinks, but once it reaches the .app it has lost the symlinks and has duplicate files.

Expected Behavior

App builds and links.

Actual Behavior

/usr/local/share/dotnet/packs/Microsoft.MacCatalyst.Sdk/15.0.100-preview.7227/tools/msbuild/iOS/Xamarin.Shared.targets(1140,3): 
error : bin/Debug/net6.0-maccatalyst/maccatalyst-x64/SkiaSharpTestAppMacCat.app/Contents/Frameworks/libSkiaSharp.framework: bundle format is ambiguous (could be app or framework)

Environment

dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.100-preview.7.21379.14
 Commit:    22d70b47bc

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  11.5
 OS Platform: Darwin
 RID:         osx.11.0-x64
 Base Path:   /usr/local/share/dotnet/sdk/6.0.100-preview.7.21379.14/

Host (useful for support):
  Version: 6.0.0-preview.7.21377.19
  Commit:  91ba01788d

.NET SDKs installed:
  3.1.411 [/usr/local/share/dotnet/sdk]
  5.0.302 [/usr/local/share/dotnet/sdk]
  6.0.100-preview.7.21377.3 [/usr/local/share/dotnet/sdk]
  6.0.100-preview.7.21377.35 [/usr/local/share/dotnet/sdk]
  6.0.100-preview.7.21379.14 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.17 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.8 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-preview.7.21376.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-preview.7.21377.13 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-preview.7.21378.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-rc.1.21365.18 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.17 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.8 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0-preview.7.21377.12 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0-preview.7.21377.19 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download

Build Logs

msbuild.binlog.zip

Example Project (If Possible)

SkiaSharpTestAppMacCat.zip

Extract the project and then unzip libSkiaSharp.framework.zip making sure to preserve symlinks.

@rolfbjarne rolfbjarne added bug If an issue is a bug or a pull request a bug fix dotnet An issue or pull request related to .NET (6) dotnet-pri0 .NET 6: required for stable release labels Aug 6, 2021
@rolfbjarne rolfbjarne added this to the .NET 6 milestone Aug 6, 2021
@mattleibow
Copy link
Contributor Author

I have a fairly suspect workaround:

I basically avoid the issue of storing Mac Catalyst frameworks in .nupkg files by zipping it up as a native runtime asset: runtimes/maccatalyst/native/libSkiaSharp.framework.zip.

In most TFMs (Android and Windows), this would auto reference and make sure it is compiled in. Due to a bug (#11667) this is not referenced, and in the case of maccatalyst and my .zip, this still would not work. However, if it is in this folder, I can still reference it in MSBuild without having to write logic in may targets files to include it from the package.

Then I use this .targets file to extract and reference. But, since this bug exists, I also watch for the collection of these framework and then overwrite the copy that MSBuild made using Unix cp: https://github.com/mono/SkiaSharp/blob/3bf130d70ea75e7bbe7ef9fe3f1762728c51a0cd/binding/SkiaSharp/nuget/build/maccatalyst/SkiaSharp.targets

rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this issue Sep 8, 2021
…eworks to the app bundle. Fixes xamarin#12369.

.NET/MSBuild don't handle symlinks properly [1], which means that we can't ask .NET
to copy frameworks to the app bundle, since frameworks may contain symlinks.

In our case, the symptom was that instead of copying symlinks, the file the symlink
pointed to was copied instead, and then codesign complained about invalid bundle
format when we tried to sign the framework.

We fix this by having our own target (_CopyFrameworksToBundle) to copy frameworks
to the app bundle (instead of adding all the files in the frameworks to the ResolvedFileToPublish
item group), and then using 'ditto' to copy the frameworks.

[1]: dotnet/msbuild#6821

Fixes xamarin#12369.
@rolfbjarne rolfbjarne self-assigned this Sep 8, 2021
rolfbjarne added a commit that referenced this issue Sep 9, 2021
…opy frameworks to the app bundle. Fixes #12369. (#12656)

.NET/MSBuild don't handle symlinks properly [1], which means that we can't ask
.NET to copy frameworks to the app bundle, since frameworks may contain
symlinks.

In our case, the symptom was that instead of copying symlinks, the file the
symlink pointed to was copied instead, and then codesign complained about
invalid bundle format when we tried to sign the framework.

We fix this by having our own target (_CopyFrameworksToBundle) to copy
frameworks to the app bundle (instead of adding all the files in the
frameworks to the ResolvedFileToPublish item group), and then using 'ditto' to
copy the frameworks.

In order to create a test case for this, I also made the macOS and Mac
Catalyst versions of the XTest framework use symlinks:

* Create a proper XTest framework bundle hierarchy for macOS and Mac Catalyst
  by using the typical symlink structure (actual files in the Versions/A
  subdirectory, and then symlinks pointing into that directory).
* Create a separate Info.plist for each platform for XTest.framework, since
  using an otherwise correct framework makes tooling (such as codesign)
  complain if the Info.plist isn't correct too.

This made our existing tests show the bug.

Finally I had to fix signing frameworks where the executable is a symlink.

We were first resolving symlinks for the input - say we had an
Example.framework/Example symlink to Example.framework/Versions/A/Example -
and then checking the parent directory if it's a framework. The parent
directory of 'Example.framework/Versions/A/Example' is 'A', which did not meet
our framewrok condition (if it ends with '.framework').

The fix is to adjust the logic to resolve symlinks after checking if the input
is a framework or not.

[1]: dotnet/msbuild#6821

Fixes #12369.
@ghost ghost locked as resolved and limited conversation to collaborators Apr 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug If an issue is a bug or a pull request a bug fix dotnet An issue or pull request related to .NET (6) dotnet-pri0 .NET 6: required for stable release
Projects
None yet
2 participants