not able to find package when running from SLIME, but from command line is ok

天大地大妈咪最大 提交于 2019-12-11 08:51:33

问题


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:

  1. put the quickload operation in a separate file and compile/execute it before compiling the next file.
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!