2012-02-10 9 views
13

Attualmente ho un piccolo programma in Common Lisp, che voglio eseguire come script di shell. Sto usando il SBCL e perfettamente bene con questo quindi preferirò rimanere su questa piattaforma. :)Come utilizzare quicklisp quando il programma CL viene richiamato come script di shell?

Sono a conoscenza dell'opzione --script e funziona perfettamente ad eccezione del modulo (ql:quickload).

Il mio programma utilizza lo CL-FAD, che viene caricato tramite ql:quickload (penso che dovrei menzionare che si tratta della funzione di caricamento pacchetti da quicklisp). Quando script viene eseguito fino a valutare la forma

(ql:quickload :cl-fad) 

, si rompe con l'errore successivo:

package "QL" not found 

programma è confezionato nel singolo file sorgente, che ha seguente intestazione:

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

È un semplice eseguibile di automazione, quindi ho deciso (forse erroneamente) di non scrivere alcun sistema ASDF. Esporta la singola funzione che dovrebbe essere eseguita senza argomenti.

Per questo programma Attualmente sto cercando di scrivere la sceneggiatura launcher, e questo è quello che sto fissando:

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

Queste tre linee (senza contare la baracca) è quello che sto voglio automatizzare. Come ho letto nella documentazione, lo script con questo shebang può essere chiamato come semplice ./script.lisp, e lo fa davvero ... con l'errore descritto in precedenza.

Cosa devo aggiungere nel launcher per :cl-fad da caricare correttamente? La documentazione afferma che con l'opzione --script SBCL non viene caricato un file di inizializzazione, quindi ho davvero bisogno di CopyPaste le linee

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

(che ql:add-to-init-file aggiunge alla .sbclrc), per il mio script launcher? Forse ho qualche difetto architettonico profondo nella configurazione del mio programma?

E sì, quando inserisco le righe che tento di automatizzare in REPL nello stesso sbcl, il programma viene eseguito come previsto.

risposta

7

Creazione di una versione dedicata di immagine core è una buona opzione. Si può:

  1. carico quicklisp e sb-ext:save-lisp-and-die in una nuova immagine.Si scrive uno script di shell/bat nome, dite qlsbcl, in questo modo:

    sbcl --core <my-new-image-full-path-location> "[email protected]" 
    
  2. afferrare clbuild2 a http://gitorious.org/clbuild2 ed eseguire clbuild lisp. Dovrai collegare sympath a una directory binaria nel tuo percorso e modificare leggermente alcuni script se il tuo quicklisp non si trova nel posto comune ~/quicklisp (https://gist.github.com/1485836) o se si utilizza ASDF2 (https://gist.github.com/1621825). In tal modo, clbuild crea un nuovo core con quicklisp, ASDF e qualsiasi cosa tu possa aggiungere in conf.lisp. Ora la faccenda può sembrare in questo modo:

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

Il vantaggio di clbuild è che si può facilmente creare e gestire core e installazione quicklisp da shell per sbcl (per impostazione predefinita) o qualsiasi altro CL moderno come ccl64 implementazione . Mescolando le due tecniche (script e clbuild) risolverà il tuo problema.

+0

Ho quicklisp nella directory diversa e non voglio _yet_ per hackerare gli script di altri. :) Coredumping con il primo metodo ha funzionato benissimo, ho già molti launcher nel mio ~ ~/bin'. Anche l'immagine scaricata scorre incredibilmente veloce. %) – hijarian

+0

Sì! Lavorare con le immagini è fantastico! Ecco perché Smalltalker inizia il suo lavoro quotidiano con un sorriso e gli sviluppatori di Java Eclipse iniziano il loro con il caffè. –

14

Stai facendo tutto bene.

Fondamentalmente, prima di poter utilizzare quicklisp, è necessario caricarlo (al momento, non è in bundle con SBCL, anche se potrebbe cambiare in futuro). Ci sono vari modi per farlo. Ad esempio, è possibile caricare il tuo .sbclrc con l'init quicklisp:

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

o semplicemente incollare queste righe nello script, come avete suggerito.

+2

Wow, "stai facendo tutto bene" ... queste parole sono davvero rare, grazie, @Vsevolod. Sia le tue che le risposte di Martial sono fantastiche e funzionanti, mi è dispiaciuto che si possa contrassegnare solo la singola risposta. :) Preferisco il coredumping, ma mi salva una riga in ogni sceneggiatura con poco overhead di preparativi in ​​forma di collegamento simbolico di tutto insieme. – hijarian

+2

@hijarian nessun problema. Come ho detto ci sono molti modi per risolvere il tuo problema. Spero di vedere ancora più risposte :) –

Problemi correlati