Search code examples
emacslispcommon-lispclispquicklisp

How to load external dependencies with quicklisp?


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?


Solution

  • 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.