Как я могу игнорировать назначение переменной командной строки в рекурсивной сборке?

Я пытаюсь склеить две системы сборки вместе. Оба являются рекурсивными (правила в make-файле используют make для вызова других make-файлов для сборки компонентов проекта).

Я назову их «A» и «B», где «A» создает приложение, а «B» создает библиотеки, используемые «A».

Makefile верхнего уровня в A вызывает make TARGET=whatever, что означает, что все рекурсивно вызываемые биты сборки наследуют значение TARGET как переменной только для чтения, включая систему сборки из B, которая вызывается как часть рекурсивная сборка.

Я не хочу, чтобы это произошло в системе сборки для «B» (которые происходят из другого проекта), поскольку make-файлы там используют TARGET для своих собственных целей, и сборка завершается ошибкой, поскольку TARGET имеет неправильное значение и доступен только для чтения.

Я вижу только два решения этой проблемы, ни одно из которых не приемлемо;

1) Переименуйте TARGET во что-то другое в make-файле в A, который его устанавливает, и в make-файлах в A, которые его используют, чтобы избежать конфликта с более низкими уровнями системы сборки.

2) Используйте директиву override везде в make-файлах в B, где установлена ​​переменная TARGET, чтобы переопределить ее статус только для чтения.

У кого-нибудь есть идеи получше? - в идеале я хочу, чтобы ничего не наследовалось системой сборки B от системы A, кроме тех опций, которые я явно передаю системе сборки B от A.

Кстати, я использую GNU Make v3.80.


person John Skilleter    schedule 01.06.2009    source источник
comment
Если вы не хотите устанавливать TARGET в make-файле B, то почему вы передаете TARGET=whatever в make-файле A?   -  person JesperE    schedule 01.06.2009
comment
Makefile верхнего уровня A передает TARGET=whatever в makefile второго уровня в A (который нуждается в этом), а makefile второго уровня в A затем вызывает makefile B, который наследует TARGET как переменную только для чтения из среды второго уровня. -уровень делать.   -  person John Skilleter    schedule 01.06.2009


Ответы (4)


Вы можете установить MAKEOVERRIDES в make-файле второго уровня в A.

callb:
      cd subdir && $(MAKE) MAKEOVERRIDES=

При этом передаются обычные параметры командной строки, такие как -k и -s, но не определения переменных командной строки.

Или вы используете исторический MFLAGS, который аналогичен MAKEFLAGS, за исключением того, что MFLAGS не содержит определений переменных командной строки.

callb:
     cd subdir && $(MAKE) $(MFLAGS)

Подробнее об этих двух параметрах можно прочитать здесь: Руководство по GNU Make

person Community    schedule 03.06.2009

Возможно, вы можете использовать директиву «unexport», чтобы предотвратить распространение TARGET в make-файл B?

person JesperE    schedule 01.06.2009
comment
К сожалению, директива unexport запрещает экспортировать только переменные, экспортированные с помощью export, — она не влияет на переменные, переданные в командной строке текущему процессу make или унаследованные из командной строки родительского make. Похоже, что установка значения через командную строку make делает его нерушимо доступным только для чтения для всех дочерних make. - person John Skilleter; 02.06.2009

В точке, где система сборки A вызывает систему сборки B, не используйте '${MAKE}' напрямую; вызвать сценарий оболочки, который вызывает систему сборки B (возможно, после очистки среды).

Чтобы добиться поведения, при котором команды выполняются с помощью «make -n», добавьте к командной строке в make-файле префикс «+» (аналогично префиксу строки «@» или «-»).

person Jonathan Leffler    schedule 03.06.2009

Похоже, вы изменили make-файл A, чтобы рекурсивно вызывать make-файл B, и, следовательно, ваша проблема. Почему бы вместо этого не ввести новый make-файл верхнего уровня, который рекурсивно вызывает make-файл B, а затем рекурсивно вызывает make-файл A? Например, комбинированный.mk:

all:
    $(MAKE) -f Makefile.B
    $(MAKE) -f Makefile.A

Таким образом, make-файл B ничего не наследует от make-файла A.

person Eric Melski    schedule 09.11.2011