将各种SBT任务与本机库(例如,来自JOGL,LWGL或JCuda的那些)集成的好方法是什么?具体来说,
是否有推荐的方法在run
任务中包含本机库?关于SBT邮件列表的讨论表明了这些可能性:
JavaOptions
为包含-Djava.library.path=<path to native libraries>
,然后修改run
任务以分叉JVM.(有关示例,请参阅此插件.)initialize
设置运行调用System.setProperty(...)
configure的代码java.library.path
.再次,run
必须分叉.最后一个的优点是run
不需要fork,但缺点是配置必须在SBT之外完成.
我可以自动在sbteclipse插件生成的Eclipse项目中包含本机库吗?可以在后处理步骤中重写.project
文件.有示例代码吗?有没有更好的办法?
本机库是否可以包含在由sbt-assembly,sbt-onejar或sbt-proguard等插件生成的可运行Jar中?
我假设本机库没有直接的SBT设置.如果存在类似的东西,上述任务是否可以透明地处理本机库?
Mik*_*ike 28
根据我过去所做的研究,只有两种方法可以加载本机库:修改java.library.path
和使用System.loadLibrary
(我觉得大多数人都这样做),或者使用System.load
绝对路径.
正如你所提到的那样,java.library.path
在配置SBT和Eclipse方面,搞乱可能很烦人,我认为不可能自动为可执行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运行,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包装器方法的更多详细信息.