编写库

生态系统概述

在 Common Lisp 中,构建系统和包管理器是两个独立的部分。

ASDF
ASDF 是构建系统。它让你可以定义项目,称为“系统”,以及它们的元数据、依赖项、源代码文件和文件加载顺序。
Quicklisp
Quicklisp 是包管理器。它使用 ASDF 来提取包的依赖项并从中心存储库下载它们。与大多数包管理器不同,Quicklisp 不是命令行应用程序:你可以像其他任何 Lisp 工具一样在 REPL 中运行它,所以你可以非常轻松地上手。

定义系统

一个典型的系统定义如下所示(来自 项目)

(defsystem common-doc
  :author "Fernando Borretti <eudoxiahp@gmail.com>"
  :maintainer "Fernando Borretti <eudoxiahp@gmail.com>"
  :license "MIT"
  :version "0.2"
  :homepage "https://github.com/CommonDoc/common-doc"
  :bug-tracker "https://github.com/CommonDoc/common-doc/issues"
  :source-control (:git "git@github.com:CommonDoc/common-doc.git")
  :description "A framework for representing and manipulating documents as CLOS objects."
  :depends-on (:trivial-types
               :local-time
               :quri
               :anaphora
               :alexandria
               :closer-mop)
  :components ((:module "src"
                :serial t
                :components
                ((:file "packages")
                 (:file "define")
                 (:file "error")
                 (:file "file")
                 (:file "classes")
                 (:file "metadata")
                 (:file "constructors")
                 (:file "macros")
                 (:file "format")
                 (:file "util")
                 (:module "operations"
                  :serial t
                  :components
                  ((:file "traverse")
                   (:file "figures")
                   (:file "tables")
                   (:file "links")
                   (:file "text")
                   (:file "unique-ref")
                   (:file "toc")
                   (:file "equality")))
                 (:file "print"))))
  :long-description
  #.(uiop:read-file-string
     (uiop:subpathname *load-pathname* "README.md"))
  :in-order-to ((test-op (test-op common-doc-test))))

分解一下,第一行定义系统名称,common-doc

接下来,我们有元数据

:author "Fernando Borretti <eudoxiahp@gmail.com>"
:maintainer "Fernando Borretti <eudoxiahp@gmail.com>"
:license "MIT"
:version "0.2"
:homepage "https://github.com/CommonDoc/common-doc"
:bug-tracker "https://github.com/CommonDoc/common-doc/issues"
:source-control (:git "git@github.com:CommonDoc/common-doc.git")
:description "A framework for representing and manipulating documents as CLOS objects."

ASDF 允许我们提供作者的联系信息(名称和电子邮件地址)、许可信息、版本字符串、一些有用的链接以及一行描述。

然后,我们有依赖项列表

:depends-on (:trivial-types
             :local-time
             :quri
             :anaphora
             :alexandria
             :closer-mop)

这只是一个系统所依赖的系统列表。此处可以指定版本,但通常在外部进行版本管理,请见下面。

紧随其后的是组件,基本上是源代码树的描述。模块是目录,文件是 Lisp 文件。

:components ((:module "src"
              :serial t
              :components
              ((:file "packages")
               (:file "define")
               (:file "error")
               (:file "file")
               (:file "classes")
               (:file "metadata")
               (:file "constructors")
               (:file "macros")
               (:file "format")
               (:file "util")
               (:module "operations"
                :serial t
                :components
                ((:file "traverse")
                 (:file "figures")
                 (:file "tables")
                 (:file "links")
                 (:file "text")
                 (:file "unique-ref")
                 (:file "toc")
                 (:file "equality")))
               (:file "print"))))

:serial t 选项基本上表示“此目录中的文件应按此处显示的顺序加载。ASDF 还允许我们更复杂,并手动指定哪些文件依赖于哪些文件,并且只要让 ASDF 确定加载它们的总顺序即可。但对于大多数情况,只需使用 :serial t 即可足够。

然后,我们使用 :long-description 选项和读取时执行将 README.md 文件嵌入到系统定义中

  :long-description
  #.(uiop:read-file-string
     (uiop:subpathname *load-pathname* "README.md"))

此选项由诸如 [Quickdocs][qd] 之类的工具用于显示关于系统的信息。

最后,我们告诉 ASDF 关于关联的测试系统,这是加载测试框架并运行独立测试的系统。我们将在单元测试指南中介绍它。

  :in-order-to ((test-op (test-op common-doc-test)))

配置 ASDF

在加载系统之前,您必须告诉 ASDF 在何处找到它们。这在 ~/.config/common-lisp/source-registry.conf 文件中指定。

例如,以下配置

(:source-registry
  (:tree (:home "code"))
  :inherit-configuration)

告诉 ASDF 在 ~/code/ 目录中递归搜索以查找您的系统,并从 Quicklisp 继承配置以便您可以加载 Quicklisp 的系统。

加载

当您配置 ASDF 并创建了您的系统后,您可以使用 Quicklisp 或 ASDF 加载它

CL-USER> (asdf:load-system :my-system)
CL-USER> (ql:quickload :my-system)