虽然这可能看似主观,但有一个具体的例子,我希望帮助解决。这与Overtone Clojure库https://github.com/overtone/overtone/issues/274的问题有关,似乎应该有一个" Best Practice"对于Leiningen并适用于比Overtone更多的库。
Overtone是一个clojure库,可以在其他项目中使用。 Overtone需要本机库才能工作,因此它在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"]
。{1}}仅返回当前本机路径,而使用Overtone的项目无法传递到任何本地库的路径。
所以,问题是 - 依赖项目如何将本地本地库与Overtone混合? Overtone或依赖项目是否应调整其project.clj设置?怎么样?
答案 0 :(得分:3)
我不知道" best",但这是一个现在至少在四个项目中成功运作的实践,其中三个是"真实" ,商业的。虽然我只开源a specific case for ZeroMQ,但我相信这些原则是通用的,适用于任何本地库。大多数代码也可以轻松地重用,并且它在Eclipse下获得许可,因此如果您愿意,可以随意使用它。我还没有对包含本机的库的更通用版本的需求,但我相信它很容易被提取出来。
我对标准解决方案(lein' s:native-path,JVM args等)的问题是,我想要一个便携式解决方案,用于uberjar发布,不需要用户安装任何东西其他,所以请说明如下"下载uberjar,从你的软件包管理器安装libzmq-dev,然后启动uberjar"不可能。
原理非常简单:我将所有支持的平台中的本机库捆绑在库jar中。那样:
我也不依赖于任何操作系统链接策略,因为我发现很难让它们可靠地工作。所以我做的是我包含了所有必需的本机库,这些库不能保证在jar中运行的系统上,然后在运行时,库中包含:
这种方法当然有缺点:
答案 1 :(得分:2)
我通过Clojars发布了clj-nativedep,可以帮助解决这个问题。该库提供了快速识别当前系统体系结构的规范化名称的功能,并且可以将任何选定的资源(在jar或类路径中)加载到运行时环境中。
请参阅:https://github.com/rritoch/clj-nativedep
这个系统专门用于我的WarpCTL项目,该项目利用swig生成的大量本机代码。由于处理Clojure类加载的方式,需要通过静态类构造函数加载本机依赖项,您可以在https://github.com/rritoch/WarpCTL/blob/master/extra/JADL-SDK/build/java/src/com/vnetpublishing/swig/adl/jadl_sdk.java#L13看到一个示例。对于该项目,我将java代码构建到JAR中,并添加clj-nativedep和jar作为依赖项。应该可以从纯clojure应用程序加载资源,但为了获得最佳性能,需要从静态类构造函数加载。
答案 2 :(得分:0)
我曾经遇到过这个问题,所以我创建了一个非正统的lein插件,只需一次性解决这个问题就可以添加几行project.clj
:https://bitbucket.org/noncom/nativot
警告:Clojure方式非常不受欢迎,因为它打破了所有可重复性和内容的概念,允许您将任意jar,资源和其他文件打包到生成的jar中,并使其正常工作。