msteinbeck / tinyspline

ANSI C library for NURBS, B-Splines, and Bézier curves with interfaces for C++, C#, D, Go, Java, Javascript, Lua, Octave, PHP, Python, R, and Ruby.
MIT License
1.19k stars 206 forks source link

Providing native jar files for common platforms #140

Closed ivanshuba closed 5 years ago

ivanshuba commented 5 years ago

@msteinbeck Can you please provide a concise guide on creating the jar/dll file needed for using the tinyspline with Java?

I understand that the library is designed such that everyone could compile it for its own target platform and include specific language bindings he/she requires. I understand that it is simply impossible to include prebuilt jar files in the repository since there are lots of operating systems and JDK versions.

But for the non-C/C++ people, dealing with all these options:

it is a total nightmare because the number of options is terrifying and drive me nuts.

I've tried several times. Every time something happens, googling doesn't help much since it points to even more infinite googling and searching. .

P.S. Though, providing these files directly in the repository (as revisions) would be awesome and definitely boost-up the number of tinyspline users.

msteinbeck commented 5 years ago

Hi @ivanshuba

I know that users don't want to struggle with TinySpline's build environment, and I actually began to create pre-built binaries for Linux, OSX, and Windows. In tools/ci you'll find shell scripts (i.e. build.linux-x86_64.sh) that are supposed to create bindings using docker images. Unfortunately, however, creating distribution-ready-binaries for Windows is not that easy because Windows, unlike Linux and OS X, does not install the standard library of the MSVC/MinGW compiler out-of-the-box. That is, you need to install the compiler specific dlls (i.e. libstdc++-6.dll if the binding was built with MinGW) in order to load the native library of the binding. Usually, applications bundle the necessary libraries so that a user does not have to install these dlls by their own. Before I can start creating bindings for Windows, I need to find out how to determine the compiler specific libraries though (I already have some ideas). Once this is solved, I can create bindings from a single host and compose the platform specific native libraries into the final jar which, in turn, can be published at maven central.

@msteinbeck Can you please provide a concise guide on creating the jar/dll file needed for using the tinyspline with Java?

I guess you are using Windows (because you mention cygwin and mingw). Make sure that you installed MinGW for x86_64 (64 bit). You also need to install Swig and CMake (I recommend chocolatey which is a package manager for Windows). Once MinGW is installed you should have a "MinGW Shell" shortcut in your start menu. If you run this shell, all MinGW specific settings should be applied correctly. Make sure that the swig and cmake binaries are available in your shell. To check, run the following command: where swig and where cmake. If these commands are not available, make sure to add their location to the PATH variable (https://www.java.com/en/download/help/path.xml). Reopen! the "MinGW Shell" (otherwise swig and cmake are still not available). Navigate (in your shell) to the directory where you cloned/downloaded TinySpline and create a new folder: mkdir build. Navigate into build and run cmake: cmake ... This will auto detect MinGW and configure the build environment. To enable Java, run the following command: cmake -DTINYSPLINE_ENABLE_JAVA=true ... Afterwards, create all targets with: cmake --build .. The resulting jar should be available at the lib directory. Copy the jar to examples/java. Compile and run the Java example QuickStart.java as described in the INFO file. Make sure to run the example in your "MinGW Shell". Otherwise, MinGW's library cannot be found. If you want to run your Java-Application without a MinGW shell, make sure that libstdc++-6.dll is available in PATH (see above).

ivanshuba commented 5 years ago

@msteinbeck Thank you for the reply and for taking the time to explain the procedure!

Yes, you're right - I'm using Windows 7x64. Previously, I've tried to use the Cygwin and the portable version of the CMake-gui without luck.

As you've suggested, I installed the MinGW x86_64 version from Sourceforge, the link was listed here: image But it doesn't put the "MingGW-Shell" shortcut in the Start menu, even after I reopen command interpreter (or login-then-logout, or reboot) and I can't find such shortcut/executable on the C: drive where I installed it.

Therefore I've removed it and switched back to Cygwin (from the same source mentioned above): image

This way I obtain "Cygwin64 Terminal" in the Start menu. Next, I'm installing the Chocolately and then swig and cmake.

After that I'm running the Cygwin terminal and follow the procedure as you've described:

  1. Check that I can call swig and cmake from command line :heavy_check_mark:
  2. Clone the tinyspline repository on the hard drive :heavy_check_mark:
  3. Go inside that folder and create a new build folder :heavy_check_mark:
  4. Go inside the build folder and run cmake -DTINYSPLINE_ENABLE_JAVA=True .. :x:

At this step, I receive the Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY) error: image

I understand that I should insert some paths (probably the ones pointing to some folders inside the JDK installation folder) into some config file (probably the PATH_TO\tinyspline\CMakeLists.txt) but I'm not sure. Could you please advise me what paths and where should I put?

msteinbeck commented 5 years ago

@ivanshuba I never tested Cygwin, thus I don't know if any of the targets can be compiled at all. At best Cygwin is detected as GCC. I'll test Cygwin later this day and, if possible, commit a fix. However, I guess you missed to add the JAVA_HOME environment variable to your system, which is used by many tools (i.e. CMake) to detect your Java installation: https://confluence.atlassian.com/doc/setting-the-java_home-variable-in-windows-8895.html

ivanshuba commented 5 years ago

@msteinbeck I've checked that the JAVA_HOME variable is present and can be seen from the Cygwin terminal: image

msteinbeck commented 5 years ago

Maybe your Cygwin environment does not support your Java installation. TBH I'm not familiar with Cygwin and I don't know if you need to install Java through Cygwin. The easiest approach would be using MingGW as it is covered by the test suite.

You said that you installed MinGW from the official website but didn't get the MinGW shell shortcut? Maybe installing MinGW from chcolatey installs the necessary parts (or makes the .bat files available in your shortcut menu). In any case, the shell should be available in MinGW's installation directory.

When setting up CMake with MinGW you may have an error saying that sh.exe must not be in your path. You can either delete or rename this file (which is quite invasive, see https://github.com/msteinbeck/tinyspline/blob/master/tools/ci/build.ps1#L57) or you can try to pass the following argument to CMake: -DCMAKE_SH="CMAKE_SH-NOTFOUND". For example: cmake -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DTINYSPLINE_ENABLE_JAVA=true ..

msteinbeck commented 5 years ago

@ivanshuba I checked my local MinGW installation and I also have no "MinGW Shell" shortcut. However, running the suggested commands from the Windows shell (and powershell) works as expected. I will now try Cygwin.

msteinbeck commented 5 years ago

I tested several things to compile the source files with Cygwin but was unable to create any binary. Adding support for Cygwin won't be easy because I have to add several Cygwin specific settings to the CMake config file. Cygwin is primarily used to compile and run POSIX compliant software whereas MinGW is designed to compile code for Windows. Thus, I will not add explicit support for Cygwin.

ivanshuba commented 5 years ago

@msteinbeck Thank you for taking the time for helping me. Can I try to follow the steps you're taking to compile the library using MinGW? I mean, could you provide the step-by-step guide including the links for the website from which you download your MinGW tool suite (there are several resources for this available on the internet). Please also mention the options I should select (some MinGW tool suits provide get utilities for manual selecting packages which should be downloaded) during installation. I will report to you the results of my efforts.

msteinbeck commented 5 years ago

@ivanshuba I ran the following commands to install all dependencies, compile the library, and run example code. Depending on your local setup, you may have to vary particular commands:

  1. Open a new cmd shell with administration privileges.
  2. Install chocolatey (you may skip this step because you already installed chocolatey):
    @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
  3. Apply new settings by opening a new cmd shell with administration privileges.
  4. Install dependencies (you may skip the installation of adoptopenjdk because you already have a viable Java installation):
    choco install mingw
    choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'
    choco install swig
    choco install adoptopenjdk

On my system I have a Git installation which leads to a failure while setting up TinySpline's CMake environment (due to the sh.exe provided by Git). The quickfix is to remove sh.exe. However, this may break your local setup. You may want to just rename sh.exe to sh2.exe. If you didn't install Git or sh.exe is not available in your shell (where sh.exe), you don't need to run the following command (note that your installation path may vary):

del "C:\Program Files\Git\bin\sh.exe"
  1. Download TinySpline from Github (or clone the repository).
  2. Create a build directory and set up the CMake environment:
    mkdir build
    cd build
    cmake -G "MinGW Makefiles" -DTINYSPLINE_ENABLE_JAVA=true ..
    cmake --build . --target tinysplinejava
  3. Copy the resulting jar file into the corresponding example directory:
    copy lib\tinyspline.jar ..\examples\java
  4. Change into the example directory:
    cd ..\examples\java
  5. Compile and run the QuickStart example:
    javac -cp tinyspline.jar QuickStart.java
    java -cp tinyspline.jar;. QuickStart

Note that on my system MinGW's libstdc++-6.dll is available in the PATH environment variable, thus, I don't need to copy it next the .class files. If you installed MinGW through chocolatey, libstdc++-6.dll should also be available in PATH. The location of libstdc++-6.dll on my system is: C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin\libstdc++-6.dll.

ivanshuba commented 5 years ago

@msteinbeck

Hello Marcel!

Below is the step-by-step report of me following your guide:

1. Running all the subsequent commands from the cmd shell with administrative privileges :heavy_check_mark:

image (sorry for Cyrillic characters on the picture, it shows that I'm using the context (RMB) menu to run the cmd.exe with administrator privileges)

2. Installed chocolately previously already :heavy_check_mark:

image

3. Apply new settings by opening a new cmd shell with administration privileges. :heavy_check_mark:

4. (Re)Install all dependencies, :heavy_check_mark:

(only cmake package status is shown on the picture below because of the relation to error reported later in this answer) image

5. Clone TinySpline repository from Github on the harddrive :heavy_check_mark:

image

6. Create a build directory and set up the CMake environment :warning:

a. Create a build directory :heavy_check_mark: image b. Set up the cmake environment is the step that I was unable to reproduce :x:

When I'm running the line

cmake -G "MinGW Makefiles" -DTINYSPLINE_ENABLE_JAVA=true ..

I got the 'cmake' is not recognised as an internal or external command error image

Though, the PATH environment variable contains the path to chocolately's mingw/bin image the path itself doesn't contain any cmake.exe image

The searching inside the whole C:\ProgramData\chocolatey folder also showed that there is no at least one cmake executable. Even when I searched the whole C: disk for the cmake.exe I didn't find any such file.

BUT :exclamation:, the same search on all hard drives showed that I after all these several day efforts I had couple cmake.exe on my hard drive in different places.

Therefore I chosed one, and temporarily added the path to its cmake\bin folder to my system PATH with

E:\TMP\TEST\tinyspline\build>path=%path%;D:\cmake-3.12.2-win64-x64\bin

and proceeded again with your instructions:

7. Copy the resulting jar file into the corresponding example directory :heavy_check_mark:

8. Change into the example directory :heavy_check_mark:

9. Compile and run the QuickStart example :warning:

a. Compile the QuickStart example :heavy_check_mark: image b. Run the QuickStart example :x: Despite I was unable to run the compiled example from the command line and got Error: Could not find or load main class QuickStart, I already guessed that this might be caused by the JDK9+ module system. image

Therefore, I've created a simple project in Eclipse (the version which supports JDK9+), copied and added the jar file we've compiled in the previous steps to the build path of the project. Then I was able to copy the examples into the project and fix the warnings using IDE suggestions - it simply adds the tinyspline lib/jar into module-info.java:

module tinysplinetest {
    requires java.base;
    requires tinyspline;
    requires java.desktop;
}

At last, both examples can be executed from Eclipse !!! image

I'm happy! :smile: Thank you! I very appreciate for your help!

msteinbeck commented 5 years ago

I'm surprised that running the quickstart example from command line fails because I tested it with JDK11. However, you finally have a working example, allowing you to explore TinySpline's features :). If you have further questions, feel free to open another issue.

msteinbeck commented 5 years ago

FYI: I managed to create a jar containing all relevant files for Windows, Linux, and MacOSX (64 bit only). The jar archive is available at releases. Travis will automatically create a snapshot build on each commit.

ivanshuba commented 5 years ago

Thank you for letting me know!

I've downloaded the tinyspline-0.3.0-1.jar and tested it with your Swing demo - it works smoothly!