尽管这可能看起来很主观,但有一个具体的例子需要解决。这与Overtone Clojure库https://github.com/overtone/overtone/issues/274的问题有关,该问题似乎应该为Leiningen提供“最佳实践”,并且不仅仅适用于Overtone,还应应用于更多库。

Overtone是一个Clojure库,可以在其他项目中使用。泛音要求本机库起作用,因此它在project.clj https://github.com/overtone/overtone/blob/master/project.clj#L69中使用:native-path "native",以便为所使用的本机scsynth库[overtone/scsynth "3.5.7.0"]获取正确的路径。

但是,我相信这会重置依赖于Overtone库的项目的传入路径。请参阅问题的背景知识,但是基本上取决于项目中的[overtone "0.9.1"]。clj(System/getProperty "java.library.path")仅返回当前的本机路径,并且使用Overtone的项目无法将路径传递到任何本地库。

因此,问题是-从属项目如何将本地本机库与Overtone混合?泛音或从属项目是否应该调整其project.clj设置?怎么样?

最佳答案

我对“最佳”一无所知,但这是一种成功的实践,现在至少在四个项目中对我有效,其中三个是“真实的”商业项目。尽管我仅开源了a specific case for ZeroMQ,但我相信这些原则是通用的,适用于任何本机库。大多数代码也很容易重用,并且它是在Eclipse下获得许可的,因此,如果需要,可以随时使用。我不需要本机(包括库)的通用版本,但我相信可以轻松提取它。

我在标准解决方案(如莱因的:native-path,JVM args等)中遇到的问题是,我想要一个适用于uberjar发行版的便携式解决方案,该解决方案不需要用户安装其他,因此请参见“下载uberjar,从软件包管理器安装libzmq-dev,然后启动uberjar”。

原理很简单:对于所有受支持的平台,我都将本机库 bundle 在库jar中。那样:

  • I,作为库作者,专门控制使用哪个版本。没有惊喜。
  • 可以在不知道该库依赖于本机库的情况下,将另一个项目中的库包括在内。
  • 同样,无论是leiningen还是maven的uberjar发行版都可以无缝工作。

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

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

    10-12 23:57