hey-red / Mime

.NET wrapper for libmagic
MIT License
84 stars 22 forks source link

native lib for M1 Mac os #46

Open bdurrani opened 1 year ago

bdurrani commented 1 year ago

Hi there

Would you be able to add support for m1 mac os? Seems like you would need an arm64 native lib.

I can help out if needed, but I would need some guidance on how to manage the default platform. As the default platform for mac os will no longer be x64.

I was able to get all the tests passing with a local build of libmagic v5.41, so it looks like no other code changes are required. Just needs another platform added.

I couldn't figure out how to get the dylib from the older version of brew (the newer one is too new), so I built it from source from here https://astron.com/pub/file/

Thanks for your project.

hey-red commented 1 year ago

@bdurrani

Would you be able to add support for m1 mac os? Seems like you would need an arm64 native lib.

Yes. You can create PR with our own build. I think u have latest macos(macOS 13 Ventura ?), so what all you need is just place library inside runtimes/osx.13-arm64/native directory.

All available RIDS: https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#macos-rids

See runtimes directory https://github.com/hey-red/Mime/tree/master/src/Mime/runtimes

bdurrani commented 1 year ago

Here you go #47

If there is something else you want me to test out, let me know.

hey-red commented 1 year ago

@bdurrani Nuget package has been updated(version 3.5.0). Try it with some test app, to make sure the library is correctly selected according current runtime.

bdurrani commented 1 year ago

I tried the following code snippet

var result = MimeGuesser.GuessExtension("diamond.png");
Console.WriteLine(result);

Things continue to work on a mac x64 os.

On an M1, I get the following runtime error

Unhandled exception. HeyRed.Mime.MagicException: Could not find any valid magic files!
   at HeyRed.Mime.Magic..ctor(MagicOpenFlags flags, String dbPath)
   at HeyRed.Mime.MimeGuesser.GuessMimeType(String filePath)
   at HeyRed.Mime.MimeGuesser.GuessExtension(String filePath)
   at Program.<Main>$(String[] args) in /Users/bilal.durrani/deletethis/ConsoleApp30/ConsoleApp30/Program.cs:line 7

Not sure what's I missed here.

However, if I run this via the dotnet command line tool, it seems to work

at 22:07:11 ❯ dotnet run -r osx.13-arm64

/usr/local/share/dotnet/sdk/7.0.200/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(1142,5): warning NETSDK1179: One of '--self-contained' or '--no-self-contained' options are required when '--runtime' is used. [/Users/bilal.durrani/deletethis/ConsoleApp30/ConsoleApp30/ConsoleApp30.csproj]
png

I guess I need to figure out how to set this runtime option when running it via Rider/Visual Studio

bdurrani commented 1 year ago

Look like I needed to add the RID to the csproj

 <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net7.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <RuntimeIdentifier>osx.13-arm64</RuntimeIdentifier>
    </PropertyGroup>
hey-red commented 1 year ago

@bdurrani Oh, wait. Seems like library is correctly loaded, but libmagic database(magic.mgc) not found. The problem is that current RID for OSX hardcoded as "osx" here

As temporary solution you can set database path: MimeGuesser.MagicFilePath = "/path/to/magic.mgc"; or copy magic.mgc to bin directory. But anyway I must find better way to do this..

bdurrani commented 1 year ago

Thanks for digging into this. I will check it out.
Let me know if you need me to test anything out

hey-red commented 1 year ago

Well. That's quick and dirty solution but it should work. Update package to latest version.

bdurrani commented 1 year ago

That seems to work. On an M1, using a console app with no configuration changes, I was able to use v3.5.1 just by adding the nuget package and hitting run, with the same code snippet as above.

I realized I forgot to update the readme to mention support for Ventura arm64.

bdurrani commented 1 year ago

Sigh, I also just realized. I was testing this using .NET 7. Apprently that RID was added only for .NET 7 That RID won't work for .NET 6 applications

for .NET 6, the osx RID stops at 12. it seems /usr/local/share/dotnet/sdk/6.0.406/RuntimeIdentifierGraph.json

I wonder if you used a lower RID, whether it will also work for .NET 6 applications RuntimeIdentifierGraph.json.txt

The following is the file i found for .NET 7 RuntimeIdentifierGraph7.json.txt

Based on this, it looks like if you specify a lower RID, things should work? https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#rid-graph

hey-red commented 1 year ago

@bdurrani Good point. osx-arm64 RID should works for all top level RIDS. The main problem is that libmagic itself can contains dependencies to another libs within your system. You can check it with command line utils like otool -L libmagic-1.dylib Without someone that has macOS 11/12 we won't able to verify that, but I think this will work.

bdurrani commented 1 year ago

Yeah, i figured the lib was tied to the os.

UnfortunatelyI dont have access to mac os 11/12 so I can't build the libs for the other versions of mac os. Unless there is a way to pull it from homebrew. Or use the free tier of github actions.

This is the output from my current system.

at 20:06:08 ➜ otool -L libmagic-1.dylib
libmagic-1.dylib:
        /usr/local/lib/libmagic.1.dylib (compatibility version 2.0.0, current version 2.0.0)
        /usr/lib/liblzma.5.dylib (compatibility version 6.0.0, current version 6.3.0)
        /usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.8)
        /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0)

Probably best to leave things as is. I appreciate your patience with all this. I didn't realize what a PITA this would be to get working for a M1 Mac.

hey-red commented 1 year ago

Well. I changed osx arm64 RID to more generic. If someone wants to use it on older version then we will know.

This is the output from my current system.

Maybe I'm missing something but why dylib from nuget has link to local libmagic?

I didn't realize what a PITA this would be to get working for a M1 Mac.

This happens only for libraries with native dependencies. Other things should works as expected.

Also, I planned to update libmagic to latest version(may be on next week) and for more consistency, configuration for native libs shoulds disable all compressing libs. For example https://github.com/hey-red/Libmagic-Build/blob/master/unix/libmagic_unix.sh#L40

bdurrani commented 1 year ago

Maybe I'm missing something but why dylib from nuget has link to local libmagic?

Weird... I don't even have that file in my /usr/local/lib folder

at 15:22:13 ➜ otool -L ./libmagic-1.dylib
./libmagic-1.dylib:
        /usr/local/lib/libmagic.1.dylib (compatibility version 2.0.0, current version 2.0.0)
        /usr/lib/liblzma.5.dylib (compatibility version 6.0.0, current version 6.3.0)
        /usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.8)
        /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0)
runtimes/osx-arm64/native 
at 15:22:14 ➜ ls /usr/local/lib/libmagic.1.dylib 
lsd: /usr/local/lib/libmagic.1.dylib: No such file or directory (os error 2).
hey-red commented 1 year ago

Ok. Maybe it's normal for Mac. I'm leaving this issue open, maybe someone other with mac can confirm that.

On linux build I get this

 -> ldd libmagic-1.so
        linux-vdso.so.1 (0x00007ffc7bc7d000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f96524e3000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f9652907000)