Open Mazdaywik opened 2 years ago
Идею всецело поддерживаю. Насчёт деталей реализации - пока не приходит в голову, чего не хватает, кроме одного. Если я собираю проект сразу двумя компиляторами (например, refc и лямбдой - я так делала с MSCP-A; или crefal-ом и refc), то как будет выглядеть результат?
Об этом я не подумал, спасибо.
Возможный вариант — переопределять опции в командной строке:
r5pm build +common.compiler=lambda
r5pm build +targets.trojan.compiler=refal-05
Надо ещё подумать — делать пакетный менеджер в этом репозитории или создать новый. GitHub позволяет перемещать заявки между репозиториями:
Я уже пробовал эту функцию, работает. Попробуй перейти по ссылке https://github.com/Mazdaywik/Refal-05/issues/27.
А конфликтов не будет, в случае если используется crefal и refc? Т.е. не появятся ли в одной директории перекрывающие друг друга rsl-файлы?
В самой первой версии инкрементной сборки не будет, всё будет пересобираться каждый раз заново. А в случае инкрементной сборки нужно будет обеспечить раздельное хранение промежуточных файлов (.rsl
,.rasl
, .cpp
) не только для разных компиляторов, но и для одного компилятора с разными флагами оптимизации.
А по поводу папки ‹имя-цели›.rsls
— я предполагаю, что она при каждой пересборке будет создаваться заново. А значит, последующая сборка с другим компилятором перетрёт предыдущую. Точно также, если попеременно собирать одну цель Рефалом-05 и Рефалом-5λ, ‹имя-цели›.exe
будет перезаписываться.
Если нужно обеспечить одновременную сборку разными компиляторами (например, для сравнения производительности), то можно сделать несколько целей:
[targets]
my-prog-refc = my-prog.ref
my-prog-crefal = my-prog.ref
my-prog-lambda = my-prog.ref
my-prog-lambda-opt = my-prog.ref
[targets.my-prog-refc]
compiler = refc
[targets.my-prog-crefal]
compiler = crefal
[targets.my-prog-lambda]
compiler = lambda
[targets.my-prog-lambda-opt]
compiler = lambda
lambda_flags = -ODPRS
Кстати, имя файла в папке bin/
может не совпадать с именем слева от =
в секции [targets]
:
[targets]
abcd = defg.ref
[targets.abcd]
name = my-cool-program.v1.exe
Мотивация
У других языков программирования есть свои пакетные менеджеры, а у Рефала нет. И мне обидно.
Кроме того, у меня есть несколько своих проектов на Рефале:
Пишутся и другие проекты на Рефале-5:
К каждому из них скрипт сборки и скрипт запуска пишутся индивидуально.
Между двумя моими проектами есть зависимость: Рефал-05 зависит от фреймворка. Также не исключена зависимость между фреймворком и Рефалом-5λ — не хочется синхронно поддерживать две библиотеки
LibraryEx
.Декомпилятор на выходе самостоятельно формирует .rsl-ки, но он выиграл бы, если бы для их формирования он использовал фреймворк (правда, он требует доделки для вставки комментариев в код).
Рефал-5λ содержит копию исходника декомпилятора, она подключена через хитрое слияние ветвей. Тоже было бы неплохо, если бы декомпилятор подключался бы как зависимость.
MSCP-A зависит от библиотеки
prefal
и для корректной работы вынужден её включать себе в репозиторий.prefal
доступен в интернете для загрузки:http://www.botik.ru/pub/local/scp/refal5/bin/prefal_180216.zip
Запуск программ на Рефале-5 не очень удобен: в командной строке
refgo
нужно явно перечислять все имена скомпилированных модулей, например так:https://github.com/TonitaN/MSCP-A/blob/bf4a5175549ff913c52a68f5270a3370d3bf9daa/mscpdo.bat#L1-L7
Компиляция неудобна тем, что нужно явным образом перечислять все файлы, т.к. обнаруживать зависимости между файлами
refc
не умеет.Про зависимости
В Рефале-5λ имеется утилита
rlmake
, которая умеет находить зависимые файлы в специальным образом размеченных исходниках. Она принимает в командной строке имя единственного файла, находит все файлы, связанные с ним и вызывает компиляторrlc
для сборки всех этих файлов.Разметка осуществляется комментариями
В
‹имени-файла›
расширение.ref
писать не обязательно. Файлы ищутся в т.н. путях поиска, которые явно указываются в командной строкеrlmake
, опция--ref5rsl
позволяет добавить к путям поиска также и содержимое переменной средыREF5RSL
.Имя метки
*$FROM
предполагает, что после этого комментария располагается список*$EXTERN
, содержащий имена функций, импортируемых из искомого модуля:Исторически комментарии
*$FROM
я использовал при раскрутке Модульного Рефала в 2007 году:С тех пор я уже привык использовать подобного рода комментарии, не только для утилиты
rlmake
, но и вообще.Другие программисты тоже используют подобные комментарии перед списками
$EXTERN
. Пример из MSCP-A:https://github.com/TonitaN/MSCP-A/blob/bf4a5175549ff913c52a68f5270a3370d3bf9daa/Drive.ref#L69-L88
Пример из SCP4 (версия
scp4_000925
, файлaccess.ref
):Черновик спецификации
Источник вдохновения
Источником вдохновения послужили пакетные менеджеры и системы сборки языков Go и Rust:
У языка Go была позаимствована децентрализованность, у Rust — выделение библиотечного крейта.
Зависимости
Предполагается, что на машине пользователя доступны команды
git
,wget
илиcurl
и какой-то разархиватор zip-файлов (unzip
на unix-подобных, для Windows разархиватор указывает пользователь в настройках), а также имеется какая-нибудь реализация Рефала-5 (сам Рефал-5, Рефал-5λ, Рефал-05 с компилятором Си).Структура проекта
Проект представляет собой папку, в которой имеются следующие файлы и каталоги:
bin/
— создаётся автоматически, в неё помещаются скомпилированные файлы,lib/
— создаёт пользователь, в неё помещаются компоненты (исходники*.ref
), которые можно повторно использовать,modules/
— создаётся автоматически, в неё скачиваются зависимости,src/
— создаёт пользователь, в неё помещаются исходники, которые повторно использоваться не должны, из них собираются целевые файлы,tmp/
— папка для временных файлов (создаётся автоматически),r5pm.prj
— ini-файл, описывающий текущий проект.Файл конфигурации
r5pm.prj
Файл имеет следующий формат:
Рабочий процесс
Доступны следующие команды:
r5pm fetch
— скачивает все зависимости в папкуmodules/
.r5pm build [цель…]
— собирает указанные цели. Если цели не указаны, собирает все цели.r5pm clean
— удаляет промежуточные скомпилированные файлы (*.rsl
для Рефала-5,*.c
для Рефала-05 и т.д.).r5pm distclean
— удаляет всё (папкиbin/
,modules/
,tmp/
).Если при скачивании зависимостей в скачанном репозитории/архиве в корне нашёлся файл
r5pm.prj
, извлекаются зависимости из него и скачиваются тоже и далее рекурсивно.Процесс сборки:
[targets]
указываются «корневые» имена исходных файлов (как правило, они содержат функциюGo
илиGO
).*$FROM
— имена файлов, указанные в них, назовём импортируемыми файлами или импортами (не нашёл более подходящего термина).Затем система сборки по очереди смотрит в папку
lib/
, во все папкиmodules/*/lib
у скачанных зависимостей (если явно не указана другая подпапка в опцииsubdir
) и в папкуsrc/
до тех пор, пока не найдёт импортируемый файл с соответствующим расширением, если его не указал пользователь явно в комментарии.Соответствующее расширение — это сначала расширение
.ref
, а затем расширение, зависящее от компилятора в опцииcompiler
:.rsl
дляrefc
илиcrefal
,.c
для Рефала-05 и т.д. Если файл уже скомпилирован (например, импортhello
нашёлся как файлhello.rsl
), то рядом с этим файлом ищется файл с расширением.imports
(например,hello.imports
), который тоже сканируется на предмет строчек*$FROM
(см. далее).*$FROM
.bin/
создаётся запускаемый модуль.Запускаемый модуль для компиляторов Рефал-05 и Рефал-5λ — исполнимый файл (хотя для Рефала-5λ может быть, например,
.dll
или.so
в зависимости отlambda_flags
), тут всё просто.Запускаемый модуль для Рефала-5 — это пара из скрипта ОС (.bat-файл на Windows
‹имя-цели›.cmd
и shell-скрипт для unix-подобных ОС‹имя-цели›
без расширения и с флагом исполнимости) и папки с rsl-ками‹имя-цели›.rsls
. Предполагается, что пользователь эти файл и папку будет копировать, перемещать и переименовывать синхронно. В папке‹имя-цели›.rsls
.rsl-ки будут лежать, переименованными вa.rsl
,b.rsl
, …,z.rsl
,a1.rsl
… Возможный вид скриптов запуска (не уверен на счёт экранирования скобок в Bash):Параметры
-l2000 -c300
берутся изrefgo_flags
в файле конфигурации.В проекте может отсутствовать папка
src/
, в этом случае проект может быть использован только как зависимость, ничего в папкеbin/
не создаётся. В проекте может отсутствовать папкаlib/
, в этом случае проект использовать как зависимость бессмысленно.Плагины
Предполагается, что поддержка отдельных компиляторов (значения опции
compiler
:refc
,crefal
,refal-05
,refal-5-lambda
) будет оформлена как плагины, т.е. не захардкожена напрямую в сам пакетный менеджер.Плагин будет представлять собой команду
r5pm-plugin-compiler-‹имя›
вродеr5pm-plugin-compiler-refal-05
. Пакетный менеджер будет вызывать соответствующую команду функциейSystem
, передавая ей необходимые опции — интерфейс взаимодействия нам пока не важен. Будут отдельные команды для запроса свойств (вроде расширений импортируемых файлов) и запуска сборки (передаётся файл, где перечислены исходные файлы + всякие опции).Предустановленными будут плагины для
refc
иcrefal
, плагины для Рефала-05 и Рефала-5λ будут устанавливаться вместе с соответствующими компиляторами.Судьба
rlmake
В перспективе этот сборщик должен заменить собой утилиту
rlmake
, последняя скукожится до плагина.@TonitaN, вопросы, предложения, замечания, комментарии?