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

kernel32 not found (on linux) #89

Closed
1 of 3 tasks
tzachshabtay opened this issue May 3, 2018 · 10 comments
Closed
1 of 3 tasks

kernel32 not found (on linux) #89

tzachshabtay opened this issue May 3, 2018 · 10 comments

Comments

@tzachshabtay
Copy link

  • **I'm submitting a ... **

    • bug report
    • feature request
    • support request or question => Please do not submit support request or questions here, see note at the top of this template.
  • What is the current behavior?

Running from linux with mono, but ffmpeg.autogen seems to think I'm running from Windows.

  • *If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem:

This is my sample code (but pretty sure it will happen no matter what ffmpeg function I'll try to invoke):


const int out_channels = 2, out_samples = 512, sample_rate = 44100;
ulong max_buffer_size = (ulong)ffmpeg.av_samples_get_buffer_size(null, out_channels, out_samples, AVSampleFormat.AV_SAMPLE_FMT_FLT, 1);

  • What is the expected behavior?

I'm expecting it to search for the linux library, not the Windows library.

  • What is the motivation / use case for changing the behavior?

I want to use ffmpeg autogen on linux.

  • Please tell us about your environment:
  • Ubuntu 16.04 LTS 64bit
  • Mono JIT compiler version 5.10.1.20 (tarball Thu Mar 29 10:44:58 UTC 2018)
  • package id="FFmpeg.AutoGen" version="4.0.0.1" targetFramework="net461"
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

Here's the stacktrace:


FFmpeg.AutoGen.Native.WindowsNativeMethods.LoadLibrary() in 
FFmpeg.AutoGen.Native.LibraryLoader.LoadNativeLibrary(string libraryName) in 
FFmpeg.AutoGen.Native.LibraryLoader.LoadNativeLibraryUsingPlatformNamingConvention( Parameters) in 
FFmpeg.AutoGen.ffmpeg.( Parameters) in 
FFmpeg.AutoGen.ffmpeg.<>c.<.cctor>b__4_681( Parameters) in 
FFmpeg.AutoGen.ffmpeg.av_samples_get_buffer_size( Parameters) in 

I looked at the code of LibraryLoader, and added this code to my test before calling ffmpeg:

#if NET45
            Debug.WriteLine("NET45 is on!!");
#endif
            Debug.WriteLine($"Is Windows = {RuntimeInformation.IsOSPlatform(OSPlatform.Windows)}");
            Debug.WriteLine($"Is Linux = {RuntimeInformation.IsOSPlatform(OSPlatform.Linux)}");
            Debug.WriteLine($"Is Mac = {RuntimeInformation.IsOSPlatform(OSPlatform.OSX)}");

The output:

Is Windows = False
Is Linux = True
Is Mac = False

So it seems to work fine in my code but somehow fails in your code.
My only guess is that maybe you somehow packaged with the wrong RuntimeInformation assembly? See this issue: https://github.com/dotnet/corefx/issues/3032

@Ruslan-B
Copy link
Owner

Ruslan-B commented May 4, 2018

@tzachshabtay thanks for detail explanation, however, it looks like your code is referring to the NET45 assembly, instead of .net Standard one. Which does not doing OS detection it assumes the OS is Windows. I would advice to fix the reference fist.

@tzachshabtay
Copy link
Author

@Ruslan-B how do I reference the .net standard assembly, then? I just added the package via nuget.

And also, why does your code assume net45 is windows?

Thanks for the response.

@Ruslan-B
Copy link
Owner

Ruslan-B commented May 4, 2018

Package contains two assembles one is net45 and the other one netstandard2.0. As your targetFramework is set "net461" nuget must-likely created the link to the net45 assembly. Could you please check this fist? And if so just adjust your csproj file to refer to netstandard2.0 instead.
And the reason why it assumes windows - because RuntimeInformation type is absent in net45.

@tzachshabtay
Copy link
Author

Ah, indeed the net45 assembly is copied instead of the netstandard one.
That said, I can't find any way to change that.

My scenario is that I have a dotnet stanard library referencing your library, and a mono/dotnet console app targetting dotnet 4.6.1 referencing my library (an executable cannot target netstandard- it's for libraries only).
In my library's csproj I just have <PackageReference Include="FFmpeg.AutoGen" Version="4.0.0.1" /> and I don't see any way to select a specific assembly.

In the executable I tried to change the target framework for the package to netstandard2, didn't work (still net45 assembly gets copied).
I then tried to migrate the csproj on the executable to the new csproj format (the library was already in the new csproj format), which means I no longer have a packages.config file (it's supposed to work automaically in the new format to my understanding) -> that didn't help either, same result.

I wanted to look in your nuspec to see how it's packaged (I don't if and how it uses reference groups: https://docs.microsoft.com/en-us/nuget/reference/nuspec#reference-groups), but it's not in the repo?

Interesting observation: looking at the build log, I saw that my library was using the net45 assembly. Then I added <AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects> to my library's csproj which seems to fix it for the library (it now uses the netstandard assembly), but when it goes to compile the executable it still uses the net45 assembly (and adding the same attribute to that project had no effect).
Should be noted that I don't want to use that attribute anyway as it's recommended to leave it enabled.

And the reason why it assumes windows - because RuntimeInformation type is absent in net45.

This could be hacked around: Environmet.OSVersion can tell you if it's Windows or not, and if it's not windows: /usr/lib/libc.dylib exists -> mac, otherwise linux.

@Ruslan-B
Copy link
Owner

Ruslan-B commented May 4, 2018

Hmm, so you can convert your application to .net core 2.0? Any way I guess it wouldn't be a problem to add another target net461 in to nuget package. I'll take a look. As for hacks you can redefine ffmpeg.GetOrLoadLibrary meanwhile.

@Ruslan-B
Copy link
Owner

Ruslan-B commented May 4, 2018

@tzachshabtay I wouldn't work:
RuntimeInformation was introduced in 4.7.1 and part of .Net Core/Standard:
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation?view=netframework-4.7.1
I guess test you mentioned is mono specific or you used higher version of the net framework.

@tzachshabtay
Copy link
Author

Did you see my link about the reference groups?
Can't you add in your nuspec something like:

<group targetFramework="net461">
        <reference file="lib/netstandard2.0/FFmpeg.AutoGen.dll" />
</group>

I'm not completely confident this would work, but it might...

Regardless, is there a reason not to implement the workaround I mentioned for net45?

I can't migrate to netcore (I have dependencies that don't support it), I might be able to upgrade to 4.7.1, but I don't want to lose potential target platforms if I can help it.

@Ruslan-B
Copy link
Owner

Ruslan-B commented May 4, 2018

I saw it but it wouldn't work in case you have 4.6.* framework or lower.
And the reason why to not to use /usr/lib/libc.dylib way - it is a trickery.
But I'll refactor a bit library loading to make it more open for extension or for hacks.

@tzachshabtay
Copy link
Author

Ok, that will work too, I guess.

@Ruslan-B
Copy link
Owner

Ruslan-B commented May 7, 2018

I've updated the package. Feel free to reopen if this issue will reoccur.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants