Search code examples
common-lispquicklisp

Quickload inside eval-when


Here's a strange situation. I have this code:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload "cffi-grovel")
  (setf cffi-grovel::*cc* "mpicc")) ; <--- this is the line it complains about.

Which I belive has to load cffi-grovel package before setting cffi-grovel::*cc* variable. When this form is executed from SLIME it works, but it doesn't work when loaded directly by SBCL, here's the output:

$ sbcl --noinfo
* (ql:quickload "cl-mpi")

debugger invoked on a LOAD-SYSTEM-DEFINITION-ERROR in thread
#<THREAD "main thread" RUNNING {10029C0E43}>:
  Error while trying to load definition for system cl-mpi from pathname
  /home/wvxvw/quicklisp/local-projects/cl-mpi/cl-mpi.asd:
     READ error during COMPILE-FILE:

       Package CFFI-GROVEL does not exist.

         Line: 6, Column: 25, File-Position: 264

< restarts ... >

* (ql:quickload "cffi-grovel")
To load "cffi-grovel":
  Load 1 ASDF system:
    cffi-grovel
; Loading "cffi-grovel"
..
("cffi-grovel")
* (ql:quickload "cl-mpi")
To load "cffi-grovel":
  Load 1 ASDF system:
    cffi-grovel
; Loading "cffi-grovel"

To load "cl-mpi":
  Load 1 ASDF system:
    cl-mpi
; Loading "cl-mpi"
; mpicc -m64 ...
; ...
.
("cl-mpi")

Why does it fail the first time?

PS. I also tried #.cffi-grovel::*cc* instead - same result.


Solution

  • monoid gives a good answer. Here is a slightly shorter form.

    Find the symbol at runtime, when the package actually exists. Note the use of SET, not SETF here:

    (set (find-symbol "*CC*" "CFFI-GROVEL") "mpicc")
    

    To make it more robust, one would need to check that FIND-SYMBOL actually finds the symbol. The following function also gives you meaningful error messages and restarts:

    (defun set-runtime-symbol (name package value)
      (assert (find-package package) (package))
      (assert (find-symbol name package) (name))
      (set (find-symbol name package) value))
    

    Alternatively use two EVAL-WHEN statements, instead of one.