无法使用系统中定义的lisp包

1am*_*bda 2 lisp sbcl common-lisp asdf quicklisp

我试图使用lisp代码制作可执行文件.但是我根本无法编译 lisp文件,因为hellowolrd在加载helloworld系统 之前没有包

;; test.lisp
(asdf:load-system :helloworld)

(defun main()
  (helloworld:start))
Run Code Online (Sandbox Code Playgroud)


当然,我制作了helloworld系统并将其放入~/quicklisp/local-projects/.helloworld系统成功加载没有错误.

;; ~/quicklisp/local-projects/helloworld/helloworld.asd
(asdf:defsystem helloworld 
  :version "1.0"
  :components ((:file "package")))

;; ~/quicklisp/local-projects/helloworld/package.lisp 
(defpackage :helloworld
  (:use :common-lisp :asdf)
  (:export :start))

(in-package :helloworld)
(defun start()
  (format t "Welcome, ASDF"))
Run Code Online (Sandbox Code Playgroud)


我想编译test.lisp没有显式加载.我也试过use-packagedefpackage,但失败了.

;; test.lisp
(asdf:load-system :helloworld)
(use-package :helloworld)

(defun main()
  (helloworld:start))


;; test.lisp
(asdf:load-system :helloworld)

(defpackage :test
  (:use :cl :asdf)
  (:export :main))

(in-package :test)

(defun main()
  (helloworld:start))
Run Code Online (Sandbox Code Playgroud)


如何helloworldhelloworld不加载的情况下使用系统中定义的包?我是否应该使用helloworld系统制作新系统?

Jos*_*lor 5

在这段代码中,有一些有趣的事情:

;; test.lisp
(asdf:load-system :helloworld)

(defun main()
  (helloworld:start))
Run Code Online (Sandbox Code Playgroud)

你不能整体编译它,因为你已经注意到尝试阅读符号hellowworld:start是一个问题,因为还没有helloworld包.要读取符号,至少需要定义包.但是,为什么我们不能得到同样的问题(asdf:load-system :helloworld)?简单地说,已经定义了ASDF包(要么是实现包含它,要么已经加载了它,或者其他东西.那么你可以做的一件事就是在编译时确保你已经加载了你的helloworld系统:

;; test.lisp
(eval-when (:compile-toplevel)
  (asdf:load-system :helloworld))

(defun main()
  (helloworld:start))
Run Code Online (Sandbox Code Playgroud)

那应该让你编译文件; 因为您在编译时会评估加载形式,然后将在您定义的时间定义包main.

当然,现在你将拥有一个已编译的文件,但是如果你将它加载到尚未加载helloworld系统的Lisp的新实例中会发生什么?你有问题.所以你真的想在加载文件时加载那个系统,也许你只是从文件中执行表单(例如,如果你一次只读一个表单并评估它们).因此,您可能希望在另外两个上下文中评估该负载系统:

;; test.lisp
(eval-when (:compile-toplevel :load-toplevel :execute)
  (asdf:load-system :helloworld))

(defun main()
  (helloworld:start))
Run Code Online (Sandbox Code Playgroud)

总而言之,在这种情况下,请务必考虑这是否是最适合加载系统的方法.如果由于某种原因,您试图将所有代码保存在一个文件中或制作交付脚本,那么这可能是有意义的.另一方面,如果您正在制作另一个ASDF可加载系统,那么您可能只需将helloworld作为依赖项包含在内,并让ASDF处理加载依赖项.