从OS-X到Windows的JNI Cross编译失败,并显示“找不到依赖库”

问题描述

我有一个Java JNI程序,该程序是在Apple OS-X上构建并针对Windows 10进行交叉编译的。

该版本可以在OS-X上正常运行。 Windows 64位的交叉编译没有任何错误,但是生成的程序无法在Windows 10下运行,并显示以下错误:

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

当我添加对C ++ new 运算符的引用时,错误仅发生。删除后,“找不到依赖库”消失,应用程序运行。该程序曾经与这些工具和操作系统的早期版本一起运行。

我的猜测是,我缺少x86_64-w64-mingw32-gcc的重要内容,其中包括新操作符所需的静态绑定库。有人可以帮忙吗?

用于构建项目的命令位于bash shell脚本文件中: 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

我的目标是使用jlink和jpackage制作Windows和Mac发行版的应用程序,因此最终发行版中将最终需要所有库。

工具版本
| 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输出
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) 

完整的SSCCE可以在公共git上找到:https://gitlab.com/Michael51773/jniexample

解决方法

调查此问题的下一步是创建一个使用可共享库的简单C ++独立命令行应用程序。

这可以在OS-X上正确构建并运行,但是在将交叉编译的产品部署到Windows平台时,它无法执行,列出以下缺少的库:

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

将这些文件从mingw发行版/usr/local/Cellar/mingw-w64/7.0.0_2/toolchain-x86_64/x86_64-w64-mingw32/ ..复制到与Windows平台上的应用程序相同的目录中即可解决问题!

在我看来,mingcw g ++ -static-libgcc -static-libstdc ++ 可能无法像以前那样工作!

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...