ifndef включает охрану в Gnu. Делает разрывы на вложенные условные выражения.
Я пытаюсь реализовать включение охранников в Gnu Make. В этом Makefile первое включение в порядке, а второе - с ошибкой.
ifndef INCLUDED
INCLUDED = 1
$(info Including)
define macro
ifneq ($(1),)
define inner_macro
macro content...
endef
else
define inner_macro
endef
endif
endef
endif
Тот же эффект может быть смоделирован путем явного INCLUDED = 1
до включения, например, в командной строке.
Gnu Make 4.1 под Gentoo говорит Makefile:14: *** missing separator. Stop.
в то время как Gnu Make 3.81 под Debian Wheezy говорит Makefile:14: *** extraneous `endef'. Stop.
, При первом включении они оба говорят:
Including
make: *** No targets. Stop.
Если я попробую $(eval $(call macro,whatever))
после первого включения он определяет inner_macro
как и ожидалось.
я использовал make INCLUDED=1
а также make
Команды соответственно, чтобы получить описанное поведение.
То же самое происходит, когда я очищаю окружение и отключаю встроенные правила и переменные: env -i make -rR INCLUDE=1
, Когда я использую -p
сбросить базу данных, без INCLUDED=1
, macro
определяется как и должно быть, но с INCLUDED=1
пустой inner_macro
определено. Это согласуется с обеими версиями Make. Это намекает мне на то, что когда условие ложно, Make разбирает Makefile по-другому и думает, что else
внутри macro
Определение принадлежит ifndef
, Другие типы условий ведут себя одинаково.
Если я уберу оба определения inner_macro
проблема уходит.
Я читаю страницы руководства info make conditional\ syntax
а также info make multi-line
(ранее defining
), но я не нашел здесь никаких предостережений и все еще думаю, что не делаю ничего плохого.
- Я прав с моими выводами?
- Это ошибка в Make или я вызываю неопределенное поведение?
- Как мне реализовать включить охранники в Gnu Make?
1 ответ
Это ошибка. Сообщите об этом в Саванне.
Что-то не так с отслеживанием вложенного define / endef внутри не принятого условия ifdef / ifndef. Если вы не используете вложенный define / endef, тогда это работает; например (очевидно, вы не сможете сделать это в вашей среде):
ifndef INCLUDED
INCLUDED = 1
$(info Including)
define macro
ifneq ($(1),)
inner_macro = macro content...
else
inner_macro =
endif
endef
endif