Tcl Policy
Введение
Tcl/Tk — простой, но мощный, высокоуровневый интерпретируемый динамический язык общего назначения. Он представлен в виде командного интерпретатора и оболочки (shell) tclsh, которая является обвязкой над библиотекой Tcl (libtcl), которая и реализует язык. Данное полиси предназначено помочь опакечивать программное обеспечение, написанное на нём. Программное обеспечение, написанное на нём, можно разделить на исполняемые программы и на расширения языка Tcl.
Исполняемые программы
Программы на Tcl должны использовать неверсионированное имя интерпретатора в строке шебанга:
#!/usr/bin/tclsh
Это предотвратит зависимости на версионированный интерпретатор, который может создать дополнительные проблемы при мажорном обновлении Tcl/Tk. Как правило, последующие версии Tcl/Tk достаточно совместимы с предыдущими.
Аналогично для программ на Tk:
#!/usr/bin/wish
В случае, когда приложению требуются возможности языка, реализованные в определённой версии, следует использовать механизм package require, например
#!/usr/bin/tclsh package require Tcl 8.6
Сборка расширений
Соглашения об именовании
Расширения Tcl/Tk, независимо от того, являются ли они самостоятельным программным обеспечением или частью другого, нужно упаковывать отдельно, имена их пакетов должны начинаться с tcl-. Например, если расширение называется foo, то имя пакета будет tcl-foo. Если название расширения начинается на tcl, например tclfoo, то исторически в названии пакета между подстрокой tcl и остальной частью названия пакета ставился дефис: tcl-foo, и, вероятно, стоит придерживаться такого способа именования пакетов.
Исключение: расширения, которые предоставляют одновременно и командную оболочку, например expect.
Схема установки и вспомогательные макросы
В сборочных зависимостях пакетов расширений Tcl/Tk должен присутствовать tcl-devel. Он вытягивает rpm-build-tcl, который предоставляет вспомогательные макросы, а также содержит скрипты автоматической генерации зависимостей.
В целях оптимизации времени запуска пути поиска расширений Tcl/Tk в Sisyphus отличаются от предполагаемых асптримом: архитектурно-зависимые расширения следует устанавливать по пути, определённом в макросе %_tcllibdir; архитектурно-независмые — по пути %_tcldatadir. Также архитектурно-независимые данные расширений следует устанавливать в %_tcldatadir.
Расширения, установленные по путям, предлагаемые апстримом, не смогут быть загружены библиотекой и интерпретатором Tcl, оформление пакетов таким образом считается ошибкой.
Для упрощения сборки в пакете rpm-build-tcl определён макрос %tea_patch, который патчит сборочные файлы TEA-совместимых расширений согласно данному полиси. В spec-файле это выглядит примерно так:
%prep %setup %tea_patch
Для сборки архитектурно-независимых расширений при использовании %tea_patch следует определить макрос _tea_noarch:
%global _tea_noarch 1
Для макроса %tea_patch реализовано несколько аргументов, например %tea_patch -C dir, подробнее можно почитать в реализации макроса в файле macros.d/tcl.
В некоторых пакетах для сборки расширений используется макрос %teapatch. Начиная с rpm-build-tcl-0.5.2-alt1 этот макрос считается устаревший и его не следует использовать: он использует предыдущую схему упаковки расширений, более сложную к сопровождению. Тем не менее стоит заметить, что предыдущая схема упаковки совместима с новой, и расширения, собранные старым способом, остаются работоспособными, а новая схема остаётся совместимой с tcl >= 8.6.7-alt2 (сентябрь 2017 года).
Использование stubs
Механизм Tcl stubs позволяет вместо того, чтобы напрямую связывать расширения с библиотекой Tcl, статически связывать расширения с объектным файлом libstubtcl$major.a, который содержит переменную для хранения таблицы функций Tcl и функцию Tcl_InitStubs для заполнения таблицы функций указателями на сами функции.
Расширения, которые могут быть собраны с механизмом Tcl stubs, обязаны быть собраны с использованием этого механизма (обратное следует считать ошибкой), при сборке следует определить макрос USE_TCL_STUBS. В качестве одного из преимущества (но не единственного) получаем, что расширение не зависит от версии Tcl, с которым собрано, и может использоваться Tcl другой версии, в том числе более старой (т.е., расширение, собранное для Tcl 8.6, будет работать без пересборки и с Tcl 8.7, и с Tcl 8.5).
Custom Tcl Shell
Некоторые расширения предоставляют командную оболочку (Custom Tcl Shell). В ALT сборка таких шеллов обычно подавляется: получение соответствующей функциональности следует производить посредством package require. Сборку Custom Tcl Shell не следует производить. Для некоторых пакетов сделано исключение, например для tk (wish) и expect.
Отключение автоматической генерации зависимостей и подавление зависимостей
Чтобы отключить автоматическую генерацию зависимостей Tcl, необходимо в Autoreq (AutoProv или AutoReqProv в зависимости от типа зависимости) прописать notcl.
В случае, когда надо подавить некую зависимость Tcl, напрмер foo, надо указать её в %add_tcl_req_skip:
%add_tcl_req_skip foo
devel-подпакеты
Некоторые расширения предоставляют разделяемые библиотеки для связывания, а также статические stub-библиотеки, которые не являются статическими библиотеками в обычном понимании, а stub'ом для непрямого указания на разделяемую библиотеку. В идеале их клиенты должны использовать механизм package require для доступа к функциональности расширения. Т.к. как правило апстримы клиентов так не делают, возможно, стоит для упрощения сопровождения разрешить линковаться с разделяемыми библиотеками расширений. В таком случае неверсионированный указатель на разделяемую библиотеку должен быть установлен в %_libdir и упакован вместе со всеми остальными "разработческими" файлами (включая stub-файл, если имеется) в devel-файл соответствующего пакета. Чтобы динамический загрузчик смог связать клиента библиотеки с самой библиотекой, путь, где лежит библиотека, стоит записать в %_sysconfdir/ld.so.conf.d/%name-%arch.conf, а этот файл упаковать в пакет расширения.
Немного истории
TBD.