← Blog of oldlisper

cookbook:asdf

· 24.09.2009 11:45
· old wiki

ASDF

ASDF или "Another System Definition Facility" это система слежения за расположением и зависимостями исходных кодов, а также - система установки пакетов. О ней стоит рассказать, хотя бы потому, что она повсеместно используется.

Как получить?

Одним файлом - asdf.lisp, для большинства целей этого достаточно. Но можно получить и архив с дополнениями : asdf.tar.gz. Для доступа к git-репозиторию:

$ git clone http://common-lisp.net/project/asdf/asdf.git

Как использовать?

Для начала нужно посмотреть, не установлен ли ASDF уже:

(require 'asdf)
; Если ASDF обнаружен, но не загружен - он загружается, функция возвращает ("ASDF")
; Если ASDF уже загружен (например в сеансе slime) функция вернёт NIL
; Но если ASDF не найден - будет ошибка

В SBCL ASDF установлен по умолчанию. На других реализациях - имеем третий вариант, поэтому загружаем asdf.lisp и задаём необходимые переменные:

(load ".../asdf.lisp") ; путь к asdf.lisp
(load ".../some-system.asd") ; файл asd - основной файл для системы ASDF (как Makefile), он обычно один для пакета
; ИЛИ : можно определить пути по которым ASDF будет искать файлы asd
(setf asdf:*central-registry*
    (list '*default-pathname-defaults*
        #p"/home/dev/cl/system1/"
        #p"/home/dev/cl/system2/"
)
)

; так или иначе, после загрузки asd должно появится символическое имя пакета, по которому его можно загрузить:
(asdf:operate 'asdf:load-op :package-name) ; то же, что и (asdf:oos 'asdf:load-op :package-name)
; всё - далее можно сделать (in-packege :package-name) и использовать пакет

На примере CL-PPCRE

Библиотека для работы с регулярными выражениями CL-PPCRE использует файл cl-ppcre.asd для установки. Допустим, директория для ваших лисп-библиотек /home/room/lisp, тогда для Clisp:

$ pwd
/home/room/lisp
$ wget http://common-lisp.net/project/asdf/asdf.tar.gz
...
$ tar zxvf asdf.tar.gz
...
$ wget http://www.weitz.de/files/cl-ppcre.tar.gz
...
$ tar zxvf cl-ppcre.tar.gz
...
$ ls
asdf/ cl-ppcre/
$ vi run-ppcre
(load "/home/room/lisp/asdf/asdf.lisp")
(load "/home/room/lisp/cl-ppcre/cl-ppcre.asd")
(asdf:oos 'asdf:load-op :cl-ppcre)
$ clisp -i run-ppcre
...
[1] (in-package :cl-ppcre)
[2]

В SBCL можно поступить иначе: при первом запуске

(load "/home/room/lisp/cl-ppcre/cl-ppcre.asd")
(require 'cl-ppcre)

А после - просто:

(require 'cl-ppcre)

CFFI

Часто бывает, что пакет имеет зависимости - например, чтобы поставить CFFI нужно поставить ещё три пакета. Чтобы узнать о зависимостях нужно посмотреть в cffi.asd часть :depends-on (alexandria trivial-features babel). Три перечисленых пакета зависят только друг от друга, их можно найти на CLiki. После скачивания всех четырех архивов, разархивируем их в папку с библиотеками:

$ wget http://common-lisp.net/project/cffi/releases/cffi_latest.tar.gz
$ wget http://common-lisp.net/~loliveira/tarballs/inofficial/alexandria-2008-07-29.tar.gz
$ wget http://common-lisp.net/project/babel/releases/babel_latest.tar.gz
$ wget http://common-lisp.net/~loliveira/tarballs/trivial-features/trivial-features_latest.tar.gz
$ tar zxvf cffi_latest.tar.gz
$ tar zxvf alexandria-2008-07-29.tar.gz
$ tar zxvf trivial-features_latest.tar.gz
$ tar zxvf babel_latest.tar.gz

и пишем такой скрипт загрузки:

;; load-cffi.lisp

(load "/.../trivial-features_0.5/trivial-features.asd") ; вместо троеточия - правильный путь
(load "/.../alexandria/alexandria.asd")
(load "/.../babel_0.3.0/babel.asd")
(load "/.../cffi_0.10.5/cffi.asd")

(asdf:oos 'asdf:load-op :trivial-features)
(asdf:oos 'asdf:load-op :alexandria)
(asdf:oos 'asdf:load-op :babel)
(asdf:oos 'asdf:load-op :cffi)

Автоматическая загрузка

Чтобы не запускать каждый раз скрипты инициализации, как load-cffi.lisp, автоматизируем загрузку пакетов. Для SBCL можно отредактировать файл .sbclrc в домашней папке - он выполняется при каждой загрузке SBCL:

$ kwrite ~/.sbclrc

Лучше помещать в него пакеты, которые действительно необходимы, чтобы не тратит время при каждом запуске.

(require 'trivial-features)
(require 'alexandria)
(require 'babel)
(require 'cffi)
(require 'cl-ppcre)

Предполагается, что все пакеты уже были установлены с помощью asdf:oos 'asdf:load-op