我正在编写一个涉及本机代码的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
错误。
答案 0 :(得分:4)
答案取决于您的确切用例。在最简单的情况下,您需要:
native/
文件夹包含在:resource-paths
的{{1}}中。project.clj
选项以指示库jar中的路径,应从中提取本机库。例如,如果您的库在根文件夹中包含资源“mylib.so”,则可以这样指定::native-prefix
[com.foo/bar "1.0.1" :native-prefix ""]
中的:native-path
选项指定提取的目标应该去的位置。project.clj
将您指定的:native-path
添加到java.library.path
。这些选项记录在sample leiningen project.clj。
中现在我说它取决于你的用例的原因是,如果你想创建一个包含本机库的uberjar,事情开始变得更加混乱。主要原因是你无法直接链接到jar中压缩的lib。如果您很幸运,您将能够使用NativeUtils课程中的:jvm-opts
方法。但是,我记得有loadLibraryFromJar
个相关问题导致我无法使用ClassLoader
。相反,我必须确保库存在于JVM查找的其中一个路径中,以便System/load
正确找到它。这是我最终做的事情:
System/loadLibrary
(-> my-lib io/resource io/input-stream (io/copy my-temp-file))
java.library.path
系统属性以向其添加临时文件夹
设置很痛苦,但之后效果很好。