Изменение схемы решения
Иметь четыре make-файла:
- Makefile
- app1.1.mak
- app1.2.mak
- appdummy.mak
Makefile app.dummy.mak
может быть пустым - символическая ссылка на / dev / null, если хотите. И app.1.1.mak, и app.1.2.mak не отличаются от своего текущего содержимого.
Основной make-файл немного меняется:
MAK_VER = dummy
include makefile$(MAK_VER).mak
dummy:
${MAKE} MAK_VER=$$(echo $(APP_VER) | sed -e 's/^\([0-9]*\.[0-9]*\).*$$/\1/') all
all: PROD
...as now...
Если вы введете make
, он прочитает (пустой) фиктивный make-файл, а затем попытается создать цель dummy
, потому что она появляется первой. Чтобы построить фиктивную цель, она снова запустится make
, с APP_VER=1.1
или APP_VER=1.2
в командной строке:
make APP_VER=1.1 all
Макросы, установленные в командной строке, не могут быть изменены в make-файле, поэтому это переопределяет строку в make-файле. Поэтому при втором вызове make
будет прочитан правильный make-файл для конкретной версии, а затем будет построен all
.
Эта техника имеет ограничения, наиболее заметно то, что очень трудно организовать, чтобы каждая цель рассматривалась таким образом. Есть способы обойти это, но обычно не стоит.
Проектная организация
Более серьезно, я думаю, вам нужно пересмотреть то, что вы делаете в целом. Предположительно, вы используете систему управления версиями (VCS) для управления исходным кодом. Кроме того, предположительно, есть некоторые (существенные) различия между исходным кодом версии 1.1 и 1.2. Таким образом, чтобы иметь возможность сделать сборку для версии 1.1, вы должны переключиться с ветки обслуживания версии 1.1 на ветку разработки версии 1.2 или что-то в этом роде. Итак, почему make-файл не имеет версии для 1.1 или 1.2? Если вы переключаетесь между версиями, вам нужно очистить все производные файлы (объектные файлы, библиотеки, исполняемые файлы и т. Д.), Которые могли быть созданы с неверным источником. Вы должны изменить исходный код. Так почему бы тоже не изменить make-файл?
Скрипт сборки для вызова make
Я также заметил, что, поскольку у вас есть переменная окружения APP_VER, управляющая вашим процессом, вы можете уладить проблему, потребовав стандартизированного 'make invoker', который сортирует значение APP_VER и правильно вызывает make
. Представьте, что скрипт называется build
:
#!/bin/sh
: ${APP_VER:=1.2.0.1} # Latest version is default
case $APP_VER in
[0-9].[0-9].*)
MAK_VER=`echo $APP_VER | sed -e 's/^\(...\).*/\1/'`
;;
*) echo "`basename $0 .sh`: APP_VER ($APP_VER) should start with two digits followed by dots" 1>&2;
exit 1;;
esac
exec make MAK_VER=$MAK_VER "$@"
Этот скрипт проверяет, что APP_VER установлен, давая соответствующее значение по умолчанию, если это не так. Затем он обрабатывает это значение для получения MAK_VER (или выдает ошибки, если оно неверно). Разумеется, вам нужно будет изменить этот тест после того, как вы достигнете версии 10, поскольку вы планируете добиться такого успеха, что со временем вы получите двузначные номера версий.
Учитывая правильную информацию о версии, теперь вы можете вызывать ваш make-файл с любыми аргументами командной строки.
Makefile может быть довольно простым:
MAK_VER = dummy
include app$(MAK_VER).mak
all: PROD
...as now...
Файл appdummy.mak теперь содержит правило:
error:
echo "You must invoke this makefile via the build script" 1>&2
exit 1
Он просто указывает правильный способ сделать сборку.
Обратите внимание, что вы можете избежать переменной среды APP_VER, если вы сохраните номер версии продукта в VCS в файле, а сценарий затем прочитает номер версии из файла. Сценарий может выполнять любые другие действия, гарантируя, что установлены правильные инструменты, установлены другие переменные среды и т. Д.