Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I compile and run a Common Lisp program from the directory of the .asd file?

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)

like image 566
Flux Avatar asked Mar 02 '23 20:03

Flux


1 Answers

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 .asd files simply with cl:load, and neither should you. You should let ASDF find and load them when you operate on systems. If you somehow must load a .asd file, use the same function asdf:load-asd that ASDF uses. Among other things, it already binds the *package* to asdf-user. Recent versions of SLIME (2013-02 and later) know to do that when you C-c C-k when you use the slime-asdf contrib.

like image 200
Flux Avatar answered Apr 28 '23 12:04

Flux