简体   繁体   English

如何在Mac上的JNI构建中包括外部框架/库

[英]How to include an external framework/library in my JNI build on Mac

I have an API I am building that calls native operations through C/C++. 我正在构建一个API,该API通过C / C ++调用本机操作。 I have created a JNI project and built the jnilib using the following arguments: 我创建了一个JNI项目,并使用以下参数构建了jnilib

g++ -dynamiclib -rpath @loader_path -F /Users/nstuart/Downloads/myo-sdk -framework myo -framework JavaVM -o libmyo.jnilib *.o

I'm trying to have my API be self-contained, so all the libraries are in my /src/main/resources and I just copy them to a temp directory before setting the java.library.path and loading my JNI library from there. 我试图使我的API独立,因此所有库都在我的/ src / main / resources中,我只是将它们复制到临时目录,然后再设置java.library.path并从那里加载我的JNI库。 I've gotten this to work on Windows, as I just need my JNI DLL, and another DLL that I can copy over too. 我已经在Windows上运行了它,因为我只需要我的JNI DLL和另一个我也可以复制的DLL。

When I try this on Mac, I run into issues: 在Mac上尝试此操作时,遇到了以下问题:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/libmyo.jnilib: dlopen(/private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/libmyo.jnilib, 1): Library not loaded: @rpath/myo.framework/Versions/A/myo
  Referenced from: /private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/libmyo.jnilib
  Reason: image not found

I assume this is because I have my @rpath set up incorrectly, and I'm wondering the "correct" way to set it up. 我认为这是因为我的@rpath设置不正确,并且我想知道设置它的“正确”方法。 From the perspective of java, where is @rpath ? 从Java的角度来看, @rpath在哪里? If it's relative, or at the loader_path location, where is that? 如果是相对的,或者在loader_path位置,那在哪里? I would prefer to be able to set this at run time such that I can copy over my library files, then point to where they are for the program. 我希望能够在运行时进行设置,以便可以复制库文件,然后指向程序所在的位置。

In Java, how do I determine: @rpath ? 在Java中,如何确定: @rpath loader_path ? loader_path Where dependent frameworks are being loaded from? 从哪里加载依赖框架?

The way @rpath works is each executable or library replaces @rpath in the framework's install name with a list of directories to search for the framework when linking to it. @rpath工作方式是每个可执行文件或库都用目录列表替换框架安装名称中的@rpath ,以在链接到框架时搜索该框架。 The error you're seeing is libmyo.jnilib being unable to find myo.framework since its runpath is set to @loader_path , meaning it will look for myo.framework in /private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/ . 你看到的错误是libmyo.jnilib暂时无法找到myo.framework因为它的运行路径设置为@loader_path ,这意味着它会寻找myo.framework/private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/

From what I can tell, you have myo.framework in /Users/nstuart/Downloads/myo-sdk . 据我所知,您在/Users/nstuart/Downloads/myo-sdk具有myo.framework You can fix the issue by adjusting your runpath, or moving myo.framework to your output directory. 您可以通过调整运行路径或将myo.framework移至输出目录来解决此问题。

Reference: Myo SDK Reference subsection "Terminal" 参考: Myo SDK参考小节“终端”

I got that working for the JavaCPP Presets . 我已经为JavaCPP Presets工作了。 On the third-party libraries we link with, we need to use install_name_tool to change whatever the build process put there to @rpath (which is lib in the case of OpenCV), as demonstrated by these lines in the cppbuild.sh script for OpenCV: 在我们链接的第三方库上,我们需要使用install_name_tool将构建过程中的所有内容更改为@rpath (在OpenCV中为lib ),如OpenCV的cppbuild.sh脚本中的以下行cppbuild.sh

VER=${OPENCV_VERSION:0:3}
BADPATH=lib
LIBS="../lib/libtbb.dylib ../lib/libopencv_*.$VER.dylib"
for f in $LIBS; do install_name_tool $f -id @rpath/`basename $f` \
    -add_rpath /usr/local/lib/ -add_rpath /opt/local/lib/ -add_rpath @loader_path/. \
    -change libtbb.dylib @rpath/libtbb.dylib \
    -change $BADPATH/libopencv_core.$VER.dylib @rpath/libopencv_core.$VER.dylib \
    -change $BADPATH/libopencv_calib3d.$VER.dylib @rpath/libopencv_calib3d.$VER.dylib \
    -change $BADPATH/libopencv_features2d.$VER.dylib @rpath/libopencv_features2d.$VER.dylib \
    -change $BADPATH/libopencv_flann.$VER.dylib @rpath/libopencv_flann.$VER.dylib \
    -change $BADPATH/libopencv_gpu.$VER.dylib @rpath/libopencv_gpu.$VER.dylib \
    -change $BADPATH/libopencv_highgui.$VER.dylib @rpath/libopencv_highgui.$VER.dylib \
    -change $BADPATH/libopencv_imgproc.$VER.dylib @rpath/libopencv_imgproc.$VER.dylib \
    -change $BADPATH/libopencv_legacy.$VER.dylib @rpath/libopencv_legacy.$VER.dylib \
    -change $BADPATH/libopencv_ml.$VER.dylib @rpath/libopencv_ml.$VER.dylib \
    -change $BADPATH/libopencv_nonfree.$VER.dylib @rpath/libopencv_nonfree.$VER.dylib \
    -change $BADPATH/libopencv_objdetect.$VER.dylib @rpath/libopencv_objdetect.$VER.dylib \
    -change $BADPATH/libopencv_photo.$VER.dylib @rpath/libopencv_photo.$VER.dylib \
    -change $BADPATH/libopencv_video.$VER.dylib @rpath/libopencv_video.$VER.dylib; done
;;

To find what we have as BADPATH for myo, we can use the otool -L command. 为了找到我们有什么作为BADPATH为肌,我们可以使用otool -L命令。 Once the framework library file is fixed, you would need to rebuild your libmyo.jnilib file. 框架库文件固定后,您将需要重建libmyo.jnilib文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM