Сотрудник Red Hat представил сборочную систему Goals. Выпуск GNU Make 4.2

Ричард Джонс (Richard WM Jones), автор libguestfs, работающий в компании Red Hat, объявил о начале работы над новой сборочной утилитой Goals, нацеленной на устранение недостатков и проблем в утилите make, при сохранении общей простоты и понятности сценариев. Утилита make проектировалась в 1976 году и имеет ряд концептуальных недоработок, в Goals планируется устранить эти недоработки не меняя общей концепции.

Решаемые проблемы:

  • Поддержка только одной тактики разрешения зависимостей — «сборочная инструкция запускается если целевой файл отсутствует или он старее одной из зависимостей». В Goals планируется реализовать и другие тактики, такие как проверка наличия URL, сравнение времени изменения с любым файлом, оценка сборки пакета в Koji, сравнение контрольных сумм, запуск тестовых наборов с выборочным пропуском тестов.
  • При обработке сборочных целей утилита make не разделяет файлы и имена правил, и, как следствие, отсутствует проверка того, что при запуске правила действительно будет создан файл, создание которого заявлено. Например, если при наличии правила с именем «test», запускающего скрипты с тестами, случайно будет создан файл с именем «test», то тесты перестанут вызываться, так как make посчитает, что цель собрана и не требует выполнения каких-либо действий (для обхода проблемы в make можно указать директиву «.PHONY: test»). Goals явно разделяет файлы и имена правил.
  • Проблема с предоставлением только одного параметра для сборочных инструкций.

    В Goals предлагается использовать произвольное число именованных параметров. Например, можно отдельно выделить из имени признак отладочного файла:

  • Завязка на shell-интерпретатор. Например, необходимость контролировать экранирование пробелов в именах файлов и каталогов, трата ресурсов на запуск отдельного shell-интерпретатора при выполнении каждой команды, двойная трактовка символа «$» (используется как в shell, так и в make), учёт отступов.

    Указанные проблемы решаются в Goals использованием символа «%» вместо «$» для сборочных переменных («$» остаётся только для shell), применением парсера LALR(1), требующего обрамлять пути и имена файлов кавычками и выделять фигурными скобками блоки с кодом. Весь блок команда запускается в одном экземпляре командной оболочки, а внутри блока допускается произвольное форматирование кода, без привязки к специальным пробелам.

      Было:      target: foo.o bar.o                    ${CC} ${CFLAGS} $

Другие особенности Goals:

  • Опциональная поддержка задания произвольных имён и параметров:
           goal all = : "target"         goal link =       "target" : "foo.o", "bar.o" { ... }         goal compile (name) =       "%name.o" : "%name.c", "dep.h" { %CC %CFLAGS -c $^ -o $@ }  
  • Два режима запуска: режим make для сопоставления сборочных целей с именами файлов (например, файл «foo.o» соответствует цели «%name.o»), и режим прямой компиляции:
           goal all = : link         goal link =       "target" : "foo.o", compile ("bar") { ... }         goal compile (name) =       "%name.o" : "%name.c", "dep.h" { %CC %CFLAGS -c $^ -o $@ }  
  • Тактика сборки определяется специальными правилами, при помощи которых можно определять необходимость пересборки сборочной цели. Если осуществляется привязка к наличию файла, то это явно определяется через соответствующий признак («target» для имени правила и *file(«target») для проверки файла).
        "target" : "foo.o", "bar.o" { ... }      *file("target") : *file("foo.o"), *file("bar.o") { ... }  
  • Разработчик может определять произвольные признаки сборочных тактик. Признак «*file» определён по умолчанию (@{…} указывает на подавление вывода, а «exit 99» сигнализирует о необходимости пересборки):
         tactic *file (filename) = @{        test -f %filename || exit 99        for f in %
  • Предлагается парсер сценариев на языке goals и runtime для выполнения языка, построения графа зависимостей и параллельного запуска работ. В состав входит стандартная библиотека вспомогательных функций, которые могут определяться на shell или с использованием специфичного синтаксиса сценариев goals. Функции могут вызываться как по имени, так и по шаблону (по аналогии с языком Пролог)
          function wildcard (wc) returning strings = @{          shopt -s nullglob          wc=%wc          for f in $wc; do echo "$f"; done      }  
  • Из планов на будущее упоминается поддержка типов, отличных от строк, возможность определения значений параметров по умолчанию и поддержка анонимных функций.
          goal build (project, bool release = true) = ...      build ("foo")      build ("foo", false)        let hello = { echo "hello" }        let f = function (name, version) { CODE }      f ("goals", "0.1")  

    Тем временем, после почти четырёх лет разработки состоялся релиз системы сборки GNU Make 4.3. Кроме исправления ошибок, в новой версии можно отметить следующие улучшения:

    • Применение символа «#» внутри макроподстановок или при вызове функций теперь не обрабатывается как комментарий и не требует экранирования (например, теперь нужно писать «foo := $(shell echo ‘#’)», а «foo := $(shell echo ‘#’)» будет приводить к выводу «#»).
    • Использование оператора ‘+=’ для добавления к пустой переменной теперь не приводит к подстановке начального пробела, так же как и прикрепление пустой строки вконец переменной не приводит к добавлению финального пробела.
    • Добавлена возможность явного определения правил, генерирующих несколько сборочных целей при одном вызове. Для использования данной возможности при определении сборочной цели вместо символа «:» в правилах следует использовать «&:»;
    • Реализована переменная «.EXTRA_PREREQS», через которую можно задать необходимые для цели дополнительные компоненты;
    • В Makefile теперь допускается выставление опции ‘-j’ в переменных MAKEFLAGS для запуска в параллельном режиме;
    • Добавлена возможность использования вызова posix_spawn() вместо fork/exec;
    • Применяемый в Windows лимит на 63 параллельные работы (включая субпроцессы, запускаемые через выражения «$(shell)») увеличен до 4095;
    • Добавлена опция «—no-silent», отменяющая действие флагов «-s», «—silent» и «—quiet»;
    • Добавлен сокращённый вариант опции «—eval» — «-E»;
    • Для всех операций раскрытия по маске, включая «$(wildcard …)», теперь применяется сортировка результата (для обеспечения предсказуемого на разных платформах поведения);
    • Добавлена поддержка новых версий Си-библиотек Glibc и musl;
    • Внесены оптимизации производительности;
    • Код перемещён из корня архива в каталог src/*.

    Источник: http://www.opennet.ru/opennews/art.shtml?num=52215