-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Our .NET MAUI app launches and functions correctly locally (Debug & Release) and on both iOS and macOS.
After uploading via TestFlight, the MacCatalyst build crashes immediately at launch with a dyld error indicating a missing framework:
Termination Reason: Namespace DYLD, Code 1 Library missing
Library not loaded:@rpath/McuMgrBindingsiOS.framework/Versions/A/McuMgrBindingsiOS
Reason:(security policy does not allow @ path expansion)
This is how our .csproj looks like.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
...
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<!-- iOS codesigning -->
<CodesignKey Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'"></CodesignKey>
<CodesignProvision Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'"></CodesignProvision>
<!-- MacCatalyst codesigning -->
<CodesignKey Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">-</CodesignKey>
<CodesignProvision Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'"></CodesignProvision>
<UseHardenedRuntime Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">false</UseHardenedRuntime>
<CodesignEntitlements Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">Platforms/MacCatalyst/Entitlements.plist</CodesignEntitlements>
<RuntimeIdentifier Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">maccatalyst-arm64</RuntimeIdentifier>
<!-- MacCatalyst Linker Configuration - Prevent stripping McuMgr bindings in Release mode -->
<MtouchLink Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst' and '$(Configuration)' == 'Release'">SdkOnly</MtouchLink>
<!-- MacCatalyst Registrar Configuration - Keep dynamic registrar for McuMgr bindings -->
<MtouchExtraArgs Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst' and '$(Configuration)' == 'Release'">--optimize=-remove-dynamic-registrar</MtouchExtraArgs>
<!-- iOS Build Settings to force device builds -->
<RuntimeIdentifier Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and '$(Configuration)' == 'Debug'">ios-arm64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and '$(Configuration)' == 'Release'">ios-arm64</RuntimeIdentifier>
<!-- iOS Linker Configuration - Prevent stripping McuMgr bindings in Release mode -->
<MtouchLink Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and '$(Configuration)' == 'Release'">SdkOnly</MtouchLink>
<!-- iOS Registrar Configuration - Keep dynamic registrar for McuMgr bindings -->
<MtouchExtraArgs Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and '$(Configuration)' == 'Release'">--optimize=-remove-dynamic-registrar</MtouchExtraArgs>
</PropertyGroup>
...
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="11.0.0" />
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Plugin.BLE" Version="3.1.0" />
<PackageReference Include="Laerdal.McuMgr" Version="3.55.0" />
</ItemGroup>
<!-- iOS-specific package reference -->
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<PackageReference Include="Laerdal.McuMgr.Bindings.iOS" Version="3.55.0" />
</ItemGroup>
<!-- MacCatalyst-specific package reference -->
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">
<PackageReference Include="Laerdal.McuMgr.Bindings.MacCatalyst" Version="3.55.0" />
</ItemGroup>
<!-- Ensure the bundled McuMgr framework has the symlinks codesign expects on macOS -->
<Target Name="FixLaerdalFrameworkForMacCatalyst" Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'" AfterTargets="_CollectCodesigningData">
<Message Importance="Low" Text="FixLaerdalFramework: AppBundleDir=$(AppBundleDir)" />
<Exec Command="bash -lc "FRAMEPATH='$(AppBundleDir)/Contents/Frameworks/McuMgrBindingsiOS.framework'; if [ -d \"\$FRAMEPATH\" ]; then cd \"\$FRAMEPATH\"; ln -sfn A Versions/Current; ln -sfn Versions/Current/Resources Resources; ln -sfn Versions/Current/Headers Headers; ln -sfn Versions/Current/Modules Modules; if [ -f McuMgrBindingsiOS ]; then rm -f McuMgrBindingsiOS; fi; ln -sfn Versions/Current/McuMgrBindingsiOS McuMgrBindingsiOS; fi"" />
</Target>
<!-- https://github.com/xamarin/xamarin-macios/issues/19451#issuecomment-1811959873 -->
<PropertyGroup>
<_UseClassicLinker>false</_UseClassicLinker>
</PropertyGroup>
</Project>
With this TestFlight post-checks get successful. However after opening the app we get a crash report that says this.
Termination Reason: Namespace DYLD, Code 1 Library missing
Library not loaded: @rpath/McuMgrBindingsiOS.framework/Versions/A/McuMgrBindingsiOS
Referenced from: <A04581E4-FA11-3987-A16D-CCDC9A3BECD2> /Users/USER/*/sampleapp.app/Contents/MacOS/sampleapp
Reason: , (security policy does not allow @ path expansion)
(terminated at launch; ignore backtrace)
Environment
- macOS: 15.3.1 (24D70)
- Architecture: ARM64 (Apple Silicon). We intend to ship ARM-only as
Laerdal.McuMgrhas no explicit x64 support statement. - .NET target:
net9.0-maccatalyst - Registrar: dynamic registrar previously linked away (fixed for runtime, see below)
We also tried with this configuration. With this, App Store Connect post-processing reports framework bundle structure and code signing issues for McuMgrBindingsiOS.framework (see “App Store Connect Errors” below).
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
...
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
...
<!-- MacCatalyst Runtime - ARM64 only (framework only supports ARM64) -->
<RuntimeIdentifier Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">maccatalyst-arm64</RuntimeIdentifier>
<!-- MacCatalyst Linker Configuration - Prevent stripping McuMgr bindings in Release mode -->
<MtouchLink Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst' and '$(Configuration)' == 'Release'">SdkOnly</MtouchLink>
<!-- MacCatalyst Registrar Configuration - Keep dynamic registrar for McuMgr bindings -->
<MtouchExtraArgs Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst' and '$(Configuration)' == 'Release'">--optimize=-remove-dynamic-registrar</MtouchExtraArgs>
<!-- iOS Build Settings to force device builds -->
<RuntimeIdentifier Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and '$(Configuration)' == 'Debug'">ios-arm64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and '$(Configuration)' == 'Release'">ios-arm64</RuntimeIdentifier>
<!-- iOS Linker Configuration - Prevent stripping McuMgr bindings in Release mode -->
<MtouchLink Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and '$(Configuration)' == 'Release'">SdkOnly</MtouchLink>
<!-- iOS Registrar Configuration - Keep dynamic registrar for McuMgr bindings -->
<MtouchExtraArgs Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and '$(Configuration)' == 'Release'">--optimize=-remove-dynamic-registrar</MtouchExtraArgs>
</PropertyGroup>
...
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="11.0.0" />
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Plugin.BLE" Version="3.1.0" />
<PackageReference Include="Laerdal.McuMgr" Version="3.55.0" />
</ItemGroup>
<!-- iOS-specific package reference -->
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<PackageReference Include="Laerdal.McuMgr.Bindings.iOS" Version="3.55.0" />
</ItemGroup>
<!-- MacCatalyst-specific package reference -->
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">
<PackageReference Include="Laerdal.McuMgr.Bindings.MacCatalyst" Version="3.55.0" />
</ItemGroup>
<!-- MacCatalyst Static Linking - Required for TestFlight/App Store Distribution -->
<!-- https://github.com/xamarin/xamarin-macios/issues/14686 -->
<!-- TestFlight enforces stricter security policies that don't allow @rpath expansion for dylibs -->
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">
<!-- Force static linking instead of dynamic libraries to avoid "security policy does not allow @ path expansion" crash -->
<_LibMonoLinkMode>Static</_LibMonoLinkMode>
<_LibXamarinLinkMode>Static</_LibXamarinLinkMode>
</PropertyGroup>
<!-- https://github.com/xamarin/xamarin-macios/issues/19451#issuecomment-1811959873 -->
<PropertyGroup>
<_UseClassicLinker>false</_UseClassicLinker>
</PropertyGroup>
</Project>
App Store Connect post-processing reports
Malformed Framework. The framework bundle McuMgrBindingsiOS (sampleapp.app/Contents/Frameworks/McuMgrBindingsiOS.framework/Versions/A) must contain a symbolic link 'Resources' -> 'Versions/Current/Resources'. Refer to the <a href="http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html">Anatomy of Framework Bundles</a> for more information. (90291)
Invalid signature. The nested app bundle, McuMgrBindingsiOS at the “sampleapp.app/Contents/Frameworks/McuMgrBindingsiOS.framework/Versions/A” path, has the following signing error(s): [code has no resources but signature indicates they must be present]. For details about signing Mac code for distribution, visit: https://developer.apple.com/documentation/xcode/creating-distribution-signed-code-for-the-mac. (90238)
Invalid signature. The main app bundle, sampleapp at the “sampleapp.app” path, has the following signing error(s): [embedded framework contains modified or invalid version. In subcomponent: sampleapp.app/Contents/Frameworks/McuMgrBindingsiOS.framework]. For details about signing Mac code for distribution, visit: https://developer.apple.com/documentation/xcode/creating-distribution-signed-code-for-the-mac. (90238)
Invalid signature. The executable, at the “sampleapp.app/Contents/Frameworks/McuMgrBindingsiOS.framework/McuMgrBindingsiOS” path, has the following signing error(s): [invalid resource directory (directory or signature have been modified)]. For details about signing Mac code for distribution, visit: https://developer.apple.com/documentation/xcode/creating-distribution-signed-code-for-the-mac. (90238)
Malformed Framework. The framework bundle McuMgrBindingsiOS (sampleapp.app/Contents/Frameworks/McuMgrBindingsiOS.framework/Versions/A) contains 'Headers', which should be a symbolic link -> 'Versions/Current/Headers'. Refer to the <a href="http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html">Anatomy of Framework Bundles</a> for more information. (90291)
Invalid code signature. Signatures created with macOS version 10.8.5 or earlier [v1 signatures] are obsoleted and will no longer be recognized by Gatekeeper beginning with macOS version 10.9.5. To ensure your apps will run on updated versions of macOS they must be signed on macOS version 10.9 or later [v2 signatures]. Bundle with identifier 'Laerdal.McuMgrBindingsiOS' does not have v2 signature. For more information, see macOS Code Signing In Depth (90385)
Malformed Framework. The framework bundle McuMgrBindingsiOS (sampleapp.app/Contents/Frameworks/McuMgrBindingsiOS.framework/Versions/A) must contain a symbolic link 'McuMgrBindingsiOS' -> 'Versions/Current/McuMgrBindingsiOS'. Refer to the <a href="http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html">Anatomy of Framework Bundles</a> for more information. (90291)
Malformed Framework. The framework bundle McuMgrBindingsiOS (sampleapp.app/Contents/Frameworks/McuMgrBindingsiOS.framework/Versions/A) 'Versions' directory must contain a symbolic link 'Current' resolving to a specific version directory. Resolved link target: '${linkTarget}'. Refer to the <a href="http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html">Anatomy of Framework Bundles</a> for more information. (90292)