2012-02-10 2 views
13

J'ai actuellement un petit programme en Common Lisp, que je veux lancer en script shell. J'utilise le SBCL et parfaitement bien avec cela, donc je préfère rester sur cette plate-forme. :)Comment utiliser quicklisp lorsque le programme CL est appelé comme script shell?

Je suis conscient de l'option --script et il fonctionne parfaitement, sauf pour (ql:quickload) forme.

Mon programme utilise le CL-FAD, qui charge par ql:quickload (je pense que je devrais mentionner que c'est la fonction de chargement de paquet de quicklisp). Lorsque script est exécuté jusqu'à l'évaluation de la

(ql:quickload :cl-fad) 
forme

, il rompt avec l'erreur suivante:

package "QL" not found 

programme est emballé dans le fichier source, qui suit en-tête:

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

C'est un simple exécutable d'automatisation, j'ai donc décidé (peut-être à tort) de ne pas écrire de système ASDF. Il exporte une seule fonction qui doit être exécutée sans aucun argument.

Pour ce programme, je suis en train d'essayer d'écrire le script de lancement, ce qui est ce que je suis les yeux fixés à:

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

Ces trois lignes (sans compter le tralala) est ce que je veux automatiser. Comme je l'ai lu dans la documentation, script avec ce shebang peut être appelé comme ./script.lisp simple, et il le fait vraiment ... avec l'erreur décrite auparavant.

Qu'est-ce que j'ai besoin d'ajouter dans le lanceur pour :cl-fad pour charger correctement? Documentation indique que avec l'option --script SBCL ne charge aucun fichier init, alors dois-je vraiment besoin de copypaste les lignes

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

(qui ql:add-to-init-file ajoute à .sbclrc), à mon script de lancement? Peut-être que j'ai un défaut architectural profond dans la configuration de mon programme?

Et oui, quand j'entre les lignes que j'essaie d'automatiser dans REPL dans le sbcl lui-même, le programme fonctionne comme prévu.

Répondre

7

La création d'une version dédiée de l'image principale est une bonne option. Vous pouvez:

  1. charge quicklisp et sb-ext:save-lisp-and-die dans une nouvelle image.Vous écrivez un script shell/chauve-souris nommée, dites qlsbcl, comme ceci:

    sbcl --core <my-new-image-full-path-location> "[email protected]" 
    
  2. grab clbuild2 à http://gitorious.org/clbuild2 et exécutez clbuild lisp. Vous devrez symlink clbuild vers un répertoire binaire dans votre chemin et modifier quelques scripts un peu si votre quicklisp n'est pas à l'endroit commun ~/quicklisp (https://gist.github.com/1485836) ou si vous utilisez ASDF2 (https://gist.github.com/1621825). En faisant cela, clbuild créer un nouveau noyau avec quicklisp, ASDF et tout ce que vous pouvez ajouter dans conf.lisp. Maintenant, le tralala peut ressembler à ceci:

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

L'avantage de clbuild est que vous pouvez facilement créer et gérer de base et l'installation quicklisp de shell pour sbcl (par défaut) ou tout autre CL moderne comme ccl64 mise en œuvre . Le mélange des deux techniques (script et clbuild) résoudra votre problème.

+0

J'ai quicklisp dans le répertoire différent et je ne veux pas _yet_ pour pirater les scripts des autres. :) Coredumping par première méthode a bien fonctionné, j'ai déjà beaucoup de lanceurs dans mon '~/bin'. Et l'image jetée tourne vite aussi. %) – hijarian

+0

Oui! Travailler avec des images est génial! C'est pourquoi les Smalltalkers commencent leur travail au quotidien avec le sourire et les développeurs de Java Eclipse commencent leur propre café. –

14

Vous faites tout ce qu'il vous faut.

Fondamentalement, avant de pouvoir utiliser quicklisp, vous devez le charger (actuellement, il n'est pas livré avec SBCL, bien qu'il puisse changer à l'avenir). Il y a plusieurs façons de le faire. Par exemple, vous pouvez charger votre .sbclrc avec l'init quicklisp:

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

ou tout simplement coller ces lignes dans votre script, comme vous l'avez suggéré.

+2

Wow, "tu fais tout ce qu'il faut" ... ces mots sont vraiment rares, merci, @Vsevolod. Les vôtres et les réponses de Martial sont géniales et fonctionnelles, je me sentais désolé que l'on ne puisse marquer qu'une seule réponse. :) Je préfère le coredumping cependant, cela me sauve une ligne dans chaque scénario avec peu de frais généraux de préparations en forme de tout symplanger ensemble. – hijarian

+2

@hijarian pas de problème. Comme je l'ai dit. Il existe de nombreuses façons de résoudre votre problème. J'espère voir encore plus de réponses :) –

Questions connexes