У меня есть серия (десятки) проектов, которые состоят из большого количества контента в репозиториях git. Каждый репозиторий имеет god-подмодуль общего инструментария. Инструментарий содержит библиотеки и скрипты, необходимые для обработки репозиториев контента и создания опубликованного результата. Все репозитории помещаются на хост, который запускает CI и публикует результаты. Идея состоит в том, чтобы сохранить повторяющийся код до абсолютного минимума и в основном содержать контент в репозиториях и полагаться, а инструментарий - все это вместе для каждого проекта.Сделать переполнение¹ или «Как преодолеть цель?»
Каждый проект имеет верхний Makefile уровня, как правило, имеет только пару строк, например:
STAGE = stage
include toolkit/Makefile
Переменная ступень имеет некоторую информацию о том, на каком этапе это это частности, в котором определить, какие форматы получить встроенные. Практически все остальное обрабатывается 600-строчным Makefile в наборе инструментов. Для построения некоторых выходных форматов может потребоваться длинная цепочка зависимостей: прецессия источника может инициировать целевое правило, но чтобы добраться до цели, может быть 8-10 промежуточных зависимостей, когда различные файлы генерируются до того, как конечная цель может быть сделал.
Я столкнулся с несколькими ситуациями, где хочу полностью заменить (не просто расширить) целевое правило только в одном проекте. Цель запускается в середине цепочки зависимостей, но я хочу сделать что-то совершенно другое для этого шага.
Я попытался просто заменить цель в верхнем Makefile уровня:
STAGE = stage
%-target.fmt:
commands
include toolkit/Makefile
Это специально документирован не быть поддержан, но заманчиво это работает когда-то время. Я попытался изменить порядок объявления пользовательской цели и включить, но это, похоже, не влияет на это. В случае, если это имеет значение, да, важно использовать шаблоны в целях.
Иногда полезно иметь make-файл, который в основном похож на другой файл makefile. Вы часто можете использовать директиву «include», чтобы включить ее в другую, и добавить больше целей или определений переменных. Однако для двух make-файлов недействительно давать разные рецепты для одной и той же цели.
Интересно, если я ставлю пользовательские функции в верхнем Makefile уровня ниже включаемый я могу переопределить функции из набора инструментов, такие, что $(call do_thing)
будет использовать мое переопределение:
STAGE = stage
include toolkit/Makefile
define do_thing
commands
endef
Однако же не делает похоже, верно для целей. Я знаю о two colon syntax, но я не хочу просто продлить существующую цель с большим количеством зависимостей. Я хочу полностью заменить цель другим способом создания одного и того же файла.
Я думал об использовании рекурсивных вызовов для создания as suggested in the documentation, но тогда среда, включающая вспомогательные функции, которые широко настраиваются в инструментальном файле Makefile, не будет доступна ни одному из объектов в Makefile верхнего уровня. Это будет показательный стоппер.
Есть ли какой-либо способ сделать исключение для меня? Может ли он быть принужден к переопределению целей? Я использую исключительно последние версии GNU-Make и не слишком озабочен переносимостью.В противном случае существует еще один концептуальный способ достижения тех же целей?
¹ Моему мозгу сегодня не хватает кофе. При попытке открыть переполнения стека, чтобы задать этот вопрос, я набранный makeoverflow.com
в моем браузере и был смущен, почему автозавершения не пинал в
Я получаю это правильно, ваш инструментарий также содержит правило '% -target.fmt' с некоторыми командами по умолчанию, которые вы хотите переопределить? – valir
@valir Да. Оба предпосылки и рецепт отличаются друг от друга, но имя правила одинаковое, и я хочу полностью переопределить тот из набора инструментов, который находится на верхнем уровне. – Caleb