Search code examples
java-native-interfacemingwcross-compiling

JNI Cross Compiled from OS-X to Windows Fails with "Can't find dependent libraries"


I have a Java JNI program that I am building on Apple OS-X and cross-compiling for Windows 10.

The build and runs fine on OS-X. Cross-compiling for Windows 64-bit completes with no errors, but the generated program fails to run under Windows 10 and gives the error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\Michael\Documents\JNIExample\MyLib.dll: Can't find dependent libraries

The error occurs only when I add a reference to the C++ new operator. When this is removed the "Can't find dependent libraries" goes away and the application runs. This program did once run with earlier versions of these tools and operating systems.

My guess is that I am missing something crucial from the x86_64-w64-mingw32-gcc to include a statically bound library required for the new operator. Can anyone help?

The command used to build the project are in the bash shell script file: doit.sh

#!/bin/bash

    echo "=== Building on OS-X ==="

    export JAVA_HOME="`/usr/libexec/java_home -v '14*'`"
    
    # Clean up
    rm -rf bin/*.class MyLib/*.o *.dll *.jnilib *.jar
    
    # Compile Java and generate JNI header file
    mkdir -p bin
    javac -d bin -h MyLib -sourcepath src src/*.java

    # Create the JAR file, main entry point in class MyLib
    jar cfe Test.jar MyLib -C bin .
    
    # Build the C++ shared library
    gcc -c -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/darwin" MyLib/MyLib.cpp -o MyLib/MyLib.mac.o
    g++ -dynamiclib -o libMyLib.jnilib MyLib/*.mac.o
    
    echo "=== Running on OS-X ==="
    java -jar Test.jar

    echo "=== Building on OS-X ==="
    
    # Cross compile for the Windows shared library
    /usr/local/bin/x86_64-w64-mingw32-gcc -D __LP64__ -c -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin MyLib/MyLib.cpp -o MyLib/MyLib.win.o
    /usr/local/bin/x86_64-w64-mingw32-g++ -shared -static-libgcc -static-libstdc++ -o MyLib.dll MyLib/*.win.o

My aim is to make a Windows and Mac distribution of the application using jlink and jpackage so all libraries will ultimately be needed by included with my final distribution.

Tool Versions
| Tool                       | Version |
|-------------------------|----------------------|
| MacBook Pro | OS-X Catalina 10.15.6 |
| x86_64-w64-mingw32-gcc/g++ | 9.3.0 (GCC) (download with brew install mingw-w64) |
| gcc/g++                    | Apple clang version 12.0.0 (clang-1200.0.31.1) |
| java                       | java version "14.0.1" 2020-04-14 |
x86_64-w64-mingw32-gcc -v Output
michaelellis$ /usr/local/bin/x86_64-w64-mingw32-gcc -v
Using built-in specs.
COLLECT_GCC=/usr/local/bin/x86_64-w64-mingw32-gcc
COLLECT_LTO_WRAPPER=/usr/local/Cellar/mingw-w64/7.0.0_2/toolchain-x86_64/libexec/gcc/x86_64-w64-mingw32/9.3.0/lto-wrapper
Target: x86_64-w64-mingw32
Configured with: ../configure --target=x86_64-w64-mingw32 --with-sysroot=/usr/local/Cellar/mingw-w64/7.0.0_2/toolchain-x86_64 --prefix=/usr/local/Cellar/mingw-w64/7.0.0_2/toolchain-x86_64 --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --enable-languages=c,c++,fortran --with-ld=/usr/local/Cellar/mingw-w64/7.0.0_2/toolchain-x86_64/bin/x86_64-w64-mingw32-ld --with-as=/usr/local/Cellar/mingw-w64/7.0.0_2/toolchain-x86_64/bin/x86_64-w64-mingw32-as --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --disable-multilib --enable-threads=posix
Thread model: posix
gcc version 9.3.0 (GCC) 

The full SSCCE is available on public git at: https://gitlab.com/Michael51773/jniexample


Solution

  • Next step in investigating this was to create a simple C++ standalone command-line app that utilised the shareable library.

    This built and ran correctly on OS-X but when deploying the cross-compiled products to the Windows platform it failed to execute listing the following libraries as missing:

    • libstc++-6.dll
    • libwinpthread-1.dll
    • libgcc_s_seh

    Copying these files from the mingw distribution /usr/local/Cellar/mingw-w64/7.0.0_2/toolchain-x86_64/x86_64-w64-mingw32/.. into the same directory as the application on the Windows platform solved the problem!

    It looks to me as if the mingcw g++ -static-libgcc -static-libstdc++ may not be working as they used to!