2014-01-29 14 views
21

雖然這可能看起來很主觀,但有一個具體的例子,我想幫助解決。這與Overtone Clojure圖書館https://github.com/overtone/overtone/issues/274存在一個問題有關,Leiningen似乎應該有一個「最佳實踐」,並且應用於更多的圖書館而不僅僅是Overtone。使用本機庫的clojure庫的「最佳實踐」?

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"]在project.clj (System/getProperty "java.library.path")之後只返回當前的本地路徑和使用Overtone的項目不能傳遞到任何本地庫的路徑。

所以,問題是 - 從屬項目如何與Overtone混合使用本地本地庫? Overtone或從屬項目是否應該調整其project.clj設置?怎麼樣?

+0

你有沒有嘗試設置:你自己的project.clj中的native-path?它看起來像lein會將它與依賴的本機路徑結合起來。 – Alex

+0

有趣......初始測試看起來很積極,但是java.library.path只報告我的新路徑,而不是Overtone的路徑。經過更多結帳後會迴圈,謝謝! –

+0

不......不知道爲什麼它可能最初工作,但與:本地路徑「leaplib」和「leaplib/macosx/x86_64」中的庫它無法找到泛音scsynth庫。設置:原生路徑似乎覆蓋,不加入。 –

回答

2

我通過Clojars發佈了clj-nativedep,可以幫助解決這個問題。該庫提供了快速識別當前系統架構的規範化名稱的能力,並且可以將任何選定資源(在jar或classpath中)加載到運行時環境中。

參見:https://github.com/rritoch/clj-nativedep

這個系統,它利用與痛飲生成的本地代碼很大我WarpCTL項目是專門製造。由於如何處理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應用程序以這種方式加載資源,但是需要從靜態類構造函數中加載所需的最佳性能。

3

我不知道「最好」,但是這裏有一個實踐,至少在四個項目中已經成功地爲我工作,其中三個是「真正的」商業項目。雖然我只開源a specific case for ZeroMQ,但我相信這些原則是通用的,並且適用於任何本地庫。大部分代碼也可以輕鬆地重用,並且在Eclipse中獲得許可,所以如果您願意,可以隨意使用它。我沒有需要一個更通用的本地包含庫的版本,但我相信它可以很容易地被提取出來。

我曾與標準解決方案的問題(雷音的:本地路徑,JVM ARGS等)是我想爲uberjar分佈的便攜式解決方案,不需要用戶安裝任何東西,所以說明例如「下載uberjar,從你的軟件包管理器安裝libzmq-dev,然後啓動uberjar」是不可能的。

原理非常簡單:我將所有受支持平臺上的本機庫捆綁到庫jar中。那樣:

  • 我作爲圖書館作者,具體控制使用哪些版本。那裏沒有驚喜。
  • 從另一個項目中包含庫可以完全不需要知道該庫依賴於本機庫。
  • 同樣,uberjar發佈,無論是來自leiningen還是maven,都能無縫工作。

我不依賴任何OS鏈接策略,因爲我發現很難使它們可靠地工作。因此,我所做的是,我包括所有不保證是目前罐子內運行的系統上,然後在運行時庫所需的本地庫:

  • 動態發現什麼平臺它正在運行;
  • 將本機庫從其自己的存檔提取到特定於系統的臨時目錄(如果它尚未存在)(基於SHA;這是避免在未正確清理臨時目錄的平臺上累積的必要步驟 - 即,Windows);
  • 「手動」以正確的順序加載本機依賴關係,因此動態鏈接不會嘗試解析主機操作系統路徑上的庫。

當然也有缺點,以這種方法:

  • 作爲單個工件生成過程中涉及三個不同的操作系統(我支持Linux,Windows和OSX)和2個體繫結構(i386 & x86_64的) ,構建過程很難自動化並需要訪問相關機器;
  • 由於本地庫的特定版本已捆綁,庫用戶無法更新它們;在安全敏感的環境中,這可能是不可接受的;
  • 作爲這個庫的用戶,您必須相信我捆綁的本地庫確實是我聲稱的,並且確實已經通過我在源代碼中描述的過程進行構建,而不會再有任何篡改;
  • 因爲我幾乎不知道鏈接動態庫,所以這種方法可能還有其他問題,儘管他們還沒有咬我。
0

我也有這個問題一次,所以我做了一個非正統的雷音插件,解決了這一點一勞永逸了幾行添加到您的project.cljhttps://bitbucket.org/noncom/nativot

警告:這是非常不受歡迎Clojure的方式,因爲它打破了重複性和東西的所有概念,允許您將任意的jar,資源和其他文件打包到您的結果jar中,並使其工作。