mendix / LibSvnSharp

C# wrapper around Subversion based on SharpSvn
Apache License 2.0
25 stars 6 forks source link

LibSvnSharp.Native.dll not found #3

Open frklan opened 4 years ago

frklan commented 4 years ago

Hi

This looks like an awesome project!

I've been trying to use the library in a small console application that only prints the svn version like so:

namespace ConsoleClient
{
  class Program {
    static void Main(string[] args) {
      Console.WriteLine("Using LibSvnSharp");
      Console.WriteLine(SvnClient.Version.ToString());
      Console.WriteLine("done!");
    }
  }
}

However I get the following error when trying to run it

Using LibSvnSharp

Unhandled Exception: System.EntryPointNotFoundException: Unable to find an entry point named 'svn_client_version' in DLL 'LibSvnSharp.Native.dll'.
   at LibSvnSharp.Interop.Svn.svn_client.__Internal.svn_client_version()
   at LibSvnSharp.Interop.Svn.svn_client.svn_client_version() in C:\source\svn\LibSvnSharp\LibSvnSharp\src\NativeBindingsGenerator\bin\Debug\Generated Files\SvnUnmanagedApi.cs:line 5424
   at LibSvnSharp.SvnClient.get_Version() in C:\source\svn\LibSvnSharp\LibSvnSharp\src\LibSvnSharp\SvnClient.cs:line 39
   at ConsoleClient.Program.Main(String[] args) in C:\source\svn\LibSvnSharp\LibSvnSharp\src\ConsoleClient\Program.cs:line 14

To reproduce, do like so 1) download, build and install the apr, apr-iconv and the apl-expat components from the apache web site and libexpat from github. 2) update the paths in NativeBindingsGenerator/appconfig.cs to point to the correct locations 3) run NativeBindingsGenerator.exe 4) build LibSvnSharp 5) build the ConsoleClient.exe test

I got no error running NativeBindingsGenerator and it created the following files

AprUnmanagedApi.cs
AprUnmanagedApi.dll
AprUnmanagedApi.pdb
AprUnmanagedApi.xml
LibSvnSharp.Interop.Apr-symbols.cpp
LibSvnSharp.Interop.Svn-symbols.cpp
Std.cs
Std.dll
Std.pdb
Std.xml
SvnUnmanagedApi.cs
SvnUnmanagedApi.dll
SvnUnmanagedApi.pdb
SvnUnmanagedApi.xml

As we can see; LibSvnSharp.Native.dll is missing!

I would appreciate if you have minute to guide me how to getting this to work.

ghost commented 4 years ago

Hi @frklan,

Thanks for your interest in the project! 😄

LibSvnSharp is a managed wrapper around the native Subversion library. It's written in C# entirely and uses P/Invoke to call into the native library. Thus it needs the native Subversion library built and placed next to the LibSvnSharp.dll in your app's folder.

You will need to follow the README of Subversion (https://subversion.apache.org) to build it manually. LibSvnSharp then expects all the parts of the native Subversion library to be linked into one dynamic library, LibSvnSharp.Native.dll. You can either do this after building the Subversion library, or change the code in LibSvnSharp to point to separate DLLs built by the normal Subversion build process.

At the moment I'm still struggling to prepare a build script for the native Subversion library (it turns out to be much easier on Linux, even though we have MinGW on Windows). I'll keep looking into it though, for now I'm also waiting for the new Subversion LTS release 1.14 to become available.

Let me know if you need some further advice!

frklan commented 4 years ago

Hi @A-Ovchinnikov-mx

Thanks for your input, I did not for one second consider to build svn itself. I'll try building it for windows in the comming days and see if I can get it up and running.

ahwm commented 3 years ago

I have a working build script for Subversion on Windows without MinGW (or other such utilities). I first installed Python 3.8 and OpenSSL from https://slproweb.com/products/Win32OpenSSL.html and downloaded Apache from ApacheLounge

https://gist.github.com/ahwm/47dca1ae4290094a539d5dcc30338fb9

Based on the work of https://github.com/Jan-E/svn-windows

JulidtheRealOne commented 3 years ago

Hello,

I'm having a bit of trouble getting started with this and was wondering if someone could give me a hand. Here is what I've got so far:

[using VS 2019 Community Edition] [using Windows 10 Pro]

-Downloaded LibSvnSharp via Zip file and extracted it. Opened the LibSvnSharp.sln using VS. -Checked-out the the Apache Subversion repo from: https://svn.apache.org/repos/asf/subversion/trunk -Downloaded APR and APR-util from the Apache site, and tracked down their dependencies (such as OpenSSL, Expat). Used CMake and VS to finish the APR and APR-util installation into C:\Program Files (x86).

Set the NativeBindingsGenerator settings to: -APR include dir: "C:\Program Files (x86)\APR\include" [files start with apr.h] -APR util include dir: "C:\Program Files (x86)\APR-Util\include" [files start with apr_anylock.h] -Lib SVN Sharp include dir: "{LibSvnSharp download dir}\include" [files start with libsvnsharp_auth.h] -Subversion Include dir:" {apache subversion checkout dir}\subversion\include" [files start with mod_authz_svn.h]

NativeBindingsGenerator builds with no errors

When I run NativeBindingsGenerator, most files are parsed but I get the following errors with 'svn_sorts_private.h' -{Subversion Include dir}\private\svn_sorts_private.h(128,1): error: unknown type name 'svn_error_t' -{Subversion Include dir}\private\svn_sorts_private.h(142,1): error: unknown type name 'svn_error_t'

And I kinda get stuck here. AND I still need to build LibSvnSharp.Native.Dll...but there is no point in me even trying to build the LibSvnSharp.Native.Dll if I can't even get the Generator to parse the source files.

Sorry! I'm really hopeless at complicated build scenarios...any help would be appreciated!

frklan commented 3 years ago

I have never gotten around to try comiling this again. However if I recall correctly, I had the same or similar error @JulidtheRealOne. I solved it (at least the error in NativeBindingsGenerator disapperad) by adding a #include in svn_sorts_private.h (the svn_error_t is defined in svn_types.h). Perhaps it's more "correct" to move line 86 in NativeBindingsGenerator/SvnLibrary.cs upwards so it's comes before line 84?

JulidtheRealOne commented 3 years ago

@frklan thanks for the suggestion! I'd love to get this library up and running some day... If I ever get a chance to try to compile this again, I'll let you know if either of those suggestions worked for me. In the mean time, stay safe out there!

ghost commented 3 years ago

Hi @frklan, @JulidtheRealOne, sorry that I couldn't respond earlier 😞

I'm afraid I never tested this code against any version of libsvn newer than 1.10. So something might have changed in the headers layout.

I've had a working build script but it is for Linux. I've tried to make it work on Windows in MinGW environment but there were quite some problems compiling it (I don't think libsvn officially supports building inside Cygwin/MinGW). So now I need a completely different approach for building libsvn on Windows and I didn't have much time to think about it yet.

Please feel free to submit pull requests if you find out something doesn't work for you on the latest version of libsvn. Note though that it would be better to focus on LTS versions (the latest LTS is 1.14). Thanks!

ahwm commented 3 years ago

So it turns out my SVN build was missing serf and running svn import would result in this error

svn: E170000: Unrecognized URL scheme for 'https://svn.domain.com/test-repository/....jpg'

Reference: https://github.com/Jan-E/svn-windows/issues/2

After some trial and error Jan-E got this figured out on AppVeyor and I used that to update my script: https://gist.github.com/ahwm/47dca1ae4290094a539d5dcc30338fb9

I also added comments for setup and operation. And that is based on 1.14.0 (the current LTS).

Still trying to figure out how to build LibSvnSharp.Native.dll and, therefore, LibSvnSharp. Unfortunately, I haven't had a lot of time to devote to it.

frklan commented 3 years ago

Phew, this was a handfull, but I believe I've managed to build everything. Thanks to the build script @ahwm linked to!

I did a couple of changes since my setup differs, e.g. different Visual Studio etc.

Below, I assume that we have the source in \build-svn, I used the subst command to make a drive alias (e.g. subst b: c:\source\svn).

Prerequisites

Compiling subversion

From the Visual Studio Developer prompt do

  1. run "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" or "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" depending on which Visual Studio version you have.

  2. Save following script in \build-svn (tripple check that all paths are correct; adjust accordingly) and run it

copy zlib-1.2.11\*.h .\Apache24\include
copy expat-2.2.9\expat\lib\*.h .\Apache24\include /y

cd \build-svn\zlib-1.2.11
nmake -f win32/Makefile.msc clean
nmake -f win32/Makefile.msc
copy *.lib \build-svn\Apache24\lib
copy *.dll \build-svn\Apache24\bin

set lib="C:\Program Files\OpenSSL\lib";\build-svn\zlib-1.2.11;\build-svn\Apache24\lib;%lib%
set include="C:\Program Files\OpenSSL\include";\build-svn\zlib-1.2.11;\build-svn\Apache24\include;%include%

cd \build-svn\serf-1.3.9
nmake /s /nologo /f serf.mak CLEAN APR_SRC=b:\build-svn\Apache24 APRUTIL_SRC=b:\build-svn\Apache24 ZLIB_SRC=b:\build-svn\Apache24 OPENSSL_SRC=B:\build-svn\Apache24
nmake /s /nologo /f serf.mak ALL APR_SRC=b:\build-svn\Apache24 APRUTIL_SRC=b:\build-svn\Apache24 ZLIB_SRC=b:\build-svn\Apache24 OPENSSL_SRC="C:\Program Files\OpenSSL"

if exist Release\serf-1.lib copy Release\serf-1.lib . /y

cd \build-svn\subversion-1.14.0
"C:\Program Files\Python27\python" gen-make.py --release -t vcproj --vsnet-version=2019 --with-apr-util=b:\build-svn\Apache24 --with-apr=b:\build-svn\Apache24 --with-apr-iconv=b:\build-svn\Apache24 --with-apr_memcache=b:\build-svn\Apache24 --with-httpd=b:\build-svn\Apache24 --with-openssl="C:\Program Files\OpenSSL" --with-zlib=b:\build-svn\Apache24 --with-sqlite=b:\build-svn\sqlite-amalgamation-3310100 --with-jdk="C:\source\bin\jdk-15.0.1" --with-serf=b:\build-svn\serf-1.3.9

devenv subversion_vcnet.sln /Build "Release|x64"

set path="C:\Program Files\OpenSSL\bin";b:\build-svn\Apache24\bin;b:\build-svn\subversion-1.14.0\Release;%path%

"C:\Program Files\Python27\python" win-tests.py --release --cleanup

md \build-svn\svn\bin
md \build-svn\svn\lib
md \build-svn\svn\modules
cd \build-svn\subversion-1.14.0
for /r %%f in (*.dll, *.exe) do @copy "%%f" \build-svn\svn\bin /y
for /r %%f in (*.lib) do @copy "%%f" \build-svn\svn\lib /y
for /r %%f in (*.so) do @copy "%%f" \build-svn\svn\modules /y
cd \build-svn\svn

Note that subversion's win-tests.py will take a long time to run, you might want to comment out the line while testing the build procedure. Some of the tests are failing for me right now, I don't understand why.

  1. The subversion executables and dlls should now be available in \build-sv\svn

Modify the subversion build

Since the LibSvnSharp library expects all subversion/apr methods exists in the same dll (LibSvnSharp.Native.dll) we need to add this target to the subversion build script. This can of cource be done prior to building subversion the first time by interrupting the script above after the gen-make.py has been run; or even better modifying the input to gen-make.py. I've updated LibSvnSharp to use the native apr dll (see below) and would like to do the same for subversion going forward. Anyhow, this is how I hacked the subversion build script.

  1. Open subversion-1.14.0\subversion_vcnet.sln and add a new C++ based dll target in Libraries/Dlls called libsharp_native_dll

  2. Make sure the target name is "LibSvnSharp.Native" and Configuration Type is Dynamic Library

  3. Copy all references and Additional Dependencies from all other targets in Libraries/Dlls to libsharp_native_dll

  4. Create a new Module Definition File (.def) for libsharp_native_dll and copy the content from all other targets in Libraries/Dlls

  5. Rebuild subversion (or build just libsharp_native_dll from Visual Studio, if you prefer).

In Subversion >1.13.0 the return type of svn_sortarray_insert2() and svn_sortarray_delete2() in subversion\include\private\svn_sorts_private.h changed from void to svn_error_t*. For some reason svn_error_t is not defined in svn_sorts_private.h. Hence the NativeBindingsGenerator will give an error parsing this file. A simple solution is to add #include "../svn_types.h" to svn_sorts_private.h. (Perhaps this error could be fixed in upstream subversion?)

Compiling LibSvnSharp

  1. Clone https://github.com/mendix/LibSvnSharp.git to your local machine

  2. Open LibSvnSharp\src\LibSvnSharp.sln in visual studio

  3. Update aprModule.SharedLibraryName = "LibSvnSharp.Native"; to aprModule.SharedLibraryName = "libapr-1"; in the Setup method in NativeBindingsGenerator\SvnLibrary.cs

4: Update NativeBindingsGenerator/App.config with correct paths, in my case I did:

  <NativeBindingsGenerator.Properties.Settings>
      <setting name="apr_include_dir" serializeAs="String">
          <value>B:\build-svn\Apache24\include</value>
      </setting>
      <setting name="aprutil_include_dir" serializeAs="String">
          <value>B:\build-svn\Apache24\include</value>
      </setting>
      <setting name="subversion_include_dir" serializeAs="String">
          <value>B:\build-svn\subversion-1.14.0\subversion\include</value>
      </setting>
      <setting name="libsvnsharp_include_dir" serializeAs="String">
          <value>B:\LibSvnSharp\include</value>
      </setting>
  </NativeBindingsGenerator.Properties.Settings>
  1. Build and run the NativeBindingsGenerator project

  2. Build the LibSvnSharp project (make sure that the platform match your subversion build, i.e. x64)

Use LibSvnSharp from a .Net project

LibSvnSharp can now be used from a simple c# based .net project, e.g. like so:

class Program {
  static void Main(string[] args) {

    var ver = LibSvnSharp.SvnClient.Version;
    Console.WriteLine($"svn client ver: {ver}");

    Console.WriteLine("Hit any key to checkout..");
    Console.ReadKey();

    var u = new SvnUriTarget("https://[svn-repo]");
    var client = new SvnClient();

    client.CheckOut(u, @"c:\repo");
    Console.WriteLine("Done!");
  }
}

Of cource all dlls needs to be copied from the respective build directories to the path of our exe.

I'm currently having an issue where the svn library can't verify the svn servers ssl certificate (unknown CA cert), most probably due to that openssl do not include any CA certs. I'm still trying to figure out how to do that.