makefile 中单个逻辑行中的 Define 关键字内的 Switch-case 块

makefile 中单个逻辑行中的 Define 关键字内的 Switch-case 块

ghc.mk这是来自Haskell 源编译的一部分的代码摘录。我发现它有所不同,因为作者选择将一个功能块写在一行中。这是编写 makefile 的常见做法吗?

我喜欢echo在每个 case 句柄中放入语句进行调试,但在当前设置下,我无法将 echo 语句解释为 shell 命令。

define installLibsTo
        $(call INSTALL_DIR,$2)
        for i in $1; do \
                case $$i in \
                  *.a) \
                    $(call INSTALL_DATA,$(INSTALL_OPTS),$$i,$2); \
                    $(RANLIB_CMD) $2/`basename $$i` ;; \
                  *.dll) \
                    $(call INSTALL_PROGRAM,$(INSTALL_OPTS),$$i,$2) ; \
                    $(STRIP_CMD) $2/`basename $$i` ;; \
                  *) \
                  $(call INSTALL_DATA,$(INSTALL_OPTS),$$i,$2); \
                  esac; \
    done
endef

答案1

整个 shell 命令位于单个逻辑行上,因为 makefile 的语法要求这样做。在 makefile 规则中,每个配方行都在单独的 shell 实例中执行。在解析器到达此点之前,反斜杠换行序列将被删除,因此紧随其后的反斜杠换行符不会被视为换行符。这意味着你可以这样写(我用8个空格代表一个制表符):

target:
        for x in $^; do \
          somecommand $$x; \
        done

并且将执行这样的 shell 命令来构建target

for x in dependency1 dependency2 dependency3; do           somecommand $x;         done

shell 在这里不会接收任何换行符(这就是为什么;before 是必需的done)。

如果你写了这个 makefile:

target:
        for x in $^; do
          somecommand $$x;
        done

那么每个for x in …; do,somecommand $x;done都会在一个单独的 shell 中执行,这是行不通的。

您显示的变量installLibsTo是具有相同约束的更大示例。使用时,它将扩展为两行逻辑配方行,一行执行通过调用函数构造的命令INSTALL_DIR,另一行执行 for 循环。

相关内容