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 循环。