[FIXED] "Not a valid framework" (MM0140) error when trying to build Xamarin native bindings library for framework targeting net6-macos

Issue

I have working native bindings library targeting old xamarin.mac (xamarin.full net framework 4.8) built with mono.
It is binding ScritptingBridge.framework, not a static library. It is builds and works as expected.

Note: full project for experiments may be found here: https://github.com/snechaev/net6nativeBindingsError

Now I’m trying to migrate to newest net6-macos. To do so I do the following

  • converted main app project to the sdk style and target net6-macos. If I will temporary remove native bindings dependencies, this will build fine.

  • converted native bindings project to the sdk style and perform the following fixes suggested by the comiler errors

    • changed version to avoid wildcards
    • replaced [assembly: LinkerSafe] with AssemblyMetadata("IsTrimmable", "True")]
    • added explicit NativeReferecnce to the framework I’m trying to bind.

Final csproj content for native bindings project:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net6-macos</TargetFramework>
        <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
        <RootNamespace>NativeBindingsLib</RootNamespace>
        <AssemblyName>NativeBindingsLib</AssemblyName>
        <IsPackable>false</IsPackable>
        <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
        <IsBindingProject>true</IsBindingProject>
        <NoBindingEmbedding>true</NoBindingEmbedding>
      </PropertyGroup>
      <ItemGroup>
        <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
        <ObjcBindingCoreSource Include="StructsAndEnums.cs" />
        <NativeReference Include="/System/Library/Frameworks/ScriptingBridge.framework" Kind="Framework" />
      </ItemGroup>
    </Project>

When I trying to build the only bindings library with dotnet build it builds without errors.

But when I try to build the application project (app.csproj in the sample repository), which is referencing (via the the ProjectReference) the binding library, I got the following errors:

ILLINK: Error MM0140: File '/Users/user/work/MonoBindingTest/net6/app/obj/Debug/net6.0-macos/osx-x64/linker-cache/NativeBindingsLib.resources/ScriptingBridge.framework/ScriptingBridge' is not a valid framework. (MM0140) (app)
       
ILLINK: Error MM2342: The linker step 'Extract Binding Libraries' failed during processing: File '/Users/user/work/MonoBindingTest/net6/app/obj/Debug/net6.0-macos/osx-x64/linker-cache/NativeBindingsLib.resources/ScriptingBridge.framework/ScriptingBridge' is not a valid framework. (MM2342) (app)

I double checked the framework path and it is ok. I also tried to add ScriptingBridge.framework into the XCode project and verified that the path is the same.

I also will be happy to get any samples of working net6-macos targeted native bindings projects for frameworks (not a static libraries) for further experiments on my own.

Full project mey be found here (both mono-targeted and net6-targeted): https://github.com/snechaev/net6nativeBindingsError

Solution

Finally, I posted the issue in the xamarin repo on github https://github.com/xamarin/xamarin-macios/issues/15485.

And ducting the discussion and experiments we concluded the following:

  • MM0140 is because the ScriptingBridge is the system framework and this is the special case.

  • you should not use NativeReference for the system frameworks as it will try to copy the framework into your bundle and this is not what you want for the system framework

  • initially I was missleaded by the following error

    MSBuild : error MM7068: Can't create a binding resource package unless there are native references in the binding project.
    

    so I decided to add NativeReference pointing ScriptingBridge.

So, the final solution is that the "at least one NativeReference" compiler check is excessive and it will be removed it net7 (https://github.com/xamarin/xamarin-macios/issues/15489).

The temporary workaround for net6 is to add the fake NativeReference to the empty static library to make compiler happy.

<NativeReference Include="/Users/sergey/work/MonoBindingTest/net6/test.dylib" Kind="Static"/>

I believe that it is possible to specify NativeReference to point to the source code (C++) instead of binary file and provide an additional command to build such a C++ code into the binary during the build process of native bindings library.

Additional note: the MM0140 error was called MT0140 in the previous versions of xamarin. So, this note may help other to find this post.

Answered By – Serg

Answer Checked By – Robin (Easybugfix Admin)

Leave a Reply

(*) Required, Your email will not be published