libgit2 / libgit2sharp.nativebinaries

MIT License
28 stars 62 forks source link

Should we include all binaries in the output? #9

Closed nulltoken closed 8 years ago

nulltoken commented 9 years ago

Related to this StackOverflow question.

Current LibGit2Sharp.NativeBinaries.props seems to copy the binaries matching the known infrastructure at build time.

How silly would it be to always include all the binaries? Wouldn't that make consumers' life easier when they're willing to create a single cross-platform package?

/cc @bording @copygirl @Therzok

bording commented 9 years ago

I was just thinking about this. It could simplify things a bit, but there are also a couple issues that it could introduce.

The first thing I'd want to double check is if mono still works correctly if it finds both a .so and a .dylib. I remember seeing mono looking for .so files when running on mac, so that could be a problem if it would find and try to use the .so file first.

The other thing is right now we only have a 64-bit linux so, because Travis is 64-bit. If we ever wanted to get a 32-bit one included, we'd run into the same naming conflict that we do with the Windows binaries.

nulltoken commented 9 years ago

The other thing is right now we only have a 64-bit linux so, because Travis is 64-bit. If we ever wanted to get a 32-bit one included, we'd run into the same naming conflict that we do with the Windows binaries.

Would there be a way, on Mono, to rely on the same PATH environement variable probing trick that's leveraged on Windows? Would that be the case, maybe should we shove everything under the NativeBinaries folder hierarchy.

Therzok commented 9 years ago

@bording We rely on dlopen for them, and I don't think Mac's dlopen matches .so files. The looking for .so on Mac is a heuristic actually, you fix that by adding a .dll.config file that is embedded in the assembly.

Given that we have to set (DY)LD_LIBRARY_PATH (although it can be avoided by setting relative rpath on mac and no rpath on linux for the nativel ibraries), it doesn't matter where the files are set.

bording commented 9 years ago

Given that we have to set (DY)LD_LIBRARY_PATH

I know this has come up before, but I'm still not seeing where this is actually required to get mono to load the libgit dylib file. When the native library is sitting in the same directory as the referencing managed assembly, mono finds it just fine. Based on the docs I've seen, I'm pretty sure mono has special loading code to do this before it falls back to the native library loaders.

In the main repo's build.sh script, it is still setting LD_LIBRARY_PATH, but the only reason I had to leave that in was because of the shadow copy assembly tests, and even then that was only for linux. Mac ran the shadow copy tests just fine without it.

copygirl commented 9 years ago

I don't know anything about this native business, but if there's anything I would be able to help with, let me know.

nulltoken commented 9 years ago

I don't know anything about this native business, but if there's anything I would be able to help with, let me know.

You've raised a very valid issue. Thanks a lot for this! I think that your request makes a lot of sense. Indeed, being able to create a xplat packaged application leveraging LibGit2Sharp should be an out-of-box feature.

Hopefully, a proposal to make that happen should come up shortly. We may then need some help from you testing it before we release an official prerelease package. Would you agree, that would be tremendously helpful.

Therzok commented 9 years ago

@bording It does use that on Linux. It's smart enough to be able to use the same-directory library on Mac, but if you end up having another library (say libssh2), you do need to modify the RPATH or at least set the library path.

sushihangover commented 9 years ago

@bording Mono does use the standard dylib on OS-X, just enable one of the DYLIB reporting env vars and you will so it spew to stderr as libGit2 is not found :-)

For backwards compatibility it still supports the glib and its original bugs. i.e. It did not know what a dylib was, so on OS-X it always loaded .so || .dll. Also .bundle is supported. It also supports the parsing of a libtool .la to get the location/filename to open (so it does not matter if it the package (.pc) is installed or not).

So dylib is tried first and on failure and without any DYLIB envs set, the current dir is picked up. Linux does not support that, thus you need to set 'LD_LIBRARY_PATH=.'. After that the Mono internal 'fallback's are tried, the current execution PWD of the EXE/DLL, not the mono bin location, is tried as a fully qualified path as the first dlopen. This is why things like LD_LIBRARY_PATH work on OS-X/Mono.

FYI: If you have custom DYLIB and DYLIB_FALLBACKS setup in a non-mono parent process and are launching mono as a sub-process, using LD_LIBRARY_PATH on OS-X is a 'nice' hack to avoid messing up the parent dylib paths and allowing a parallel mono framework to exist.

For the DLLImports that are in libGit2Sharp, that is about 100 different dlopen within mono tries before the System.TypeInitializationException is thrown due to System.DllNotFoundException. This really should be wrapped within libGit2Sharp, but since there is currently no verify environment method in the C# library, I exception wrap it in applications around opening a non-existant repo to determine if I should post a friendly message that their install is f'd before exiting ;-0

Example failure and its different tries, this dll import errors repeat about 100 times for libGit2Sharp:

Mono: DllImport attempting to load: 'git2-e0902fb'.
Mono: DllImport error loading library '/Users/administrator/Documents/Code/Xamarin/LibGit2-file-listing/LibGit2-file-listing/bin/Debug/libgit2-e0902fb': 'dlopen(/Users/administrator/Documents/Code/Xamarin/LibGit2-file-listing/LibGit2-file-listing/bin/Debug/libgit2-e0902fb, 9): image not found'.
Mono: DllImport error loading library '/Users/administrator/Documents/Code/Xamarin/LibGit2-file-listing/LibGit2-file-listing/bin/Debug/libgit2-e0902fb.dylib': 'dlopen(/Users/administrator/Documents/Code/Xamarin/LibGit2-file-listing/LibGit2-file-listing/bin/Debug/libgit2-e0902fb.dylib, 9): image not found'.
Mono: DllImport error loading library '/Users/administrator/Documents/Code/Xamarin/LibGit2-file-listing/LibGit2-file-listing/bin/Debug/libgit2-e0902fb.so': 'dlopen(/Users/administrator/Documents/Code/Xamarin/LibGit2-file-listing/LibGit2-file-listing/bin/Debug/libgit2-e0902fb.so, 9): image not found'.
Mono: DllImport error loading library '/Users/administrator/Documents/Code/Xamarin/LibGit2-file-listing/LibGit2-file-listing/bin/Debug/libgit2-e0902fb.bundle': 'dlopen(/Users/administrator/Documents/Code/Xamarin/LibGit2-file-listing/LibGit2-file-listing/bin/Debug/libgit2-e0902fb.bundle, 9): image not found'.
Mono: DllImport error loading library 'libgit2-e0902fb': 'dlopen(libgit2-e0902fb, 9): image not found'.
Mono: DllImport error loading library 'libgit2-e0902fb.dylib': 'dlopen(libgit2-e0902fb.dylib, 9): image not found'.
Mono: DllImport error loading library 'libgit2-e0902fb.so': 'dlopen(libgit2-e0902fb.so, 9): image not found'.
Mono: DllImport error loading library 'libgit2-e0902fb.bundle': 'dlopen(libgit2-e0902fb.bundle, 9): image not found'.
copygirl commented 9 years ago

Hope you don't mind a question regarding getting it to run on Linux. With 0.22.0-pre20150606092322 (since there doesn't seem to be a new pre-release for the main package), how would you go about it? I tried copying it to the same directory as the .exe, as well as into NativeBinaries/amd64/. Or, since I built it on Windows, is the library name baked in or something?

edit: My testing seems to confirm this, the one built on Linux (with the library manually moved to NativeBinaries/amd64/) seems to run fine. Now to test that on the actual server... - edit2: Nope. Maybe it has something to do with the version of Mono that's on the server. edit3: I did have Mono 3.something on there, but even after an update: Still nothing.

nulltoken commented 9 years ago

since there doesn't seem to be a new pre-release for the main package

@copygirl I'm going to release a new pre-release package by June, 30th.

bording commented 9 years ago

@copygirl libgit2-ff8d635.so should be in the same directory as the LibGit2Sharp.dll and your .exe file. When I did that on my copy of your repo, I was able to run to your your program on my unbuntu 14.04 VM.

The bug I fixed with #11 was causing the .so file to be incorrectly nested down in a packages folder because of your solution directory structure.

copygirl commented 9 years ago

@bording Strangely, no matter what I try, I can't get it to work on the CentOS server. Tried putting the .so in a number of different places. Still the same exception.

sushihangover commented 9 years ago

@copygirl You can see where mono is searching and failing to find the .so by using the following:

MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll mono yourprogram.exe

The output will show you if is it finding, where it is not finding it and/or if the .so is the wrong arch.

copygirl commented 9 years ago

Ah, I see. Now this is a little bit more helpful. If only the exception would mention this

Mono: DllImport error loading library '[...]/libgit2-ff8d635.so': 'libssl.so.1.0.0: cannot open shared object file: No such file or directory'.

Found this, though everything seems to be fine, unless it's asking for the "1.0.0" part specifically:

$ ldconfig -p | grep ssl
        libssl3.so (libc6,x86-64) => /usr/lib64/libssl3.so
        libssl.so.10 (libc6,x86-64) => /usr/lib64/libssl.so.10
        libssl.so (libc6,x86-64) => /usr/lib64/libssl.so
bording commented 9 years ago

@copygirl I've set up a CentOS VM and I'm seeing the same thing. Libgit2 uses OpenSSL on linux, and we build the .so file on Travis CI, which is running Ubuntu.

So, at the moment, the included linux binary is only supported with Ubuntu. :frowning:

bording commented 9 years ago

@nulltoken I've got some ideas on how to handle both the original topic of this issue and the OpenSSL issue above that @copygirl has discovered.

I still need to test a few things out, but I hope to have something this weekend to show off and discuss further!

nulltoken commented 9 years ago

@bording :cool: