I have the following directory structure:
my-project/
├── my-project.asd
├── package.lisp # defpackage.
├── utils.lisp # Functions used by main.lisp.
└── main.lisp # Main program.
my-project.asd:
(defsystem "my-project"
:components ((:file "package")
(:file "utils")
(:file "main")))
package.lisp:
(defpackage :com.example
(:use :cl))
utils.lisp:
(in-package :com.example)
(defun double (x)
(* x 2))
main.lisp:
(in-package :com.example)
(format t "~a" (double 3))
The problem is: how do I compile and run main.lisp using ASDF?
I was able to compile and run the program by:
$ mv my-project ~/common-lisp/.
$ sbcl
* (require :asdf)
* (asdf:load-system :my-project)
However, this is incredibly silly. I do not want to move my project into ~/common-lisp/ just to run it. I want to compile and run the program right from the project directory itself. The my-project/ directory could be anywhere, and I want it to be possible to be placed anywhere. In other words, I would like to load the system from the current directory.
Think of make, where I can compile files right from the directory of the Makefile itself. How do I similarly compile and run a Common Lisp program from the directory of the *.asd file itself?
(I am using SBCL version 1.4.5 and ASDF version 3.3.1)
I found that it is possible to do the following:
$ sbcl
* (require "asdf")
* (asdf:load-asd (merge-pathnames "my-project.asd" (uiop:getcwd)))
* (asdf:load-system :my-project)
Note:
(require "asdf") is the recommended way to load ASDF, according to the "Loading ASDF" section of the ASDF manual.
NB: all implementations except GNU CLISP also accept
(require "ASDF"),(require 'asdf)and(require :asdf). For portability’s sake, you should use(require "asdf").
asdf:load-asd must be an absolute path and might not fail with any error when the path given to it is incorrect (!), so make sure that the given absolute path is correct.
Using cl:load instead of asdf:load-asd might also appear to work, but the ASDF manual explicitly warns against this practice:
Indeed, ASDF does not load
.asdfiles simply withcl:load, and neither should you. You should let ASDF find and load them when you operate on systems. If you somehow must load a.asdfile, use the same functionasdf:load-asdthat ASDF uses. Among other things, it already binds the*package*toasdf-user. Recent versions of SLIME (2013-02 and later) know to do that when youC-c C-kwhen you use theslime-asdfcontrib.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With