clojure - "Best Practice"用于使用 native 库的 clojure 库?

标签 clojure leiningen

虽然这可能看起来很主观,但我想帮助解决一个具体的例子。这与 Overtone Clojure 库的问题有关 https://github.com/overtone/overtone/issues/274似乎 Leiningen 应该有一个“最佳实践”,并适用于更多的图书馆,而不仅仅是 Overtone。

Overtone 是一个 clojure 库,可以在其他项目中使用。 Overtone 需要本地库才能工作,因此它使用 :native-path "native"在 project.clj https://github.com/overtone/overtone/blob/master/project.clj#L69为了获得本地 scsynth 库的正确路径 [overtone/scsynth "3.5.7.0"]使用的。

但是,我相信这会重置依赖于 Overtone 库的项目的传入路径。查看一些背景的问题,但基本上取决于 [overtone "0.9.1"]在项目中.clj (System/getProperty "java.library.path")只返回当前的本地路径,使用 Overtone 的项目不能传入任何本地库的路径。

所以,问题是——依赖项目如何将本地原生库与 Overtone 混合? Overtone 或依赖项目是否应该调整其 project.clj 设置?如何?

最佳答案

我不知道“最佳”是什么,但现在至少有四个项目对我来说是一种成功的做法,其中三个是“真正的”商业项目。虽然我只开源了 a specific case for ZeroMQ ,我相信这些原则是通用的,应该适用于任何 native 库。大多数代码也可以很容易地重用,并且它是在 Eclipse 下获得许可的,所以如果你愿意,可以随意使用。我不需要更通用的包含 native 库的版本,但我相信它可以很容易地提取出来。

我对标准解决方案(lein 的 :native-path、JVM args 等)的问题是我想要一个用于 uberjar 分发的可移植解决方案 不需要用户安装任何其他东西 ,因此诸如“下载 uberjar,从包管理器安装 libzmq-dev,然后启动 uberjar”之类的指令是不可能的。

原理很简单:我将本地库捆绑在库 jar 中,适用于所有支持的平台。那样:

  • 我作为库作者,具体控制使用哪些版本。那里没有惊喜。
  • 可以在不知道该库依赖于 native 库的情况下从另一个项目中包含该库。
  • 同样,无论是来自 leiningen 还是 maven 的 uberjar 分发,都可以无缝运行。

  • 我也不依赖任何操作系统链接策略,因为我发现很难让它们可靠地工作。所以我所做的是我包含了所有必需的 native 库,这些 native 库不能保证在 ja​​r 中的运行系统上存在,然后在运行时包含该库:
  • 动态找出它正在运行的平台;
  • 如果本地库尚不存在,则从其自己的存档中将 native 库提取到系统特定的临时目录中(基于 SHA;这是避免在未正确清理其临时目录的平台(即 Windows)上积累所必需的) ;
  • “手动”以正确的顺序加载 native 依赖项,​​因此动态链接不会尝试解析主机操作系统路径上的库。

  • 当然,这种方法也有缺点:
  • 由于单个工件的构建过程涉及三种不同的操作系统(我支持 Linux、Windows 和 OSX)和 2 种架构(i386 和 x86_64),构建过程很难自动化并且需要访问相关机器;
  • 由于捆绑了特定版本的原生库,库用户无法更新它们;在安全敏感的环境中,这可能是 Not Acceptable ;
  • 作为这个库的用户,您必须相信我,捆绑的原生库确实是我声称的那样,并且确实是通过我在源代码中描述的过程构建的,没有任何篡改;
  • 由于我对链接动态库几乎一无所知,这种方法可能还有其他问题,尽管他们还没有咬我。
  • 关于clojure - "Best Practice"用于使用 native 库的 clojure 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21436744/

    相关文章:

    Clojure 在 hiccup 和 noir 中使用 (for)

    postgresql - Clojure/JDBC/Postgresql : I am trying to update a timestamp value in postgresql from a string, 出现错误

    ssl - leiningen:如何关闭 ssl 验证?

    java - emacs 和 Clojure 编译错误

    clojure - 在莱宁根哪里可以找到依赖项的有效版本号

    clojure - Clojure 循环数据结构必须涉及像 ref 这样的结构吗?

    matlab - 将多维元胞数组的生成从 Matlab 转换为 Clojure 的最佳方法是什么

    java - Clojure 列出 uberjar 资源中的子文件夹

    clojure - Leiningen 和 Clojure 依赖项

    windows - Lein.bat 无法在 windows xp 中启动 repl