В asdf есть переменная *central-registry*, содержащая список директорий в которых ищутся asdf-системы. То есть, чтобы система была доступна
для загрузки, нужно чтобы путь к её asd-файлу был в *central-registry*.
Но систем много, и каждую прописывать в *central-registry* утомительно. Поэтому принято делать несколько иначе: прописывается путь к какой-то одной директории (например ~/.sbcl/systems/), а в эту директорию помещаются символические ссылки на asd-файлы.
Windows
Очевидно, что в windows нет ссылок и, казалось бы, такой вариант не подходит. Но, к счастью, asdf неплохо настраивается и можно это
ограничение обойти. Переменная *system-definition-search-functions* содержит список функций поиска asdf-систем.
Вот такая функция и код добавления её в asdf. Эта функция обходит все директории из *central-registry* и просматривает в них все lnk-файлы,
извлекает путь ссылки и сравнивает с именем искомой системы.
(defun search-for-system-in-windows (system) (let ((system-name (asdf::coerce-name system))) (dolist (dir asdf:*central-registry*) (dolist (lnk (directory (merge-pathnames (eval dir) "*.lnk"))) (let ((system-path (parse-windows-shortcut lnk))) (when (string-equal system-name (pathname-name system-path)) (return-from search-for-system-in-windows system-path))))))) (pushnew #'search-for-system-in-windows asdf:*system-definition-search-functions*)
Этот код был бы неполным без этого фрагмента http://paste.lisp.org/display/91121
Варианты
Очевидно, что можно сделать всё это ещё проще. Можно вместо lnk-файлов придумать, скажем, symlink-файлы -- простые текстовые файлы с путями внутри. Тогда чтение таких файлов будет тривиальным и кода будет поменьше.
Любители Windows могут сделать регистрацию и поиск asd-файлов даже в реестре. :)
Ну а так как функций поиска может быть несколько, то можно все эти способы сочетать.
Резюме
Остаётся добавить этот код в пользовательский файл инициализации, и можно пользоваться.
Для SBCL это будет $HOME/.sbclrc
для Clozure CL: $HOME/ccl-init.lisp
6 комментариев:
Э... Ты зачем так настроил фиды? ;)
Осталось теперь только asdf-install заломать, чтобы создавал правильно линки и высыпал системы куда надо.
Спасибо, Энди)
> Очевидно, что в windows нет ссылок
NTFS поддерживает ссылки - жесткие ссылки на файлы, символьные ссылки на директории, начиная с Windows Vista доступны символьные ссылки и на файлы.
спасибо за идею, очень в тему пришлось. правда необходимость была больше в относительных линках, желательно еще и приспособленных к жизни в репозитории, так что остановился на файлах *.asd.location c pathname внутри.
и еще небольшое уточнение: ccl читает %HOMEPATH%/ccl-init.lisp, по меньшей мере в 1.4 так. Точно знаю, потому что %HOME% у меня в другом месте.
Дмитрий Статывка
@tymmym
Всё так. Ссылки в NTFS есть. Но, дело не столько в их наличии, сколько в API. Смысл их использования в том, что asdf находит их в одном месте, но может получить truename. В NTFS же, так не получится, по крайней мере ни SBCL, ни CCL, ни Clisp не знают ничего об этих ссылках.
@Дмитрий Статывка
Ага, *.asd.location (я их назвал symlink-файлами) лучше.
У меня %HOME% тоже в другом месте, но CCL всё равно грузил из C:/Users/%username%. Странно всё это. А вот SBCL грузит как надо: из %HOME%/.sbclrc.
Отправить комментарий