How to load external dependencies with quicklisp?

1.1k views Asked by At

Here is my code:

(defpackage :com.yves.tests (:use :common-lisp))
(in-package :com.yves.tests)
(require :usocket)

Everytime I evaluate the require directive, I get this error:

LOAD: A file with name #1=USOCKET does not exist
   [Condition of type SYSTEM::SIMPLE-FILE-ERROR]

Of course I installed the package with quickload in my REPL:

CL-USER> (ql:quickload "usocket")
To load "usocket":
  Load 1 ASDF system:
    usocket
; Loading "usocket"

("usocket")
CL-USER> 

Actually I've installed it yesterday evening, and all my code was evaluating with no complain. Today I restarded Emacs and Slime. And I get this error. Is there additional configuration to do?

Here is what is in my loadpath:

CL-USER> (princ custom:*load-paths*)
(/Users/yves/quicklisp/ /opt/local/lib/clisp-2.49/dynmod/ ./ ~/lisp/**/)
(#P"/Users/yves/quicklisp/" #P"/opt/local/lib/clisp-2.49/dynmod/" #P"./"
 "~/lisp/**/")
CL-USER> 

Am I supposed to add the path to every new package by hand? Isn't quicklisp initialisation supposed to perform it, by itself?

2

There are 2 answers

3
Svante On BEST ANSWER

Require is not the required operation here.

In the simple case where you have your entire system in one self-sufficient file, you can wrap ql:quickload forms into an eval-when:

(in-package #:cl-user)

(eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload "usocket"))

(defpackage #:com.yves.tests
  (:use #:cl))

(in-package #:com.yves.tests)

;; your code here

If you want to use symbols from usocket without qualification, use it in the defpackage form:

(defpackage #:com.yves.tests
  (:use #:cl #:usocket))

If you have a bigger system that spans several files, you can use ASDF. A quick way to get a simple setup running is quickproject, also available from Quicklisp.

0
Sim On

Svante already answered a basic solution to your question, but it might be more comfortable to use quicklisp in combination with asdf (and an .asd file) to be able to expand the project and its requirements more easily.

Your setup for the .asd file would probably look like:

;;foobar.asd
(asdf:defsystem :foobar ;this is the name of your project
   :depends-on (:usocket) ;those are the names of the dependencies
   :components ((:file "the-file-name"))) ;this .asd has to be in the same folder (asdf-keyword :module)

After defining your foobar.asd you'll either move the project into the .quicklisp/local-project/ (a symlink will do) folder or you tell asdf how to find your project.

Now you should be able to load your project via (ql:quickload :foobar)

From now on asdf/quicklisp will take care of (down)loading all defined dependencies before loading your project.

If you later want to extend your project and therefore your projects .asd file, you can find valueable information at the asdf manual or stackoverflow. The project page for asdf can be visited here.