Repository navigation
Self-Contained dotnet core on Ubuntu System.DllNotFoundException: Unable to load DLL 'git2-1196807' #1472
Description
SysInfo
.Net Core: 1.0.1
libgit2sharp.portable: 0.24.10
Ubuntu: 16.04
Summary
I'm attempting to create a self contained publish of a dotnet core console application that references this library for Ubuntu 16.04. Everything works fine if I create a portable app that relies on dotnet core being installed on the target machine. i.e.
dotnet restore
dotnet publish
dotnet app.dllworks.
Where I'm running into trouble is with creating a publish version that also ships the runtime.
This only seems to be happening on Ubuntu (and I'm assuming other *nix systems).
I am able to create a self-contained dotnet core app and run it on Mac.
I'm assuming it will also work on Windows because both of those operating systems automatically load libraries in the current directory.
I've tried adding both the application directory and the lib/linux/x86_64/ subdirectory to the LD_LIBRARY_PATH environment variable, similar to what was done here in the build script, but it had no effect.
I suspect it has something to do with the way the library is loaded and the code generation that specifies the path, but that's really just a wild guess on my part.
Use Case
I'm not a fan of making users jump through a ton of hoops to get an application up and running. It's much nicer to be able to unpack an archive and have it "just work". I also much prefer users only needing to type app instead of dotnet path/to/app.dll to run the application. Hence, the self-contained publish.
Steps to Reproduce
- Create a new project
dotnet new console
dotnet add package libgit2sharp.portable
dotnet restore
- Reference LibGit2Sharp and use it
using System;
using LibGit2Sharp;
namespace gitlib2_mvce
{
class Program
{
static void Main(string[] args)
{
var repo = new Repository();
Console.WriteLine("Hello World!");
}
}
}- Add runtime identifier for Ubuntu to *.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<RuntimeIdentifiers>
<RuntimeIdentifier>ubuntu.16.04-x64</RuntimeIdentifier>
</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="libgit2sharp.portable" Version="0.24.10" />
</ItemGroup>
</Project>- Restore and Publish
dotnet restore -r ubuntu.16.04-x64
dotnet publish -c release -r ubuntu.16.04-x64- Copy to target machine
- Run app
./app
Expected: "Hello World"
Actual:
Unhandled Exception: System.TypeInitializationException: The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'git2-1196807': The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
at LibGit2Sharp.Core.NativeMethods.git_libgit2_init()
at LibGit2Sharp.Core.NativeMethods.LibraryLifetimeObject..ctor()
at LibGit2Sharp.Core.NativeMethods..cctor()
--- End of inner exception stack trace ---
at LibGit2Sharp.Core.NativeMethods.git_repository_new(git_repository*& repo)
at LibGit2Sharp.Core.Proxy.git_repository_new()
at LibGit2Sharp.Repository..ctor(String path, RepositoryOptions options, RepositoryRequiredParameter requiredParameter)
at gitlib2_mvce.Program.Main(String[] args) in /Users/rubberduck/Documents/Source/gitlib2_mvce/Program.cs:line 11
Additional Info
This is the contents of the resulting publish package.
libgit2-1196807.so is located in the same directory as LibGit2Sharp.dll and the application (gitlib2_mvce) as well as in lib/linux/x86_64/.
Both are marked as executable.
`-- mvce
|-- LibGit2Sharp.dll
|-- LibGit2Sharp.dll.config
|-- Microsoft.CSharp.dll
|-- Microsoft.CodeAnalysis.CSharp.dll
|-- Microsoft.CodeAnalysis.VisualBasic.dll
|-- Microsoft.CodeAnalysis.dll
|-- Microsoft.VisualBasic.dll
|-- Microsoft.Win32.Primitives.dll
|-- Microsoft.Win32.Registry.dll
|-- SOS.NETCore.dll
|-- System.AppContext.dll
|-- System.Buffers.dll
|-- System.Collections.Concurrent.dll
|-- System.Collections.Immutable.dll
|-- System.Collections.dll
|-- System.ComponentModel.Annotations.dll
|-- System.ComponentModel.dll
|-- System.Console.dll
|-- System.Diagnostics.Debug.dll
|-- System.Diagnostics.DiagnosticSource.dll
|-- System.Diagnostics.FileVersionInfo.dll
|-- System.Diagnostics.Process.dll
|-- System.Diagnostics.StackTrace.dll
|-- System.Diagnostics.Tools.dll
|-- System.Diagnostics.Tracing.dll
|-- System.Dynamic.Runtime.dll
|-- System.Globalization.Calendars.dll
|-- System.Globalization.Extensions.dll
|-- System.Globalization.Native.so
|-- System.Globalization.dll
|-- System.IO.Compression.Native.so
|-- System.IO.Compression.ZipFile.dll
|-- System.IO.Compression.dll
|-- System.IO.FileSystem.Primitives.dll
|-- System.IO.FileSystem.Watcher.dll
|-- System.IO.FileSystem.dll
|-- System.IO.MemoryMappedFiles.dll
|-- System.IO.UnmanagedMemoryStream.dll
|-- System.IO.dll
|-- System.Linq.Expressions.dll
|-- System.Linq.Parallel.dll
|-- System.Linq.Queryable.dll
|-- System.Linq.dll
|-- System.Native.a
|-- System.Native.so
|-- System.Net.Http.Native.so
|-- System.Net.Http.dll
|-- System.Net.NameResolution.dll
|-- System.Net.Primitives.dll
|-- System.Net.Requests.dll
|-- System.Net.Security.Native.so
|-- System.Net.Security.dll
|-- System.Net.Sockets.dll
|-- System.Net.WebHeaderCollection.dll
|-- System.Numerics.Vectors.dll
|-- System.ObjectModel.dll
|-- System.Private.CoreLib.dll
|-- System.Private.CoreLib.ni.dll
|-- System.Private.Uri.dll
|-- System.Reflection.DispatchProxy.dll
|-- System.Reflection.Emit.ILGeneration.dll
|-- System.Reflection.Emit.Lightweight.dll
|-- System.Reflection.Emit.dll
|-- System.Reflection.Extensions.dll
|-- System.Reflection.Metadata.dll
|-- System.Reflection.Primitives.dll
|-- System.Reflection.TypeExtensions.dll
|-- System.Reflection.dll
|-- System.Resources.Reader.dll
|-- System.Resources.ResourceManager.dll
|-- System.Runtime.Extensions.dll
|-- System.Runtime.Handles.dll
|-- System.Runtime.InteropServices.RuntimeInformation.dll
|-- System.Runtime.InteropServices.dll
|-- System.Runtime.Loader.dll
|-- System.Runtime.Numerics.dll
|-- System.Runtime.dll
|-- System.Security.Claims.dll
|-- System.Security.Cryptography.Algorithms.dll
|-- System.Security.Cryptography.Cng.dll
|-- System.Security.Cryptography.Csp.dll
|-- System.Security.Cryptography.Encoding.dll
|-- System.Security.Cryptography.Native.OpenSsl.so
|-- System.Security.Cryptography.OpenSsl.dll
|-- System.Security.Cryptography.Primitives.dll
|-- System.Security.Cryptography.X509Certificates.dll
|-- System.Security.Principal.Windows.dll
|-- System.Security.Principal.dll
|-- System.Text.Encoding.CodePages.dll
|-- System.Text.Encoding.Extensions.dll
|-- System.Text.Encoding.dll
|-- System.Text.RegularExpressions.dll
|-- System.Threading.Overlapped.dll
|-- System.Threading.Tasks.Dataflow.dll
|-- System.Threading.Tasks.Extensions.dll
|-- System.Threading.Tasks.Parallel.dll
|-- System.Threading.Tasks.dll
|-- System.Threading.Thread.dll
|-- System.Threading.ThreadPool.dll
|-- System.Threading.Timer.dll
|-- System.Threading.dll
|-- System.Xml.ReaderWriter.dll
|-- System.Xml.XDocument.dll
|-- System.Xml.XPath.XDocument.dll
|-- System.Xml.XPath.dll
|-- System.Xml.XmlDocument.dll
|-- gitlib2_mvce
|-- gitlib2_mvce.deps.json
|-- gitlib2_mvce.dll
|-- gitlib2_mvce.pdb
|-- gitlib2_mvce.runtimeconfig.json
|-- lib
| |-- linux
| | `-- x86_64
| | `-- libgit2-1196807.so
| |-- osx
| | `-- libgit2-1196807.dylib
| `-- win32
| |-- x64
| | |-- git2-1196807.dll
| | `-- git2-1196807.pdb
| `-- x86
| |-- git2-1196807.dll
| `-- git2-1196807.pdb
|-- libclrjit.so
|-- libcoreclr.so
|-- libcoreclrtraceptprovider.so
|-- libdbgshim.so
|-- libgit2-1196807.so
|-- libhostfxr.so
|-- libhostpolicy.so
|-- libmscordaccore.so
|-- libmscordbi.so
|-- libsos.so
|-- libsosplugin.so
|-- libuv.so
|-- mscorlib.dll
|-- mscorlib.ni.dll
`-- sosdocsunix.txt
Workaround
Require *nix users to install dotnet core as a pre-requisite.
The nicety of not needing of being able to type app instead of dotnet app.dll can be achieved with a shell alias.
Activity
rubberduck203 commentedon Jul 16, 2017
I'm a blithering idiot.
I was testing inside of a docker container.
I had determined early that I was missing some dotnet dependencies, so I installed libicu and libunwind, but I had missed a host of other dependencies.
I found the full list of dotnet dependencies in the dotnet docker dependencies image.
Replace libicu52 with libicu55 for Ubuntu 16.04 and it's all gravy.
For completeness, and future reference, you need the following list of dependencies installed to create a self-contained dotnet core application.
Something in this list is needed to load the native libgit2 binaries, but not needed to run a self-contained dotnet core app that doesn't load native binaries.
bording commentedon Jul 16, 2017
@rubberduck203 Glad to see you figured it out! I was just testing it myself, and everything was working fine.
FYI, the LibGit2Sharp.Portable NuGet package is not actually a package that we've released. It was published by @AArnott from some of his early work to add a .NET Standard target to this library.
We've recently merged in changes to begin producing a version of LibGit2Sharp that will run on .NET Core, but we haven't released it yet. One of the changes we've made is that the
libfolder you're seeing copied in there will be gone because it's not needed for .NET Core at all.rubberduck203 commentedon Jul 16, 2017
That's very good to know. I hadn't realized that.
I'll keep my eyes out for an updated package.
I apologize for the noise.