在eval-when内部快速加载

0 common-lisp quicklisp

这是一个奇怪的情况.我有这个代码:

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

我相信我必须cffi-grovel在设置cffi-grovel::*cc*变量之前加载包.当这个表单从SLIME执行时它可以工作,但是当它由SBCL直接加载时它不起作用,这是输出:

$ 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")
Run Code Online (Sandbox Code Playgroud)

为什么第一次失败?

PS.我也试过#.cffi-grovel::*cc*- 相同的结果.

mon*_*oid 6

它失败了,因为Lisp在执行之前读取每个表单.当它读取它时,包cffi-grovel确实还不存在,因为cffi-grovel在执行时被加载(无论它对于包含eval-when的表单意味着什么).

尝试将eval-when表单拆分为两个eval-whens:ql:quickload和setf.或写下这样的东西:

(setf (symbol-value (find-symbol "*CC*" "CFFI-GROVEL"))
      "mpicc")
Run Code Online (Sandbox Code Playgroud)