Cmake 在jar文件中封装JNI库
我正在尝试为斐济/ImageJ开发一个依赖于本机库(JNI)的插件。 JNI库本身依赖于Cmake 在jar文件中封装JNI库,cmake,java-native-interface,imagej,Cmake,Java Native Interface,Imagej,我正在尝试为斐济/ImageJ开发一个依赖于本机库(JNI)的插件。 JNI库本身依赖于libtiff和fftw。在OSX和Linux上,我使用这个类,一切正常 在windows上,我在CMake包中包含了libtiff和fftw的二进制版本,并设法将JNI库与之链接(静态或动态)。但是,生成的JNI模块不包括libtiff或fftw,当我尝试使用NativeUtils.loadLibraryFromJar加载JNI库时,我得到一个错误。当我在.jar中包含依赖的.dll时也是如此,因为它们不是
libtiff
和fftw
。在OSX和Linux上,我使用这个类,一切正常
在windows上,我在CMake
包中包含了libtiff
和fftw
的二进制版本,并设法将JNI库与之链接(静态或动态)。但是,生成的JNI模块不包括libtiff
或fftw
,当我尝试使用NativeUtils.loadLibraryFromJar
加载JNI库时,我得到一个错误。当我在.jar
中包含依赖的.dll
时也是如此,因为它们不是由NativeUtils
提取的
以下是CMakeLists.txt
中的相关行:
add_library(fftw STATIC IMPORTED GLOBAL)
set_target_properties(fftw PROPERTIES IMPORTED_LOCATION "${libdir}/libfftw3f-3.lib"
INTERFACE_INCLUDE_DIRECTORIES "${incdir}")
SWIG_ADD_LIBRARY(javainterf
TYPE MODULE
LANGUAGE java
SOURCES javainterf.i javainterf.c src1.c)
SWIG_LINK_LIBRARIES(javainterf libcode1 fftw)
add_jar(Foo
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/java/foo1.java
INCLUDE_JARS java/resources/ij-1.51p.jar
VERSION ${JAR_VERSION})
add_dependencies(Foo javainterf)
add_custom_command(TARGET Foo POST_BUILD
COMMAND "${Java_JAR_EXECUTABLE}" -uf Foo-${JAR_VERSION}.jar
-C ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} ${JNI_LIB_NAME})
如何确保所有依赖项都正确地包含在jar中并加载?如果不首先提取库,就无法从jar内部加载库 这里看一看完整的示例,其中本机代码嵌入到JAR中,并在需要时提取 更新 那么,在这种情况下,当您需要打包更多的lib并希望正确解析位置时,您需要稍微使用runtime env 请看这里:
享受JNI带来的乐趣 这里的问题是,我有几个依赖库,一次只提取一个。我不知道如何使用cmake将所有依赖项合并到一个dll中。您始终可以提取所有库并使用System.load加载所有库。毕竟,这只是关于从libs加载的符号。我的jni库依赖于一些非jni共享库。尽管它们不是jni,但我尝试使用
loadlibraryfromjar
加载它们,但它不起作用:我得到了同样的错误。我还没有时间测试您的解决方案。但是谢谢你花时间为我写一份额外的食谱。一有机会我就接受你的答案。谢谢>“您不能从JAR内部加载库而不首先提取它。”这是什么意思?我只是把我的DLL放在.jar中,它可以正常工作(使用JNA),这不是一个完整的解决方案,但是你读过ImageJ文档的页面了吗?您是否尝试过将本机库放在$IJ_ROOT/lib/
中,而不是嵌入到JAR文件中?我考虑过这一点,但这会使最终用户的安装更加复杂。如果@mko提出的解决方案对我有效,我会尝试将所有东西都包含在jar中。我不理解你对安装的担忧。如果您使用了,只需单击用户端部的按钮,您就可以将所有需要的文件发送给用户,用户也会自动接收更新。@ctrueden我只是不知道这一点。我试试看。谢谢
git clone https://github.com/mkowsiak/jnicookbook
cd jnicookbook/recipes/recipeNo035
make
make test