2012-05-25 47 views
31

什麼是整合與本地庫各種SBT任務(例如一個很好的方式,那些來自JOGLLWGL,或者JCuda?具體來說,集成原生系統庫與SBT

  1. 有沒有推薦的方法包括在run任務本機庫的SBT郵件列表上的討論表明,這些可能性:

    最後一個優點是run不需要分叉,但缺點是配置必須在SBT之外完成。

  2. 我可以自動將本機庫包含在由sbteclipse插件生成的Eclipse項目中嗎?有可能rewrite the .project file in a post-processing step.有沒有例子代碼?有沒有更好的辦法?

  3. 本機庫是否可以包含在由插件生成的可運行Jar中,如sbt-assembly,sbt-onejarsbt-proguard

我假設本地庫沒有直接的SBT設置。如果類似的東西存在,上述任務是否可以透明地處理本地庫?

回答

28

從研究,我已經在過去做了,只有兩種方法可以加載本地庫:修改java.library.path和使用System.loadLibrary(我覺得大多數人都這樣做),或使用System.load絕對路徑。

正如你所暗指的,與java.library.path混淆在配置SBT和Eclipse方面可能令人討厭,我認爲它不可能爲一個可執行jar自動執行。

讓葉子System.load。在編寫自己的本機庫而言,你可以做的是:

  • 創建編譯你的本地源(與javahgcc)的SBT的任務,需要.so文件,它依賴任何.so文件所產生的on,將它們放入目標目錄中的jar(作爲資源),然後將路徑添加到該jar到unmanagedJars in Compile
  • 創建一個Scala方法來加載庫。它不會調用System.loadLibrary,它將使用Class.getResourceAsStream來讀取庫,File.createTempFile將其寫入文件系統的某處,然後使用System.load將其加載到JVM中。
  • 現在,不要像以前那樣致電System.loadLibrary,請致電MyClasspathJniLoader.loadLibrary

將與SBT運行,Eclipse和可執行罐子工作,而無需任何額外的配置(雖然我不知道怎麼proguard的知道哪些資源,包括)。

現在爲那些已經被寫入第三方本地庫,他們中的一些像jblas已經使用了這塊「肥肉罐子」的做法。如果他們希望你能設置java.library.path,然後他們叫System.loadLibrary時,他們覺得喜歡它,你需要做一些魔術,使這項工作。

我沒有試過,但這種方法可能會奏效:

  • 使用類似的SBT任務,把所有的本地路徑上的圖書館,裝入瓶內的資源,並把那個罐子上clsaspath。
  • 創建Scala的方法,它的功能和庫的名稱列表,創建一個臨時目錄,讀取JAR的資源這些庫到文件的臨時目錄,增加了臨時目錄中java.library.path,調用函數傳遞,最後將java.library.path恢復到之前的狀態。
  • 你打電話到本地庫(當它想必靜態初始化,使System.loadLibrary調用),包裹在你的法庫,它會加載列表中的特定第一時間致電。這樣,當它調用System.loadLibrary時,它的所有庫都將在java.library.path上,並且會成功加載。

顯然,這是惱人的,因爲你必須在使用之前,需要手動初始化第三方庫,但它似乎更可行的包裝所有的初始化點(你的主要功能和測試初始化​​),比它讓所有的您的工具正確設置java.library.path。如果你已經在第三方庫上面有自己的抽象層,那麼它可能比這更容易,所以實際上只有一個初始化點需要包裝。

如果這似乎是一個現實的解決方案,我可以當你困惑添加關於SBT任務或斯卡拉包裝方法的詳細信息。

0

在OSX中,如果你有在sbt test問題加載本地庫中/lib/*.jnilib

[error] java.lang.UnsatisfiedLinkError: Fatal execution error, caused by no jniortools in java.library.path

你可以用它代替System.loadLibrary("jniortools")下面的代碼。

new File("lib").listFiles().map(_.getAbsolutePath).filter(_.endsWith("jniortools.jnilib")).foreach(System.load) 
0

有一個簡單的方法。

假設存儲在lib_extra目錄

  1. 添加到JNA libraryDependencies本地庫:

    libraryDependencies ++ = SEQ( 「net.java.dev.jna」 %「 JNA平臺」% 「4.1.0」)

  2. 添加這些代碼來構建。SBT:

    unmanagedResourceDirectories在編譯+ = baseDirectory.value/「lib_extra」

    includeFilter在(編譯,unmanagedResourceDirectories):= 「.DLL,。所以」