Использование подстановочного знака с ifneq в файле Makefile

#bash #makefile

Вопрос:

Вот фрагмент моего файла создания:

 MY_CONFIG ?= .config.yaml
...
.PHONY: %/foo
%/foo: %/bar.yaml
ifneq ($(wildcard $*/$(MY_CONFIG)),)
    $(info **FOUND CONFIG FILE** )
else
    $(info **DIDNT FIND CONFIG FILE** )
endif
 

Я называю эту цель такой make myfolder/foo bar.yaml , и в .config.yaml этом myfolder каталоге есть файлы и. Однако этот ifneq, похоже, не работает, и он всегда печатается DIDN'T FIND CONFIG FILE , поэтому мне интересно, как я могу исправить свое состояние ( wildcard ?), ifneq чтобы он нашел файл конфигурации.

Структура файла:

 -- Makefile
-- myfolder
---- bar.yaml
---- .config.yaml
 

Комментарии:

1. Обратите внимание, что вы не можете давать шаблоны .PHONY . В заявлении .PHONY: %/foo говорится, что буквальное имя %/foo файла является фальшивым, что, вероятно, не то, что вам нужно.

Ответ №1:

Проблема в том, что такого рода заявления:

 ifneq (...)
  $(info ... )
else
  $(info ... )
endif
 

находится в синтаксисе Make. На самом деле это не является частью правила. Make оценит его перед выполнением любого правила. В этом случае:

 ifneq ($(wildcard $*/$(MY_CONFIG)),)
  ...
 

прежде чем Make сопоставит правило шаблона с чем-либо, $* не имеет значения и расширяется до нуля, поэтому, если у вас нет файла конфигурации в корневом каталоге, поиск всегда будет отрицательным.

Есть несколько способов получить желаемый результат. Самое простое, вероятно, состоит в том, чтобы разделить правило на два правила:

 .PHONY: %/foo
%/foo: %/bar.yaml %/$(MY_CONFIG)
    @echo **FOUND CONFIG FILE**

%/foo: %/bar.yaml
    @echo **DIDNT FIND CONFIG FILE**
 

В качестве альтернативы вы можете поместить условие оболочки внутри правила в синтаксис используемой оболочки.