我正在为 clojure 编写一个涉及本机代码的库。当我将 clojure 库部署到公共存储库(如 clojars)时,如何捆绑共享库(也称为本机依赖项)?
更多信息:
我的项目结构大致如下:
src/
native/ - C code , C Object files and compiled shared libs
java/ - Java stuff
clojure/ - Clojure stuff
我目前正在使用leineingen。我尝试过这样做:
:jvm-opts [~(str "-Djava.library.path=src/native/:"
(System/getenv "$LD_LIBRARY_PATH"))]
如果我在该项目中,它会起作用。但是,如果我将此项目作为依赖项包含在内,我将得到UnsatisfiedLink
error.
答案取决于您的具体用例。在最简单的情况下,您需要:
- 将本机 lib 捆绑到库 jar 中,例如通过包含
native/
文件夹中:resource-paths
在你的project.clj
.
- 当你使用你的库时,你可以指定一个
:native-prefix
选项来指示应从中提取本机库的库 jar 内的路径。例如,如果您的库在根文件夹中包含资源“mylib.so”,您可以这样指定它:[com.foo/bar "1.0.1" :native-prefix ""]
- 您还应该使用以下命令指定提取的库的位置
:native-path
选项在你的project.clj
.
- 最后,你应该添加
:native-path
你已指定java.library.path
, using :jvm-opts
像你说的。
这些选项记录在莱宁根项目示例.clj https://github.com/technomancy/leiningen/blob/master/sample.project.clj.
现在我说这取决于你的用例的原因是,如果你想创建一个包含本机库的 uberjar,事情就会开始变得更加混乱。主要原因是您无法直接链接到压缩在 jar 内的库。如果幸运的话,您将能够使用loadLibraryFromJar
方法中的NativeUtils https://github.com/adamheinrich/native-utils/blob/master/NativeUtils.java班级。不过,我记得有ClassLoader
阻止我使用的相关问题System/load
。相反,我必须确保该库存在于 JVM 查找的路径之一中,以便System/loadLibrary
找到它是正确的。这是我最终所做的:
- 在运行时手动将本机库从 uberjar 提取到临时文件夹,使用
(-> my-lib io/resource io/input-stream (io/copy my-temp-file))
- 更新
java.library.path
在运行时的系统属性中添加临时文件夹,使用System/setProperty
- 最后,使用这个反射技巧 http://fahdshariff.blogspot.fr/2011/08/changing-java-library-path-at-runtime.html强制更新库路径
设置起来很痛苦,但设置之后效果很好。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)