3

I'm trying to use JPL with SWI-Prolog on macOS High Sierra and I'm having troubles. In fact, at first the libjpl.dylib was not found so I added the path to it to java.library.path via

java -Djava.library.path=/Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin15.6.0/

Now the library is found but I get another error:

java.lang.UnsatisfiedLinkError: /Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin15.6.0/libjpl.dylib: dlopen(/Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin15.6.0/libjpl.dylib, 1): Library not loaded: @executable_path/../swipl/lib/x86_64-darwin15.6.0/libswipl.dylib
  Referenced from: /Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin15.6.0/libjpl.dylib
  Reason: image not found
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    ...

From what I understand, this is caused by this version of SWI-Prolog being relocatable (and thus having path relative to the executable).

The output of otool -L of the libjpl.dylib give me this output:

/Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin15.6.0/libjpl.dylib:
    @rpath/libjsig.dylib (compatibility version 1.0.0, current version 1.0.0)
    @rpath/libjvm.dylib (compatibility version 1.0.0, current version 1.0.0)
    @executable_path/../swipl/lib/x86_64-darwin15.6.0/libswipl.dylib (compatibility version 0.0.0, current version 7.6.4)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

So one way of fixing it would be to install a not relocatable version via macport or homebrew.

The thing is, neither the MacPorts nor the Homebrew version of SWI-Prolog contains the libjpl.dylib library :/

Am I missing something here? What can I do to make this work?

4

2 回答 2

2

在 macOS 10.13.6 (High Sierra) 上,我经常使用以下方法编译 SWI-Prolog 7.x 源代码:

$ make distclean && ./build && swipl -g "jpl_config_dylib" -t halt

jpl_config_dylib/0查找并修复 Java 路径。启动应用程序后,您还应该能够从顶层调用它SWI-Prolog.app

于 2018-09-23T17:57:37.057 回答
1

这对谁可能有用,因为它不是 100% 匹配所问问题的内容,而是 100% 匹配所问问题的标题。

使用 Homebrew 安装(至少是最新版本的)SWI-Prolog 时,尝试use_module(library(jpl))将导致错误:

ERROR: /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/library/jpl.pl:5428: Initialization goal raised exception:
ERROR: source_sink `jar('jpl.jar')' does not exist
ERROR: In:
ERROR:   [48] throw(error(existence_error(source_sink,...),_109418))
ERROR:   [44] jpl:add_jpl_to_classpath at /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/library/jpl.pl:3979
ERROR:   [43] jpl:setup_jvm at /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/library/jpl.pl:4168
ERROR:   [42] '$run_init_goal'(jpl:setup_jvm) at /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/boot/init.pl:796
ERROR:   [41] catch(system:'$run_init_goal'(...),error(existence_error(source_sink,...),context(_109584,_109586)),system:'$initialization_error'(...,...,...)) at /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/boot/init.pl:546
ERROR:   [40] catch_with_backtrace(system:'$run_init_goal'(...),error(existence_error(source_sink,...),context(_109660,_109662)),system:'$initialization_error'(...,...,...)) at /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/boot/init.pl:614
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
ERROR: Exported procedure jpl:jpl_c_lib_version/1 is not defined
true.

此外,执行目标jpl_config_dylib会导致错误:

?- jpl_config_dylib.
ERROR: Unknown procedure: jpl_config_dylib/0 (DWIM could not correct goal)

SWI-Prolog 的 MacPorts 版本没有这个问题。解决方法是将 MacPorts 版本下的相关文件复制到 SWI Prolog 的 Homebrew 版本下:

$ cp /Applications/SWI-Prolog.app/Contents/swipl/lib/jpl.jar /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/lib/
$ cp /Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin/libjpl.dylib /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/lib/x86_64-darwin/
$ cp /Applications/SWI-Prolog.app/Contents/swipl/library/jpl.pl /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/library/
$ cp /Applications/SWI-Prolog.app/Contents/swipl/library/jpl_config.pl /usr/local/Cellar/swi-prolog/8.4.0/libexec/lib/swipl/library/

之后加载library(jpl)将正常工作:

?- use_module(library(jpl)).
true.

?- jpl_new('java.lang.Object', [], JRef).
JRef = <jref>(0x7fbefb086318).
于 2021-10-04T15:34:21.137 回答