Where should a Quicklisp QUICKLOAD go in my source? Nowhere?
Asked Answered
S

4

9

Let's say I build an application on top of net.aserve and bordeaux-threads. My package declaration might look like this:

(defpackage :my-package
  (:use :cl :net.aserve :bordeaux-threads)
  (:export …))

I use Quicklisp, so I run (ql:quickload "aserve") (ql:quickload "bordeaux-threads") in SLIME before compiling my package, and everything is fine.

Of course, tomorrow I start up SLIME again and I have to remember to issue the QUICKLOADs before I compile, otherwise I'm in for trouble.

I could put something like

(eval-when (:compile-toplevel)
  (ql:quickload "aserve")
  (ql:quickload "bordeaux-threads"))

at the top of my package—it's what I've done for development—but I have a feeling it's not a good idea to force a package manager on a user.

Is there a better alternative?

Sargassum answered 23/3, 2012 at 0:6 Comment(3)
Can you put it in your .clinit.cl file? See franz.com/support/documentation/6.2/doc/….Businesslike
@JohnPick I could, though I'm not running Allegro CL, but SBCL probably has an equivalent.Sargassum
(indeed, .sbclrc) I think this probably is my best bet—I have this feeling that it's somehow a pity that I have to run it on every startup, but something in the back of my mind tells me that what I'm looking for doesn't even make sense—hence the "Nowhere?" in the question title, I guess!Sargassum
B
16

In your asd file, you should define the depends realtion as below:''

(asdf:defsystem #:aserve
 :serial t
 :depends-on (#:hunchentoot :hunchentoot-cgi
           #::bordeaux-threads
           #:parenscript)
 ...)

After then you just need to (ql:quickload :aserve) .

Billi answered 23/3, 2012 at 1:26 Comment(4)
I'm not writing aserve, I'm trying to consume it—and just running (ql:quickload :aserve) manually is what I'm trying to avoid!Sargassum
@ArlenCuss: Just add aserve to the list of dependences like hunchentoot or bordeaux-threads, then when you'll load (or quickload) this system, it will load the dependences. Actually that's basically what Quicklisp does, it uses ASDF and download missing dependences.Tardif
This is the correct answer to the question asked; the accepted answer is the answer to a different question (I'm not sure exactly what).Aleph
@Xach: I stand corrected. The accepted answer was one that seemed to achieve my aim. I have no idea what ASDF is yet, so z_axis' reference to "[my] asd file" threw me off. I'll see how this goes!Sargassum
M
11

Use quickproject (accessible via (ql:quickload :quickproject)) to create a system for your application. As z_axis described, you can then fill the list of dependencies in the defsystem declaration (if you missed any when you called quickproject:make-project).

If you create your new project in the local-projects path of you Quicklisp installation, you can quickload your project too (even if it's not part of the Quicklisp distribution yet). Quickloading your project will of course download the dependencies (if they are part of the Quicklisp distribution), then load them.

Millepede answered 23/3, 2012 at 6:45 Comment(3)
As z_axis implied (?), I can quickload it so long as the .asd is in the same directory.Sargassum
In the same directory as your project, and if your project directory is a direct child of the local-projects directory. Just follow Xach's instructions from the linked blog post (blog.quicklisp.org/2011/11/november-quicklisp-updates.html).Millepede
Oh wow, totally missed that link on local-projects. Thanks!Sargassum
A
3

If you don't want to include a quicklisp call in the deployed source code at all, separate the quickproject system definition file from the rest of the source.

At the top of the source, just before the defpackage call, add the necessary (require ...)'s for your package dependencies. This guarantees that those lisp packages are loaded (somehow) before proceeding, but does not specify 'how' those packages get loaded. They could be loaded by running the ql:quickload :my-package call (using quickproject), which would first load the dependencies, and then run through the require calls when loading the source. Or possibly a user could load the source directly (without calling ql:quickload), and the dependencies would be loaded during the require call, if those dependencies can be found on the *module-search-path*. This technique, as you said, would allow the end user to use whatever build tool he/she wants to load your source.

After experimenting with this for a few minutes, it seems that quicklisp latches into the require function call, so that if quicklisp is installed, and (require :bordeaux-threads) e.g., is called, lisp will use quicklisp to download and install that dependency. This is a very nice feature (IMO), because it allows the Common Lisp standard require function to act as the interface layer, and abstracts the specific build tool used to satisfy the dependency. Quicklisp can latch into the require, asdf latches into it (IIRC), etc.

So to answer your question, quicklisp calls should not go anywhere in the deployed source code, and requires should be used to ensure that dependencies are loaded before the package definition file is evaluated. If someone has quicklisp installed before loading the package definition file, those requires will be satisfied by using quicklisp to download and install the dependencies. If someone has asdf installed, those dependencies will be satisfied with that build tool. And if someone already has the dependencies installed (using some other technique), the requires will simply be passed over.

Aurthur answered 29/5, 2013 at 18:56 Comment(0)
H
2

I had exactly the same question and I agree I should not force a package manager on a user. Before quicklisp's time I was using clbuild and it puts all .asd files into a systems/ directory. As long as the `systems/' directory is in asdf:central-registry, one can simply (require "a-package"), at least in SBCL and CCL, to load all relevant packages. The new clbuild2 retains this feature if you do install-from-upstream, and its integrated quicklisp does respect the separately installed-from-upstream packages, but quicklisp installed packages don't expose their .asd files anymore.

So my solution is to write a shell script that scans all quicklisp installed packages, usually under dists/quicklisp/software/, and link all .asd files there to a central place. In this way one doesn't need to load quicklisp into the cl image if one only wants to use quicklisp installed packages. I hope quicklisp could ship this feature by default.

Hemimorphic answered 21/5, 2013 at 0:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.