Как использовать quicklisp, когда программа CL вызывается как сценарий оболочки? - PullRequest
13 голосов
/ 10 февраля 2012

В настоящее время у меня есть небольшая программа на Common Lisp, которую я хочу запустить как скрипт оболочки. Я использую SBCL и прекрасно с этим справляюсь, поэтому предпочитаю оставаться на этой платформе. :)

Мне известно о параметре --script, и он работает безупречно, за исключением формы (ql:quickload).

Моя программа использует CL-FAD , который загружается через ql:quickload (думаю, я должен упомянуть, что это функция загрузки пакетов из quicklisp ). Когда скрипт запускается до оценки

(ql:quickload :cl-fad)

форма, она ломается со следующей ошибкой:

package "QL" not found

Программа упакована в один исходный файл, который имеет следующий заголовок:

(defpackage :my-package
  (:use :common-lisp)
  (:export :my-main-method))

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

Для этой программы я сейчас пытаюсь написать скрипт запуска, и вот на что я смотрю:

#!/usr/bin/sbcl --script
(load "my-program.lisp")
(in-package :my-package)
(my-main-method)

Эти три строки (не считая шебанга) - это то, что я хочу автоматизировать. Как я читал в документации, скрипт с этим shebang можно назвать простым ./script.lisp, и он действительно делает это ... с ошибкой, описанной ранее.

Что мне нужно добавить в лаунчер для :cl-fad для правильной загрузки? Документация утверждает, что с опцией --script SBCL не загружает никакой файл инициализации, поэтому мне действительно нужно скопировать и вставить строки

#-quicklisp
(let ((quicklisp-init (merge-pathnames "systems/quicklisp/setup.lisp"
                                       (user-homedir-pathname))))
  (when (probe-file quicklisp-init)
    (load quicklisp-init)))

(который ql:add-to-init-file добавляет к .sbclrc), в мой скрипт запуска? Может быть, у меня есть глубокий архитектурный недостаток в настройке моей программы?

И да, когда я ввожу строки, которые я пытаюсь автоматизировать в REPL в самом sbcl, программа запускается, как и ожидалось.

Ответы [ 2 ]

15 голосов
/ 10 февраля 2012

Вы все делаете правильно.

Как правило, прежде чем вы сможете использовать quicklisp, вам нужно загрузить его (в настоящее время он не связан с SBCL, хотя в будущем он может измениться). Есть разные способы сделать это. Например, вы можете загрузить свой .sbclrc с помощью initlisp init:

#!/usr/bin/sbcl --script
(load ".sbclrc")
(load "my-program.lisp")
(in-package :my-package)
(my-main-method)

или просто вставьте эти строки в ваш скрипт, как вы предложили.

7 голосов
/ 11 февраля 2012

Хорошим вариантом является создание выделенной версии образа ядра.Вы можете:

  1. загрузить quicklisp и sb-ext:save-lisp-and-die в новом изображении.Вы пишете сценарий оболочки / летучей мыши с именем, скажем qlsbcl, например:

    sbcl --core <my-new-image-full-path-location> "$@"
    
  2. захват clbuild2 в http://gitorious.org/clbuild2 и запускаете clbuild lisp.Вам придется использовать символическую ссылку clbuild в двоичную директорию вашего пути и немного подправить некоторые скрипты, если ваш quicklisp находится не в общем месте ~ / quicklisp (https://gist.github.com/1485836) или если выиспользуйте ASDF2 (https://gist.github.com/1621825). Таким образом, clbuild создайте новое ядро ​​с quicklisp, ASDF и всем, что вы можете добавить в conf.lisp . Теперь шебанг можетвыглядят так:

    #!/usr/bin/env sbcl --noinform --core <my-clbuild-install-directory>/sbcl-base.core --script
    

Преимущество clbuild в том, что вы можете легко создавать и управлять установкой ядра и quicklisp из оболочки для sbcl (по умолчанию) или любой другойсовременный CL, такой как ccl64 реализация. Смешивание двух техник (скрипт и clbuild) решит вашу проблему.

...