Makefiles, ifdef и вычисляемые переменные - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь сделать что-то, что, по-моему, невозможно сделать. У меня есть общая цель, которая может иметь несколько предварительных условий, например postbuild_% в этом примере

TARGET_NAMES = release.target.1.1 debug.target.1.1 release.target.2.4 debug.target.2.4
BUILD_TARGET := $(addprefix build_,$(TARGET_NAMES))    
.PHONY: $(BUILD_TARGET)
$(BUILD_TARGET): build_%: prebuild_% % postbuild_%

Я использую определение переменной (экспортируемой другим make-файлом, который вызывает файл с правилами) для каждой цели, чтобы определить определенное поведение компиляции. Поскольку каждое имя цели отличается (за исключением выпуска / отладки), я использую разные переменные для каждого. Например,

.PHONY: %.target.1.1
%.target.1.1:
ifndef NO_target.1.1
    [something specific for %.target.1.1]
else
    @echo nothing to do
endif

Теперь моя проблема в том, что даже в postbuild_% мне приходится повторять эту вещь, но рецепт всегда одинаков для каждой цели, поэтому я пытаюсь найти способ использовать вычисленный переменные для воссоздания переменной «NO _ $ *», чтобы не повторять весь рецепт, как это

POSTBUILD_TARGET := $(addprefix postbuild_,$(TARGET_NAMES))
.PHONY: $(POSTBUILD_TARGET)
$(POSTBUILD_TARGET): postbuild_%:
ifndef $(addprefix NO_,$(subst $(whitespace),.,$(wordlist 2,4,$(subst ., ,$*))))
    [...]
else
    @echo Skipping $@
endif

Что-то в этом явно не работает: что я делаю не так?

Спасибо за вашу помощь :)

1 Ответ

1 голос
/ 22 апреля 2020

Make сначала анализирует все make-файлы во внутренней структуре данных, а затем запускает правила. ifeq et c. оцениваются на первом этапе. Переменные Automati c не устанавливаются до второго шага.

Вы не можете использовать операторы препроцессора make, такие как ifeq, которые анализируются , так как make-файл читается в , для запроса автоматического c переменных, таких как $*, которые не установлены до тех пор, пока не будет запущен рецепт .

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

$(POSTBUILD_TARGET): postbuild_%:
        if [ -z '$(NO_$(subst $(whitespace),.,$(wordlist 2,4,$(subst ., ,$*))))' ]; then \
            [...]; \
        else \
            @echo Skipping $@; \
        fi
...