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), но я не нашел здесь никаких предостережений и все еще думаю, что не делаю ничего плохого.

  1. Я прав с моими выводами?
  2. Это ошибка в Make или я вызываю неопределенное поведение?
  3. Как мне реализовать включить охранники в 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
Другие вопросы по тегам