将各种SBT任务与本机库(例如,来自JOGL,LWGL或JCuda的任务相结合的好方法是什么?具体来说,
是否建议在run
任务中包含本机库?关于SBT邮件列表的讨论表明了这些可能性:
JavaOptions
包含-Djava.library.path=<path to native libraries>
,然后修改run
任务以分叉JVM。 (有关示例,请参阅this plugin。)initialize
setting运行调用System.setProperty(...)
以配置java.library.path
的代码。同样,run
必须分叉。最后一个的优点是run
不需要fork,但缺点是配置必须在SBT之外完成。
我可以自动在sbteclipse插件生成的Eclipse项目中包含本机库吗?有可能rewrite the .project
file in a post-processing step.是否有示例代码?有更好的方法吗?
本地库是否可以包含在由sbt-assembly,sbt-onejar或sbt-proguard等插件生成的可运行Jar中?
我假设本机库没有直接的SBT设置。如果存在这样的事情,上述任务是否可以透明地处理本地库?
答案 0 :(得分:28)
根据我过去所做的研究,只有两种方法可以加载本机库:修改java.library.path
和使用System.loadLibrary
(我觉得大多数人这样做),或使用System.load
有绝对路径。
正如您所提到的,在配置SBT和Eclipse方面,弄乱java.library.path
可能会很烦人,我认为不可能自动执行可执行jar。
离开System.load
。在编写自己的本机库方面,您可以做的是:
javah
和gcc
),获取生成的.so文件及其依赖的任何.so文件,将它们放入jar中(作为资源) )在目标目录中,将jar的路径添加到unmanagedJars in Compile
。System.loadLibrary
,而是使用Class.getResourceAsStream
来读取库,File.createTempFile
将其写入文件系统的某个位置,而System.load
将其加载到JVM中。System.loadLibrary
,而是致电MyClasspathJniLoader.loadLibrary
。这将适用于SBT run,Eclipse和可执行jar,无需任何额外配置(尽管我不知道proguard如何知道要包含哪些资源)。
现在,对于已经编写过的第三方本机库,其中一些像jblas已经使用了这种“胖罐”方法。如果他们希望您设置java.library.path
,然后在他们感觉到时调用System.loadLibrary
,那么您需要做一些魔术才能实现这一目标。
我没试过这个,但这个解决方案可能有效:
java.library.path
,调用在函数中传递,最后将java.library.path
恢复为以前的状态。System.loadLibrary
调用时),使用它将加载的库列表将该特定调用包装在您的方法中。这样,当它调用System.loadLibrary
时,它的所有库都将在java.library.path
上,并且将成功加载。显然这很烦人,因为你必须在使用之前手动初始化第三方库,但是包装所有初始化点(主要功能和测试初始化)似乎比获取所有工具更可行正确设置java.library.path
。如果您已经在第三方库之上拥有自己的抽象层,那么它可能比这更容易,因此实际上只需要包装一个初始化点。
如果这看起来像是一个现实的解决方案,如果您感到困惑,我可以添加有关SBT任务或Scala包装器方法的更多详细信息。
答案 1 :(得分:0)
在Osx下,如果您在/lib/*.jnilib
期间在sbt test
中加载本机库时遇到问题。
[error] java.lang.UnsatisfiedLinkError: Fatal execution error, caused by no jniortools in java.library.path
您可以使用以下代码代替System.loadLibrary("jniortools")
。
new File("lib").listFiles().map(_.getAbsolutePath).filter(_.endsWith("jniortools.jnilib")).foreach(System.load)
答案 2 :(得分:0)
有一种简单的方法。
假设存储在 lib_extra 目录
中的本机库将jna添加到libraryDependencies:
libraryDependencies ++ = Seq(&#34; net.java.dev.jna&#34;%&#34; jna-platform&#34;% &#34; 4.1.0&#34)
将这些代码添加到build.sbt:
unileagedResourceDirectories in Compile + = baseDirectory.value /&#34; lib_extra&#34;
includeFilter in(Compile,unmanagedResourceDirectories):=&#34; .dll, .so&#34;