问题
I'm running the teapot example from cl-opengl package. The only changes I've made are loading the required packages. It works fine when executed from unix shell (sbcl --load "3.cl"
), but when I try to compile and load it through SLIME (C-c C-k
) i get the error about package GLUT
not found.
Curiously, the compiler chokes on the (defclass glut-teapot-window (glut:window)
.
What gives???
Here's a screenshot of what happens
Here's the code for 3.cl.
;;;; -*- Mode: lisp; indent-tabs-mode: nil -*-
;;; glut-teapot.lisp --- Simple usage of glut:solid-teapot.
(ql:quickload :cl-opengl)
(ql:quickload :cl-glu)
(ql:quickload :cl-glut)
;(setf *communication-style* :fd-handler)
(defclass glut-teapot-window (glut:window)
()
(:default-initargs :width 250 :height 250 :title "glut-teapot.lisp"
:mode '(:single :rgb :depth)))
(defmethod glut:display-window :before ((w glut-teapot-window))
(gl:clear-color 0 0 0 0)
(gl:cull-face :back)
(gl:depth-func :less)
(gl:disable :dither)
(gl:shade-model :smooth)
(gl:light-model :light-model-local-viewer 1)
(gl:color-material :front :ambient-and-diffuse)
(gl:enable :light0 :light1 :lighting :cull-face :depth-test))
(defmethod glut:display ((window glut-teapot-window))
(gl:load-identity)
(gl:translate 0 0 -5)
(gl:rotate 30 1 1 0)
(gl:light :light0 :position '(100 1000 1 0))
(gl:light :light0 :diffuse '(1.2 0.4 0.6 0))
(gl:light :light1 :position '(-100 1000 1 0))
(gl:clear :color-buffer :depth-buffer)
(gl:color 1 10 1)
(gl:front-face :cw)
(glut:solid-teapot 1.3)
;(glut:solid-torus 0.5 1.0 50 50)
;(glu:cylinder (glu:new-quadric) 0.5 0.5 0.5 20 20)
(gl:front-face :ccw)
(gl:flush))
(defmethod glut:reshape ((window glut-teapot-window) width height)
(gl:viewport 0 0 width height)
(gl:matrix-mode :projection)
(gl:load-identity)
(glu:perspective 50 (/ width height) 0.5 20)
(gl:matrix-mode :modelview)
(gl:load-identity))
(defmethod glut:keyboard ((window glut-teapot-window) key x y)
(declare (ignore x y))
(when (eql key #\Esc)
(glut:destroy-current-window)))
(defun glut-teapot ()
(glut:display-window (make-instance 'glut-teapot-window)))
(glut-teapot)
回答1:
If you load the file, the Lisp system reads the file expression by expression and executes them after reading each single expression.
If you compile the file in a fresh Lisp, then it reads the expressions and compiles them. But it does not execute them. Thus it sees the quickload command, compiles it, but does not execute it. This OpenGL code is not loaded and the packages are not known to the compiler. But that makes sense: a compile usually should compile the file, not execute it. Lisp would execute the expressions then when you load the compiled fasl file.
There are two simple ways around it:
- put the quickload operation in a separate file and compile/execute it before compiling the next file.
- enclose the load operations in an
EVAL-WHEN
statement.(eval-when (:execute :load-toplevel :compile-toplevel) ... your code here ...)
.
The :compile-toplevel
symbol means, that the code will be executed when the compiler sees it as a top-level form. Which it otherwise would not do. Thus you can have code in a file to compile which creates side effects - here loading other code.
来源:https://stackoverflow.com/questions/15029420/not-able-to-find-package-when-running-from-slime-but-from-command-line-is-ok