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")))
等价.
暂时性的停止
感觉翻译这么多就够了, 对于我平时用到的小项目声明应该不至于需要更多的功能了.