Как вывести исполняемый образ SBCL, который использует osicat - PullRequest
3 голосов
/ 15 марта 2019

У меня есть простая общая программа на сервере lisp, которая использует библиотеку osicat для взаимодействия с файловой системой posix. Мне нужно сделать это, потому что система создает символические ссылки на файлы и использует метаданные POSIX stat, и ни одна из этих вещей не является простой в переносимом lisp.

Я управляю зависимостями с помощью quicklisp, и все это прикреплено к рабочему дистрибутиву. Приложение переносимо между CCL и SBCL, и я стараюсь встраивать его в первое и развертывать его, используя второе. Я объявляю зависимости для приложения в формате asdf defsystem, и я могу использовать quicklisp, чтобы загрузить его для легкой разработки из локальных проектов.

Для развертывания я просто использовал несколько доступных сборников, которые реплицировали среду разработчика на удаленном компьютере (например, настраивали quicklisp, вставляли код в локальные проекты, заканчивались из домашнего каталога пользователя), что было хакерским, но в основном нормальным. Позже, когда он стал более стабильным, я компилировал его, используя sb-ext:save-lisp-and-die, используя простой скрипт компиляции. Это означает, что я получаю исполняемый файл, который я могу больше запускать как сервер, со скриптами управления сервисами и анонимной учетной записью пользователя.

Это работает очень хорошо, поэтому недавно я переместил этот шаг на следующий уровень, и я собираю пакеты .deb с помощью своего скрипта компиляции, чтобы я мог собрать все в перемещаемый двоичный файл. Это тоже вроде работает, но результирующие двоичные файлы нельзя перемещать с исходного узла сборки. Они отказываются запускаться, и кажется, что они пытаются динамически загрузить общую библиотеку для osicat

Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
Mar 15 12:47:14 annie [479]:                                     {10005C05B3}>:
Mar 15 12:47:14 annie [479]:   Error opening shared object "libosicat.so":
Mar 15 12:47:14 annie [479]:   libosicat.so: cannot open shared object file: No such file or directory.

Похоже, что изображение ожидает найти это в архивах QuickLisp исходного дерева сборки

(ERROR "Error opening ~:[runtime~;shared object ~:*~S~]:~%  ~A." "/home/builder/buil...quicklisp/dists/quicklisp/software/osicat-20180228-git/posix/libosicat.so
(SB-SYS:DLOPEN-OR-LOSE #S(SB-ALIEN::SHARED-OBJECT :PATHNAME #P"

, так что копаясь в источнике, я понимаю, что когда quicklisp выбирает osicat и выполняет его операцию сборки, он компилирует эту DLL-библиотеку, чтобы обернуть ее интерфейс с системными библиотеками, а не просто напрямую обращаться к ним - возможно, потому что он использует cffi groveller, Я не очень много знаю о CFFI (пока). Это нормально, но вместо того, чтобы ссылаться на .so с помощью системного компоновщика, он пытается dlopen получить его по фиксированному пути, который не очень переносим, ​​и отчасти нарушает полезность save-image

В данный момент я немного озадачен, но прежде чем я углублюсь в QL и сборку cffi, я подумал, есть ли какая-то конфигурация сборки или компиляции, которую я пропускаю, что заставило бы ее загрузиться в более «статичном» состоянии. 'мода или влияние на производство упакованной библиотеки. В идеале мне нужен только один большой двоичный объект, который я могу обернуть в установщик и связать его с системными библиотеками, но если мне нужно развернуть некоторые дополнительные артефакты, это, вероятно, хорошо. Я не знаю, как заставить автоматически сгенерированные общие объекты появляться по более контролируемому пути.

Однако в этот момент я могу также написать .so для своих вызовов posix и распространить его вместе с приложением, а также попробовать и FFI к нему напрямую. Это было бы немного больно, поэтому я бы предпочел не делать этого.

1 Ответ

2 голосов
/ 15 марта 2019

Возможно, вы вместо этого можете использовать sb-posix:symlink и sb-posix:fstat в SBCL, удаляя зависимость от osicat с помощью переключателя функций.

...