Как заставить GNU Make исполнить файл многократно с разными аргументами
Рецепт был опубликован 16 апреля 2016 года в 14:40, а менялся 16 апреля 2016 года в 14:40.
Постоянная ссылка: http://www.nixp.ru/recipes/67.html
В современных публикациях все чаще можно слышать о недостатках утилиты Make. Например, в статье Qt Build System: спасательный круг для сборки приводятся мнения двух экспертов, первым из которых выступает Peter Miller с критикой рекурсивных возможностей Make. Разумеется, обоснованная критика необходима, иначе мы не сможем двигаться дальше. Но все-таки хочется заступиться за старую-добрую утилиту Make. Тем более, что данная утилита используется в миллионах проектов и ее рано сбрасывать со счетов. Надо просто помнить, что по сути Make является простой программой, связывающей цели пользователя с действиями, которые необходимо осуществить для достижения этих самых целей. Нельзя требовать от программы того, что она не может делать в принципе, а именно — исправлять ошибки пользователя. Она может лишь пожаловаться на то, что ее заставляют делать неприличные вещи.
Хотелось бы представить одну из возможностей, которую предоставляет GNU Make. Предположим, что нам необходимо собрать программу или отчуждаемый пакет для работы на трех устройствах с именами ci20, bt01 и dm64. Первые два устройства: ci20 и bt01 — основаны на архитектуре MIPS, а третье устройство, dm64, построено на базе процессора ARM. Toolchain-ы для простоты назовем mips и arm, соответственно.
Сценарий сборки исходной программы одинаков для всех трех устройств и написан на языке GNU Make.
Если представить все комбинации вызовов команды Make, необходимые для сборки программы на наши устройства, получим:
$ TOOLCHAIN=mips HARDWARE=ci20 make $ TOOLCHAIN=mips HARDWARE=bt01 make $ TOOLCHAIN=arm HARDWARE=dm64 make
или, при передаче имен устройств и Toolchain-ов в качестве аргументов:
$ make TOOLCHAIN=mips HARDWARE=ci20 $ make TOOLCHAIN=mips HARDWARE=bt01 $ make TOOLCHAIN=arm HARDWARE=dm64
Таким образом, система сборки должна принимать пары TOOLCHAIN — HARDWARE, которые определяют, какой именно Toolchain необходимо использовать для того или иного устройства.
Рассмотрим теперь, как на уровне системы сборки организовать последовательность вызовов утилиты Make для нашего сценария таким образом, чтобы пользователь мог осуществить данные действия с помощью лишь одного вызова:
$ make
… без задания дополнительных аргументов, отвечающих за выбор целевого устройства и связанного с ним Toolchain-а.
Если включить в начало нашего сценария список допустимых целевых устройств, например, следующим образом:
COMPONENT_TARGETS = $(HARDWARE_CI20) COMPONENT_TARGETS += $(HARDWARE_BT01) COMPONENT_TARGETS += $(HARDWARE_DM64)
… то система сборки сможет автоматически построить список возможных для данного сценария комбинаций TOOLCHAIN — HARDWARE, который будет выглядеть, например, следующим образом:
targets = target_mips_ci20 target_mips_bt01 target_arm_dm64
Имея такой список, система сборки может восстановить аргументы, которые необходимо передавать при каждом вызове утилиты Make для нашего сценария. Сделать это нетрудно — на языке GNU Make эти действия можно описать так:
target_%: TOOLCHAIN = $(shell echo $(word 2, $(subst _, , $@))) target_%: HARDWARE = $(shell echo $(word 3, $(subst _, , $@))) target_%: $(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE)
Таким образом, при вызове команды Make без аргументов переменные TOOLCHAIN и HARDWARE будут не определены и в этом случае система сборки займется созданием списка targets из числа допустимых комбинаций. Когда же список будет составлен, система сборки сможет осуществить вызов:
$(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE)
… с действительными аргументами.
Когда же при очередном вызове система убедится в том, что переменные TOOLCHAIN и HARDWARE определены, управление будет передано нашему сценарию без дополнительных вычислений.
Разумеется, приведенный здесь код не полон, но отражает фундаментальный принцип и при использовании условных операторов может быть доведен до рабочего.
Описанный здесь механизм напрямую вытекает из возможностей утилиты Make, а работающий код можно детально рассмотреть в исходном тексте системы сборки Radix.pro.
- Из той же серии:
- Как работать с кассетами из консоли?
- Как работать с кассетными библиотеками из консоли?
- Сборка и установка ccminer в Linux (Ubuntu 16.04 и 17.04) из исходников GitHub
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1