lisp 作为 shebang 脚本与在 SLIME 中运行的 lisp
我刚从 C++ 和 Python 开始接触 common-lisp。我正在尝试运行一个简单的 SDL 程序,该程序除了在屏幕上显示图像之外什么也不做。我可以在 SLIME 中让它工作。问题是,当从 shell 作为脚本运行时,它将不起作用。
我的程序如下所示:
#!/usr/bin/sbcl --script
(asdf:operate 'asdf:load-op :lispbuilder-sdl)
(defun main ()
(sdl:with-init ()
(sdl:window 320 240)
(sdl:draw-surface (sdl:load-image "image.png"))
(sdl:update-display)
(sdl:with-events ()
(:quit-event () t)
(:video-expose-event () (sdl:update-display)))))
(main)
当我将其作为脚本运行时,出现以下错误:
mkg@chisel:~/projects/common-lisp/sandbox$ ./hello-world.lisp
unhandled ASDF:MISSING-COMPONENT in thread #<SB-THREAD:THREAD "initial thread" RUNNING {AA5E849}>:
component "lispbuilder-sdl" not found
0: (SB-DEBUG::MAP-BACKTRACE #<CLOSURE (LAMBDA #) {AAF1EF5}>)[:EXTERNAL]
(...省略了长回溯)
奇怪的是,如果我执行以下操作,则该程序可以正常工作。我在 Emacs 中打开程序,在另一个窗口中启动 SLIME,然后在 SLIME 窗口中输入程序的第一行:
(asdf:operate 'asdf:load-op :lispbuilder-sdl)
然后,在编辑器窗口中,我点击 Cc Ck(编译/加载文件)。正如预期的那样,会弹出一个显示 image.png 的窗口。
为什么当作为 shebang 脚本运行时这不起作用?我该如何修复它?
I just started with common-lisp, having come from C++ and Python. I'm trying to run a simple SDL program that does nothing other than show an image on-screen. I can get it working from within SLIME. The problem is, it won't work when run from the shell as a script.
My program looks like this:
#!/usr/bin/sbcl --script
(asdf:operate 'asdf:load-op :lispbuilder-sdl)
(defun main ()
(sdl:with-init ()
(sdl:window 320 240)
(sdl:draw-surface (sdl:load-image "image.png"))
(sdl:update-display)
(sdl:with-events ()
(:quit-event () t)
(:video-expose-event () (sdl:update-display)))))
(main)
When I run this as a script, I get the following error:
mkg@chisel:~/projects/common-lisp/sandbox$ ./hello-world.lisp
unhandled ASDF:MISSING-COMPONENT in thread #<SB-THREAD:THREAD "initial thread" RUNNING {AA5E849}>:
component "lispbuilder-sdl" not found
0: (SB-DEBUG::MAP-BACKTRACE #<CLOSURE (LAMBDA #) {AAF1EF5}>)[:EXTERNAL]
(... long backtrace omitted)
Oddly, this program works fine if I do the following. I open the program in Emacs, start SLIME in another window, and in the SLIME window, I enter the first line of the program:
(asdf:operate 'asdf:load-op :lispbuilder-sdl)
Then, in the editor window, I hit C-c C-k (compile/load file). This pops up a window showing image.png, as expected.
Why does this not work when run as a shebang script? How can I fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 sbcl 的手册页所述,
--script
意味着--no-sysinit --no-userinit --disable-debugger --end-toplevel-options
,其中意味着不会读取初始化文件,因此如果您在那里设置 ASDF 注册表,则它不会设置,因此它无法找到lispbuilder-sdl
系统。您需要在脚本本身中设置注册表,或者保存可执行核心 已设置注册表并调用它而不是默认的 sbcl。通常你也可以将库保存在核心中,而不是将它们加载到脚本中,但我不太确定它如何与非 Lisp 库和资源交互。As the man page for sbcl says,
--script
implies--no-sysinit --no-userinit --disable-debugger --end-toplevel-options
, which means that initialization files are not read, and so if you set up ASDF registry there it is not set up, and so it cannot find thelispbuilder-sdl
system. You need to either set up the registry in the script itself, or save an executable core with the registry already set up and call that instead of the default sbcl. Usually you can also save libraries in the core instead of loading them in the script, but I am not quite sure how that interacts with non-Lisp libraries and resources.在 Lisp 中开发时的常用方法是使用
ASDF
来描述项目及其依赖项。然后,您可以轻松地(asdf:oos 'asdf:load-op :yourapp)
。对于大多数实现,有一种方法可以生成可执行形式的 asdf 定义。
The usual way when developing in lisp is to use
ASDF
to describe project and its dependencies. Then, you can easily(asdf:oos 'asdf:load-op :yourapp)
.For most implementations there is a way to generate executable form asdf definition.