Lisp - 定义系统
Lisp - 使用 ASDF 定义系统
Section titled “Lisp - 使用 ASDF 定义系统”在现代 Common Lisp 中,一个 **系统(system)**是构成库或应用程序的源文件集合。ASDF (Another System Definition Facility) 是定义这些系统、管理其组件和处理依赖关系的事实标准工具。可以把 ASDF 文件(.asd)看作是 Rust 中的 Cargo.toml 或 Node.js 中的 package.json 的等价物。
创建系统定义文件
Section titled “创建系统定义文件”你通过创建一个名为 your-system-name.asd 的文件来定义一个系统。这个文件包含一个 Lisp 形式,它使用 asdf:defsystem 来声明元数据和组件。
my-library.asd
Section titled “my-library.asd”;;;; my-library.asd
(asdf:defsystem #:my-library :description "A brief description of my new library." :author "Your Name <you@example.com>" :license "MIT" :version "0.1.0" :serial t ; 确保组件按列出的顺序加载。
;; 声明该库依赖的其他系统。 ;; 如果它们不可用,ASDF 会要求 Quicklisp 获取它们。 :depends-on (#:alexandria #:drakma)
;; 定义构成系统的文件和模块。 :components ((:file "packages") ; 通常是第一个文件,定义包。 (:file "utils") (:file "main")))关键 defsystem 参数
Section titled “关键 defsystem 参数”- :description, :author, :license, :version:项目的标准元数据。
- :depends-on:你的项目所需的其他 ASDF 系统列表。这是依赖管理的基础。
- :components:系统组成部分的列表。最常见的类型是
:file(用于单个.lisp文件,不带扩展名)和:module(用于包含更多组件的子目录)。 - :serial t:一个便捷选项,告诉 ASDF 按照它们在
:components列表中出现的精确顺序编译和加载组件。这对于更简单的系统来说非常常见。
推荐的项目结构
Section titled “推荐的项目结构”一个典型的 Common Lisp 项目遵循标准的目录布局:
my-library/├── my-library.asd ; 系统定义文件├── README.md├── LICENSE├── packages.lisp ; 定义系统的包├── main.lisp ; 主源代码└── utils.lisp ; 工具函数使用 Quicklisp 加载系统
Section titled “使用 Quicklisp 加载系统”Quicklisp 是 Common Lisp 的标准库管理器。它与 ASDF 协同工作。虽然你可以直接使用 ASDF,但现代的工作流程是使用 Quicklisp,它反过来会使用 ASDF 来构建和加载你的系统及其依赖项。
要加载你正在开发的本地项目,你必须首先确保 Quicklisp 知道在哪里找到它。最简单的方法是将你的项目文件夹放入 ~/quicklisp/local-projects/。一旦项目在那里,你就可以从 REPL 中加载它:
;; 将你的系统(及其依赖项)加载到你的 Lisp 镜像中。(ql:quickload :my-library)Quicklisp 将找到 my-library.asd,解析它,如果需要,下载 :depends-on 中列出的所有依赖项,然后要求 ASDF 按正确顺序编译并加载所有组件文件。
使用 ASDF 的优势
Section titled “使用 ASDF 的优势”- 标准化:ASDF 为 Common Lisp 提供了通用的“项目文件”格式,使得其他人可以轻松使用你的代码。
- 依赖管理:与 Quicklisp 无缝集成,实现所需库的自动获取和加载。
- 自动编译:ASDF 跟踪文件更改,仅在必要时重新编译文件,从而加速你的开发工作流程。
- 可移植性:ASDF 定义的系统可以被任何开发者在任何主流 Common Lisp 实现(如 SBCL、CCL 等)上加载和使用。
后续步骤:测试系统
Section titled “后续步骤:测试系统”ASDF 还可以配置为运行你的项目的测试套件。这通常涉及向你的系统定义添加 :test-op 并使用 FiveAM 或 Parachute 等测试框架。
;; 配置完成后,你可以像这样运行测试:(asdf:test-system :my-library)