ASDF 简单翻译
About
翻译自 ASDF (Another System Definition Facility).
请注意这并不是完整的翻译, 更多类似于笔记的东西.
ASDF 3
ASDF 为 Common Lisp 事实上的编译工具链. 一般的 CL 发行一般都包含了 ASDF.
(使用 (require "asdf") 可以调用).
What it is
ASDF 为 CL 程序员用于编译和加载程序的软件. 其由 asdf/defsystem 和 uiop 组成:
asdf/defsystem一个用于定义 Lisp 代码是如何组织的工具, 以及定义了如何编译和加载这些系统. 编译过程会通过系统代码的组织结构自动生成并解决编译依赖关系.
uiop为 U tilities for I mplementation- and OS - P ortability, 之前被称为
asdf/driver, 可以帮助写出比较通用的跨平台的软件.
What it is not
ASDF 并不会自动下载缺省的依赖包, 可以使用 Quicklisp 来解决该问题.
Documentation
翻译自 ASDF Manual.
Quick start summary
- 载入 ASDF 的系统
- 首先需要保证 ASDF 已经在你的系统中了, 可以参考 Loading ASDF.
一般新的发行版都已经有了吧…
- 确保要载入的文件在可以被 ASDF 找到,
可以参考 Configuring ASDF to find your system.
常见的应该是被放在
~/common-lisp/,~/.local/share/common-lisp/source/文件夹下. - 使用
(asdf:load-system "my-system")来载入系统, 参考 Using ASDF.
- 首先需要保证 ASDF 已经在你的系统中了, 可以参考 Loading ASDF.
- 定义自己的 ASDF 系统
- 同上, 载入并配置 ASDF
- 在 ASDF 可以发现的路径下新建系统的目录, 比如
my-system - 定义系统: 库依赖, 代码组成, 代码间相互依赖关系, 在
my-system.asd中定义. 可以参考 Defining systems with defsystem. - 使用
asdf:load-system来确保正常工作
载入的代码可以用 Quicklisp 来:
ql:quickload. 这自动解决依赖不是一件美事么?
Defining systems with defsystem
defsystem 的形式
(defsystem "system-name"
:description "this is a simple description for system-name"
:version "0.0.1"
:author "ryo"
:licence "MIT"
:depends-on ("..." "...")
:components ((:file "packages")
(:file "macros" :depends-on ("packages"))
(:file "hello" :depends-on ("macros"))))
defsystem定义了一个叫做system-name的系统, 该系统包含了packages.lisp,macros.lisp和hello.lisp的文件.lisp后缀在命名文件的时候是可以省略的, 该定义文件要被放在.asd文件中这个依赖关系一目了然了吧, 通过:depends-on的方式声明:components中的依赖关系- 对于外部依赖, 通过
:depends-on来声明 - 其他的一些元数据, 比如
:bug-tracker,:mailto,:long-description,:source-control等同样可以说明 - 对于
:version, 参考 Version specifiers - 推荐的声明的方法就是单一
defsystem, 不建议使用in-package和asdf:defsystem
The defsystem grammar
defsystem grammar
system-definition := ( defsystem system-designator system-option* )
system-designator := simple-component-name
| complex-component-name
# NOTE: Underscores are not permitted.
# see Simple component names
simple-component-name := lower-case string | symbol
# see Complex component names
complex-component-name := string | symbol
system-option := :defsystem-depends-on dependency-def
| :weakly-depends-on system-list
| :class class-name # see System class names
| :build-pathname pathname-specifier
| :build-operation operation-name
| system-option/asdf3
| module-option
| option
# These are only available since ASDF 3 (actually its alpha release
# 2.27)
system-option/asdf3 := :homepage string
| :bug-tracker string
| :mailto string
| :long-name string
| :source-control source-control
| :version version-specifier
| :entry-point object # see Entry point
source-control := ( keyword string )
module-option := :components component-list
| :serial [ t | nil ]
option := :description string
| :long-description string
| :author person-or-persons
| :maintainer person-or-persons
| :pathname pathname-specifier
| :default-component-class class-name
| :perform method-form
| :explain method-form
| :output-files method-form
| :operation-done-p method-form
| :if-feature feature-expression
| :depends-on ( dependency-def* )
| :in-order-to ( dependency+ )
person-or-persons := string | ( string+ )
system-list := ( simple-component-name* )
component-list := ( component-def* )
component-def := ( component-type simple-component-name option* )
component-type := :module | :file | :static-file | other-component-type
other-component-type := symbol-by-name # see Component types
# This is used in :depends-on, as opposed to "dependency", which is used
# in :in-order-to
dependency-def := simple-component-name
| ( :feature feature-expression dependency-def ) # see Feature dependencies
| ( :version simple-component-name version-specifier )
| ( :require module-name )
# "dependency" is used in :in-order-to, as opposed to "dependency-def"
dependency := ( dependent-op requirement+ )
requirement := ( required-op required-component+ )
dependent-op := operation-name
required-op := operation-name
# NOTE: pathnames should be all lower case, and have no underscores,
# although hyphens are permitted.
pathname-specifier := pathname | string | symbol
version-specifier := string
| ( :read-file-form pathname-specifier form-specifier? )
| ( :read-file-line pathname-specifier line-specifier? )
line-specifier := :at integer # base zero
form-specifier := :at [ integer | ( integer+ ) ]
method-form := ( operation-name qual lambda-list &rest body )
qual := method-qualifier?
method-qualifier := :before | :after | :around
feature-expression := keyword
| ( :and feature-expression* )
| ( :or feature-expression* )
| ( :not feature-expression )
operation-name := symbol
System designators
系统名称可以为一个简单的名字, 或者是通过 / 分割的这样的比较复杂的名字.
Simple component names simple-component-name
可以是字符串或者符号 (strings or symbols).
在使用字符串的时候, 请仅使用 小写 符号.
符号 (symbols) 会被转换成对应的名字字符串 (小写).
不要 使用下划线来命名.
在简单的组件名称中 不要 使用 /, / 意味着一个复杂的组件名字.
使用 / 会导致 ASDF 进行一个 Warning 提示.
破坏这些命名约定的后果就是会导致系统难以被发现.
Complex component names
复杂组件名称即包含 / 的组件名称, 其用于将多个子系统包含在一个 .asd 文件中定义.
其中主系统名称需要和 .asd 文件名称相同.
foo.asd 中定义叫做 foo 的系统. 同时, 该文件中可以包含类似于 foo/test,
foo/docs 等子系统. ASDF 将会理解这些子系统定义.
Serial dependencies
这个是一个依赖关系的简化记号, 若 :serial t 开启了该选项,
那么 ASDF 对于组件会默认认为是线性依赖, 即:
:serial t
:components ((:file "a") (:file "b") (:file "c"))
与
:components ((:file "a")
(:file "b" :depends-on ("a"))
(:file "c" :depends-on ("a" "b")))
等价.
暂时性的停止
感觉翻译这么多就够了, 对于我平时用到的小项目声明应该不至于需要更多的功能了.