首页 > 解决方案 > 如何定义生成文件条件并在多个构建规则中重用它?

问题描述

这可能是也可能不是Makefile Variable Assignment Executes Early

是否可以定义一个条件并在以后重用它?

MAIN_FILE_PATH := main

define copy_resulting_pdf=
if [[ -f "${MAIN_FILE_PATH}" ]] \
then \
    cp "${MAIN_FILE_PATH}" "${MAIN_FILE_PATH}.pdf"; \
else \
    $(error Error: The PDF ${MAIN_FILE_PATH} was not generated!); \
fi
endef

all:
    echo doing other things.
    $(copy_resulting_pdf)


other:
    echo doing more other things.
    $(copy_resulting_pdf)

运行它时,make 甚至不会开始构建all规则。它只是抛出:

Makefile:14: *** Error: The PDF main was not generated!.  Stop.

标签: makefileevalvariable-assignmentgnu-make

解决方案


您的代码的问题在于这$(error ...)也是文本替换。因此,任何 的扩展$(copy_resulting_pdf)也会导致所有嵌入变量和函数的递归扩展,包括$(error ...). 通常,$(error ...)由 make 条件(例如ifeq)或其他替换(例如$(if ...))保护。但在你的情况下,它是由 shell 条件“保护”的,这意味着没有什么可做的。

但以下工作正如预期的那样:

MAIN_FILE_PATH := main

define copy_resulting_pdf
    echo Printing results...
    if [[ -f "${MAIN_FILE_PATH}" ]]; then \
        printf 'Copying PDF...\n'; \
        cp "${MAIN_FILE_PATH}" "${MAIN_FILE_PATH}.pdf"; \
    else \
        printf "Error: The PDF \"${MAIN_FILE_PATH}\" was not generated!\n"; \
        exit 1; \
    fi
endef

.PHONY: all other
all:
    @echo doing other things.
    @$(copy_resulting_pdf)

other:
    @echo doing more other things.
    @$(copy_resulting_pdf)

注意:这里不需要 eval 和一些花哨的转义。


推荐阅读