Common lisp 如何从.asd文件的目录编译和运行公共Lisp程序?

Common lisp 如何从.asd文件的目录编译和运行公共Lisp程序?,common-lisp,asdf,Common Lisp,Asdf,我有以下目录结构: my-project/ ├── my-project.asd ├── package.lisp # defpackage. ├── utils.lisp # Functions used by main.lisp. └── main.lisp # Main program. my project.asd: (defsystem "my-project" :components ((:file "package")

我有以下目录结构:

my-project/
├── my-project.asd
├── package.lisp  # defpackage.
├── utils.lisp    # Functions used by main.lisp.
└── main.lisp     # Main program.
my project.asd

(defsystem "my-project"
  :components ((:file "package")
               (:file "utils")
               (:file "main")))
package.lisp

(defpackage :com.example
  (:use :cl))
(in-package :com.example)

(defun double (x)
  (* x 2))
(in-package :com.example)

(format t "~a" (double 3))
(load "my-project.asd")  ;; relative path: we must be in the same directory
(ql:quickload "my-project")  ;; I installed Quicklisp and my ~/.sbclrc has the Quicklisp-initialization snippet

(my-project::main)  ;; whatever function acts as the entrypoint
(uiop:quit)         ;; portable way to quit.
utils.lisp

(defpackage :com.example
  (:use :cl))
(in-package :com.example)

(defun double (x)
  (* x 2))
(in-package :com.example)

(format t "~a" (double 3))
(load "my-project.asd")  ;; relative path: we must be in the same directory
(ql:quickload "my-project")  ;; I installed Quicklisp and my ~/.sbclrc has the Quicklisp-initialization snippet

(my-project::main)  ;; whatever function acts as the entrypoint
(uiop:quit)         ;; portable way to quit.
main.lisp

(defpackage :com.example
  (:use :cl))
(in-package :com.example)

(defun double (x)
  (* x 2))
(in-package :com.example)

(format t "~a" (double 3))
(load "my-project.asd")  ;; relative path: we must be in the same directory
(ql:quickload "my-project")  ;; I installed Quicklisp and my ~/.sbclrc has the Quicklisp-initialization snippet

(my-project::main)  ;; whatever function acts as the entrypoint
(uiop:quit)         ;; portable way to quit.
问题是:如何使用ASDF编译和运行
main.lisp

我能够通过以下方式编译和运行程序:

$ mv my-project ~/common-lisp/.
$ sbcl
* (require :asdf)
* (asdf:load-system :my-project)
然而,这是难以置信的愚蠢。我不想仅仅为了运行它而将我的项目移动到
~/common lisp/
。我想从项目目录本身编译并运行程序。
myproject/
目录可以放在任何地方,我希望它可以放在任何地方。换句话说,我想从当前目录加载系统

想想
make
,我可以直接从
Makefile
本身的目录编译文件。如何从
*.asd
文件本身的目录编译和运行公共Lisp程序


(我使用的是SBCL版本1.4.5和ASDF版本3.3.1)

您需要告诉ASDF在哪里可以找到您的项目

以下是相关参考资料:

引用上述资源:

首先创建目录 ~/.config/common lisp/source-registry.conf.d/;这里创建了一个文件 使用您选择的任何名称,但使用conf类型,例如 50-luser-lisp.conf;在此文件中,添加以下行以告知ASDF 递归扫描/home/luser/lisp/for下的所有子目录 .asd文件:(:tree“/home/luser/lisp/”)

够了。您可以在任何地方替换/home/luser/lisp/ 安装您的源代码。您实际上不需要指定 如果使用上面的默认~/common lisp/和 实现提供了ASDF 3.1.2或更高版本。如果您的实现 提供ASDF 3的早期变体,您可能需要指定 (:tree(:home“common lisp/”)用于引导,然后安装 最近在~/common lisp/ASDF/下的ASDF源代码树


链接中还有更多内容。

这就是我解决这个问题的方法。这可能不是你所需要的,但这里可能有一些想法可以帮助你

促进发展 确保您尝试构建的系统只有一个副本。因此,尤其要确保ASDF没有可能找到的已安装副本:见下文

那么,这将起作用。首先确保您的ASDF系统定义是可冷加载的,因此特别要确保它在顶部有正确的
(在包中:ASDF user)

那么,构建您的系统的方法是:

$ cd .../my-project
$ sbcl
[...]
* (require :asdf) ;already loaded in my case by init files
nil
* (load "my-project.asd")
t
* (asdf:load-system "my-project")
; compiling file "/media/psf/share/tmp/my-project/package.lisp" (written 15 DEC 2020 09:06:54 AM):
; processing (defpackage :com.example ...)
[...]
*
现在你很好。所以我做的三个技巧是:

  • 根本不要去想整个源代码注册中心的头发,因为如果你想得太多,有触手的东西会把你的脸撕下来(我知道,这发生在我身上,我现在没有脸了)
  • 确保系统只有一个副本,这样ASDF就不能使用我避免考虑的源注册表头发来找到错误的副本
  • 显式加载系统定义文件–无论ASDF在哪里查看,它至少会在与该文件相同的目录中查看
用于生产 答案是。执行任何需要的操作,使Quicklisp安装到您的Lisp中。然后您需要知道它的安装目录在哪里:有一些默认设置,但我从不使用它,因为我对文件系统应该是什么样子有自己的想法

然后诀窍是Quicklisp将在其
本地项目
目录下查找、构建和加载系统(据我所知,Quicklisp完全是由能力和魔力组成的)。因此,如果您将一个系统放在那里,那么Quicklisp将简单而优雅地处理将其放入运行映像中的问题

要执行此安装。。。我有makefile。我知道,我应该使用Lisp工具,但我生活在*nix平台上,
make
install
擅长整个文件复制

Makefile
的一个相关块(实际上这就是它的全部)是:

这里有四件有趣的事情:

  • 我只是使用
    make
    作为文件复制机——它没有编译任何东西或类似的东西,完全可以使用脚本
  • 您需要清除Quicklisp的缓存文件,以便它在开始时再次搜索
  • 我禁用了ASDF的输出翻译,这就是为什么我花时间清理编译后的文件——安装后,项目总是应该从冷态重建
  • uninstall
    目标是开发之前需要运行的,它将取消安装的版本,使ASDF无法找到它
一旦在项目目录中运行了合适的
makeinstall
,那么
(ql:quickload:org.tfeb.sample)
将为您编译并加载它


请注意,另一种方法(Ehvince在评论中建议)是在Quicklisp的
localprojects
目录下留下一个符号链接,返回到规范版本的代码。我不这样做,但这样做会很好,在某些方面可能会更好。

我发现有可能做到以下几点:

$ sbcl
* (require :asdf)
* (asdf:load-asd "/absolute/path/to/my-project/my-project.asd")
* (asdf:load-system :my-project)
注意:
asdf:load asd
在指定给它的路径不正确时,不会出现任何错误(!)


我不熟悉Common Lisp和ASDF,所以我不知道上面的内容是否合适。

我做了一些与您发现的类似的事情。其要点是加载.asd

先决条件
my project.asd
开头(需要“asdf”)

当我在Slime上时,我可以
C-C-k
(编译并加载)这个文件

我不太清楚“-load”是否/为什么需要它

一班轮 我只需调用一次Lisp编译器即可构建项目:

sbcl --load my-project.asd --eval '(asdf:load-system "my-project")'
这会加载它并给我一个回复。我可以添加
--eval(uiop:quit)
以退出

注:我听说