Подтвердить что ты не робот

Интеграция собственных системных библиотек с SBT

Что такое хороший способ интегрировать различные задачи SBT с родными библиотеками (например, из JOGL, LWGL или JCuda В частности,

Я предполагаю, что нет прямых настроек SBT для родных библиотек. Если бы что-то подобное существовало, могли ли указанные выше задачи обрабатывать собственные библиотеки прозрачно?

4b9b3361

Ответ 1

Из исследования, которое я делал в прошлом, есть только два способа загрузки загруженных загружаемых библиотек: изменение java.library.path и использование System.loadLibrary (я чувствую, как это делают большинство людей) или используя System.load с абсолютный путь.

Как вы уже упоминали, возиться с java.library.path может раздражать с точки зрения настройки SBT и Eclipse, и я не думаю, что это можно сделать автоматически для исполняемого банку.

Итак, это оставляет System.load. Что касается написания собственных собственных библиотек, то вы можете сделать следующее:

  • Создайте задачу SBT, которая компилирует ваши собственные источники (с javah и gcc), берет полученные .so файлы и любые файлы .so, от которых она зависит, помещает их в банку (как ресурсы) в целевой и добавляет путь к банке в unmanagedJars in Compile.
  • Создайте метод Scala для загрузки библиотеки. Вместо вызова System.loadLibrary он будет использовать Class.getResourceAsStream для чтения библиотеки, File.createTempFile, чтобы записать ее где-нибудь в файловой системе, и System.load, чтобы загрузить ее в JVM.
  • Теперь вместо вызова System.loadLibrary, как и раньше, вызовите MyClasspathJniLoader.loadLibrary.

Это будет работать с SBT run, Eclipse и исполняемыми банками без дополнительной настройки (хотя я не знаю, как proguard знает, какие ресурсы включать).

Теперь, когда уже записаны собственные библиотеки сторонних разработчиков, некоторые из них, такие как jblas, уже используют этот подход с "жирной флягой". Если они ожидают, что вы настроите java.library.path, а затем они вызовут System.loadLibrary, когда они захотят, вам нужно будет сделать магию, чтобы сделать эту работу.

Я не пробовал это, но это решение может работать:

  • Используйте аналогичную задачу SBT, чтобы поместить все библиотеки на свой собственный путь в банку в качестве ресурсов и поместить эту банку в clsaspath.
  • Создайте метод Scala, который принимает функцию и список имен библиотек, создает каталог temp, читает эти библиотеки из ресурсов jar в файлы в каталоге temp, добавляет каталог temp в java.library.path, вызывает передается в функции и, наконец, возвращает java.library.path назад к тому, что было раньше.
  • При первом вызове в родную библиотеку (когда она, по-видимому, будет статически инициализироваться и вызовет System.loadLibrary), оберните этот конкретный вызов в свой метод со списком библиотек, которые он будет загружать. Таким образом, когда он вызывает System.loadLibrary, все его библиотеки будут на java.library.path и будут загружены успешно.

Очевидно, это раздражает, поскольку перед его использованием необходимо вручную инициализировать библиотеку сторонних разработчиков, но представляется более целесообразным обернуть все точки инициализации (ваши основные функции и инициализации теста), чем это сделать, чтобы получить все ваши инструменты для правильной установки java.library.path. И это может быть даже проще, если вы уже имеете свой собственный слой абстракции над третьей стороной, поэтому на самом деле вам нужно только один пункт инициализации.

Если это похоже на реалистичное решение, я могу добавить дополнительные сведения о задаче SBT или методах оболочки Scala, если вы запутались.

Ответ 2

В Osx, если у вас есть проблемы с загрузкой собственных libs в /lib/*.jnilib во время sbt test.

[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)

Ответ 3

Существует простой способ.

Предположим, что собственные библиотеки, хранящиеся в каталоге lib_extra

  • добавить jna в libraryDependencies:

    libraryDependencies ++ = Seq ( "net.java.dev.jna" % "jna-platform" % "4.1.0" )

  • добавьте этот код в build.sbt:

    unmanagedResourceDirectories в компиляции + = baseDirectory.value/ "lib_extra"

    includeFilter in (Compile, unmanagedResourceDirectories): = ".dll,.so"