'.NET 6 console app using NuGet library written for .NET 5 runs fine under Windows but crashes on Mac M1 with System.BadImageFormatException
Under Windows I have used the SaxonCS library (available on NuGet https://www.nuget.org/packages/SaxonCS/ that is written against .NET 5 successfully in both .NET 5 and .NET 6 applications.
However, now trying some of my .NET code on a Mac M1 I find that using SaxonCS in a .NET 5 application works while an attempt in a .NET 6 application gives no build errors but on attempting to run it gives an error System.BadImageFormatException.
Details are:
dotnet NET6ConsoleApp1.dll
Unhandled exception. System.BadImageFormatException: Could not load file or assembly 'SaxonCS, Version=11.2.0.0, Culture=neutral, PublicKeyToken=null'. An attempt was made to load a program with an incorrect format.
File name: 'SaxonCS, Version=11.2.0.0, Culture=neutral, PublicKeyToken=null'
zsh: abort dotnet NET6ConsoleApp1.dll
Details of used .NET:
dotnet --info
.NET SDK (gemäß "global.json"):
Version: 6.0.200
Commit: 4c30de7899
Laufzeitumgebung:
OS Name: Mac OS X
OS Version: 11.6
OS Platform: Darwin
RID: osx.11.0-arm64
Base Path: /usr/local/share/dotnet/sdk/6.0.200/
Host (useful for support):
Version: 6.0.2
Commit: 839cdfb0ec
.NET SDKs installed:
6.0.200 [/usr/local/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.2 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.2 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
In terms of C# code the console app does nothing more than
using Saxon.Api;
Console.WriteLine("{0} {1} {2}", Environment.Version, Environment.OSVersion, Environment.ProcessPath);
Environment.SetEnvironmentVariable("SAXON_LICENSE_DIR", "/Users/username/Library/SaxonCS");
Processor processor = new Processor(true);
Console.WriteLine("{0} {1}", processor.ProductTitle, processor.ProductVersion);
I don't understand why the code runs under Windows with .NET 6 but fails under a Mac M1 ARM.
Does anyone have an explanation? How can I remedy that problem, without having to wait for or ask the library owner to release a .NET 6 version?
Solution 1:[1]
Saxonica has in the meantime released SaxonCS 11.3 which fixes the problem by ensuring the NuGet package contains a platform independent/MSIL library instead of an Amd64 targeted one. That way I can use and run the library on both AMD 64 machines as well as ARM 64 machines like an M1 mini.
The other confusing part of the story was that the .NET 5 runtime on ARM 64/ M1 machines does "consume" the Windows compiled AMD 64 library as .NET 5 on the M1 platform works only through a compatibility layer (Rosetta?).
Solution 2:[2]
It's important to understand the way .NET compiles assemblies for target architecture.
- If you use a x64 architecture it will compile for the x64 binary version of the OS where you are compiling.
- If you use Any CPU architecture your assmbly will be compiled in an intermediate binary code which will be compiled by the JIT (just in time compiler) for the hosting architecture when you run your application.
You have to use specific target architecture just in the case you are using some third party library which are architecture specific or you are using native library (like a C++ one).
In all the other cases you should use Any CPU and let the JIT to do the work for you. To prove this in your little test project just compile your .NET 5 library with Any CPU configuration and everything will be fixed.
It's clear that Saxonica didn't release an architecture indipendent version of the library. So you cannot solve the issue yourself.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Marco Beninca |
