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

时间:2014-10-18 22:38:33

标签: java c++ macos java-native-interface myo

我正在构建一个通过C / C ++调用本机操作的API。我创建了一个JNI项目,并使用以下参数构建jnilib

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

我正在尝试让我的API自包含,所以所有库都在我的/ src / main / resources中,我只需将它们复制到临时目录,然后再设置java.library.path并加载我的JNI从那里的图书馆。我已经在Windows上工作,因为我只需要我的JNI DLL,以及我可以复制的另一个DLL。

当我在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

我认为这是因为我的@rpath设置不正确,我想知道设置它的“正确”方法。从java的角度来看,@rpath在哪里?如果它是相对的,或者在loader_path位置,那是哪个?我希望能够在运行时设置它,以便我可以复制我的库文件,然后指向它们用于程序的位置。

在Java中,我如何确定:@rpathloader_path?从哪里加载依赖框架?

2 个答案:

答案 0 :(得分:1)

@rpath的工作方式是每个可执行文件或库用框架列表替换框架安装名称中的@rpath,以便在链接时搜索框架。您看到的错误libmyo.jnilib无法找到myo.framework,因为其运行路径设置为@loader_path,这意味着它会在myo.framework中查找/private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/ }。

据我所知,myo.framework中有/Users/nstuart/Downloads/myo-sdk。 您可以通过调整运行路径或将myo.framework移动到输出目录来解决此问题。

参考:Myo SDK Reference小节"终端"

答案 1 :(得分:0)

我为JavaCPP Presets工作了。在我们链接的第三方库中,我们需要使用install_name_tool将构建过程中的任何内容更改为@rpath(在OpenCV的情况下为lib),如所示通过OpenCV的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
;;

要查找myo的BADPATH,我们可以使用otool -L命令。修复框架库文件后,您需要重建libmyo.jnilib文件。