2010-06-30

ASDF 2

Собираюсь написать серию постов про ASDF: его текущее развитие в связи с выходом ASDF 2, внутреннее устройство, шаблоны и некоторые идеи по поводу его использования. Вообще, в последние пару лет в Lisp-сообществе к этой теме (не только собственно ASDF, но и в целом управление сборкой и дистрибутивами), очень живой интерес, поскольку есть вопросы, которые требуют решения. Недавняя статья, дающая пищу для размышлений: Анализ использования ASDF в разных проектах.

ASDF является фактически единственным на данный момент сборщиком Common Lisp програм. Более того он играет свою роль в различных менеджерах дистрибутивов, хотя и не является самим по себе полноценным решением. И, я бы сказал, что со своей ролью инструмента сборки он справляется довольно неплохо, а вот в сфере описания дистрибутивов есть проблемы, которые пока что не решены на практике. Это заставляет многих людей, в том числе и меня, вообще не пользоваться подобными инструментами и произвоить установку дистрибутивов вручную (благо в Common Lisp среде, в том числе и благоаря ASDF это очень просто1), а других (в том числе и меня) задумыватся о создании собственного средства: примеры тому — Mudballs, Lispy, CL-Librarian, LibCL...

В недавней статье в журнале ПФП я написал, что
развитие средства управления пакетами должно идти именно с учетом децентрализованной структуры Лисп-среды, а не вопреки ей.

К такому же заключению мы пришли и в процессе обсуждения темы на форуме lisper.ru, которое также заставило меня немного заглянуть под капот ASDF, чтобы узнать, насколько реально и легко создать на его основе пакетный менеджер. Этот "быстрый взгляд" в итоге вылился в растянутое на целый месяц неспешное ковыряние кода и его доработку для полноценной поддержки версионирования. Свое решение я направил в список рассылки asdf-devel, однако оно вряд ли будет интегрированно. В любом случае, этой теме я собираюсь посвятить отдельную запись в этой серии.

А начнем мы с того, что нового нам несет ASDF 2, релиз которого состоялся 31 мая, и который уже скоро войдет в вашу любимую Лисп реализацию.

Целая новая версия системы претерпела существенный рефакторинг и доработку силами Фарэ и Роберта Голдмана. С точки зрения пользователей она включает в себя следующие улучшения (разумеется, накопленные и отлаженные за посление ряд релизов):
  • версионность самой библиотеки, возможность обновления ASDF

  • добавление более простого пользовательского интерфейса

  • добавление нового способа конфигурации

  • сохранение FASL-файлов отдельно (в других директориях) от исходного кода

  • улучшение работы c путями и соответствующее расширение классов component и system

  • исправление некоторых багов


Вот lightning talk Роберта на встрече TwinCity лисперов, посвященный ASDF 2. Нужно заметить, что ценность этого релиза не только практическая, но и символическая, знаменующая переход проекта на новую стадию разработки: более структурированную и прогнозируемую.

Итак, кратко о новых фичах.

1. Возможность обновления ASDF.
Сейчас любой пользователь может воспользоваться самой новой версией ASDF, просто загрузив ее через (asdf:oos 'asdf:load-op 'asdf) (но не через require!) Подробнее об этом в мануале, который, также улучшается.

2. Более простой пользовательский интерфейс — это функции load-system, compile-system и test-system. Вроде бы как, тривиальное изменение, но избавляющее новичков от необхоимости думать, почему это операции load-op и т.п. являются объектами, а не функциями, и других схожих волнений. Это важно в борьбе с кажущейся сложностью ASDF. При этом методы на test-op, как и раньше — и это понятно — нужно описывать разработчикам систем.

3. Системный реестр (source-registry) — новый способ конфигурации :)
Именно таким является новый, и по замыслу авторов основной способ задания места расположения исходников систем у пользователя. В то же время старый вариант через *central-registry* остается полностью функциональным и поддерживаемым. Более того, он был дополнен проверкой на самую неприятную и, наверно, частую ошибку при использовании ASDF — отсутствие слеша в конце пути к директориям — теперь этой неразберихи больше не будет.

Что же такое системный реестр? Это набор конфигурационных файлов в предопределенной структуре директорий для каждого пользователя, смоделированных по принципу *.conf.d директорий в Unix. А также собственно DSL для конфигурации. Простой пример того, как это работает из мануала:
В директории ~/.config/common-lisp/ находится файл source-registry.conf со следующей конфигурацией:

(:source-registry
(:tree "/home/fare/cl/")
:inherit-configuration)

В данном случае поиск установленных систем производится рекурсивно в поддиректориях в /home/fare/cl/.


Однако это объяснение и пример далеко не исчерпывающи, поэтому лучше читать соответствующий раздел руководства и проверить все собственноручно.

Честно говоря, как по мне, то новый подход для индивидуального разработчика менее удобен, чем использование *central-registry*. Однако он лучше подойдет для средств автоматического конфигурирования (и, я думаю, что как раз опыт в рамках ITA, где используется много Lisp серверов приложений, послужил отправной точкой для разработки этого способа), а также для использования в пакетных менеджерах. И хорошо, что теперь есть альтернативы для каждого из случаев.

4. Cохранение FASL-файлов теперь происходит в компилятор-специфичных директориях, по умолчанию спрятанных в домашней диретории пользователя. Благодаря этому устраняются проблемы как конфликта прав в случае использования одних и тех же исходников библиотек разными пользователями, так и stale FASLs, которые возникают при апгрейде реализации (в частности для SBCL).

5. В общем, исправлены основные недочеты, которые присутствовали в ASDF при работе с путями в разных операционках, а в классы компонент и система добавлены слоты, указывающие абсолютное положение их в файловой системе. Также исправлены и некоторые другие баги, о чем можно почитать в Changelog'е.

Какие проблемы остались? Из существенных для меня — две: нечеткая семантика форсированных операций (параметр :force t), а также недостатки работы с версиями (этой теме будет посвящена отдельная запись, поэтому не буду касаться ее здесь).

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

В следующей записи — немного о внутренностях ASDF...




1 Мой алгоритм установки Lisp библиотеки:
- Загрузить tar.gz файл
- Развернуть в ~/lib/lisp/
- Создать символическую ссылку на ASD-файл в ~/.lisp/
- (И вариация для случая работы с разными версиями одного пакета): ссылка на ASD-файл основной версии в ~/.lisp/, а при необходимости использования альтернативной версии, скажем hunchentoot-0.15.7 вместо hunchentoot-1.1.0 (push "~/lib/lisp/hunchentoot-0.15.7/" asdf:*central-registry*) (аналог PATH).

5 comments:

turtle said...

Т.е., с ASDF2, такой пакет как ASDF Binary Locations уже станет не нужным?

Vsevolod Dyomkin said...

@turtle да

turtle said...

Кстати, давно хотел спросить. Где можно посмотреть пример автоматической сборки с автоматическим запуском тестов?

Vsevolod Dyomkin said...

@turtle
В смысле, чтобы в ASDF были тесты подвязаны на compile-op? Про это я напишу отдельно в шаблонах использования. Можно глянуть здесь и здесь для примера.

А если в смысле чего-то типа buildbot'а, то как раз берут тот же buildbot и используют — ему ж, по большому счету, все равно, что запускать (например в bknr что-то такое было).

turtle said...

Да, я имел в виду что-то buildbot'а. Хорошо, спасибо. Посмотрю на досуге.