dotnet / Nerdbank.GitVersioning

Stamp your assemblies, packages and more with a unique version generated from a single, simple version.json file and include git commit IDs for non-official builds.
https://www.nuget.org/packages/Nerdbank.GitVersioning
MIT License
1.32k stars 165 forks source link

libgit2 not found error for MSBuild Core (Windows) #620

Open WildCard65 opened 3 years ago

WildCard65 commented 3 years ago

When executing "dotnet build" with Nerdbank.GitVersioning as a dependency (using LibGit2), the build fails with a DLLNotFoundException for the DLLImportAttribute

C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: The "Nerdbank.GitVersioning.Tasks.GetBuildVersion" task failed unexpectedly. C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: System.TypeInitializationException: The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception. C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: ---> System.DllNotFoundException: Unable to load DLL 'git2-6777db8' or one of its dependencies: The specified module could not be found. (0x8007007E) C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at LibGit2Sharp.Core.NativeMethods.git_libgit2_init() C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at LibGit2Sharp.Core.NativeMethods.InitializeNativeLibrary() in LibGit2Sharp.dll:token 0x6000918+0x2 C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at LibGit2Sharp.Core.NativeMethods..cctor() in LibGit2Sharp.dll:token 0x6000910+0x3b C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: --- End of inner exception stack trace --- C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at LibGit2Sharp.Core.NativeMethods.git_libgit2_opts(Int32 option, UInt32 level, String path) C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at LibGit2Sharp.Core.Proxy.git_libgit2_opts_set_search_path(ConfigurationLevel level, String path) in LibGit2Sharp.dll:token 0x6000bc7+0x0 C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at LibGit2Sharp.GlobalSettings.SetConfigSearchPaths(ConfigurationLevel level, String[] paths) in LibGit2Sharp.dll:token 0x600025e+0x1a C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at Nerdbank.GitVersioning.LibGit2.LibGit2Context.OpenGitRepo(String path, Boolean useDefaultConfigSearchPaths) in NerdBank.GitVersioning.dll:token 0x6000251+0x3 C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at Nerdbank.GitVersioning.LibGit2.LibGit2Context..ctor(String workingTreeDirectory, String dotGitPath, String committish) in NerdBank.GitVersioning.dll:token 0x600023f+0x8 C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at Nerdbank.GitVersioning.GitContext.Create(String path, String committish, Boolean writable) in NerdBank.GitVersioning.dll:token 0x6000048+0x1b C:\Users\lollo\.nuget\packages\nerdbank.gitversioning\3.4.216\build\Nerdbank.GitVersioning.Inner.targets(17,5): error MSB4018: at Nerdbank.GitVersioning.Tasks.GetBuildVersion.ExecuteInner() in Nerdbank.GitVersioning.Tasks.dll:token 0x600009e+0x10d

This is stemming from 3 problems:

  1. MSBuildCore is missing the native libraries git2-6777db8
  2. The dll map XML file is ignored in dotnet CLI (due to it running .NET Core and/or missing System.Runtime.InteropServices.NativeLibrary type
  3. PInvoke is trying to find the DLL in the same directory as LibGit2Sharp.dll
AArnott commented 3 years ago

I can confirm the repro. v3.3.37 does not repro this, so this is a recent regression.

AArnott commented 3 years ago

I believe #539 regressed this. Maybe I got too excited about removing the C# code that helps the CLR to load the right native binary. I don't want to revert that PR, or bring back the old RuntimeIdMap because it discriminated between linux distros in a way that is no longer necessary. But I'm not sure what the recommended path is going forward. @bording or @ethomson do you have any suggestions?

bording commented 3 years ago

What are the repro steps for this? I quickly tried to create a console app to test it, and it seems to be working fine.

WildCard65 commented 3 years ago

You have to use both LibGit2 and a .NET Core version of MSBuild (dotnet build)

AArnott commented 3 years ago

@bording Repro are (in powershell syntax):

dotnet new classlib -o bug620
cd bug620
git init
dotnet add package Nerdbank.GitVersioning
$env:NBGV_GitEngine='LibGit2'
dotnet build
bording commented 3 years ago

@AArnott Thanks for the repro steps. Is that NBGV_GitEngine value documented anywhere? Also, it seems like something that should be settable via a property in the project file, but when I tried that it didn't work.

Now that I can see the failure, I spent a little bit of time doing some research. I knew some new logic had been added to MSBuild for these sort of scenarios, but per https://github.com/dotnet/msbuild/issues/5037 and https://github.com/dotnet/msbuild/issues/1887, it doesn't look like the last required step has been done yet.

With the AssemblyDependencyResolver in place, you could ship a deps.json file in the MSBuildCore folder and move the runtimes folder in there, and it would all just work automatically.

Without that in place yet, you're still going to need some manual loading code in an AssemblyLoadContext to get the right native library.

WildCard65 commented 3 years ago

I can't remember where I found the variable in the first place, but it was while I was trying to find a solution to #619

AArnott commented 3 years ago

The env var is only documented in our release notes. It's not prominent because it's a workaround we left in place while we grew confidence in the new managed git implementation that we added as the new default in v3.4.

I'll get to work on an ALC native binary resolver then. If I understand correctly, it should be much simpler than the old RuntimeIdMap that we had before. Thanks, @bording.

WildCard65 commented 3 years ago

@AArnott Ah I remember how I found the variable, I found it in the source code as I was searching for what determined a repository to be "writable" (As named for GitContext.Create) and found it's value comes from the existence of that variable.