如何从 Makefile 调用 shell 脚本中的函数

How to invoke a function in a shell script from a Makefile

我有一个 Makefile,其中包含打印给定变量的目标:

print-%:
    @echo $*=$($*)

例如要打印变量 CURDIR 的值,我只需发出以下命令:

make print-CURDIR

结果如下:

CURDIR=/Users/j3d/Projects/myproject

现在我想创建一个 shell 脚本,其中包含一组可从任何 Makefile... 调用的常用函数...这是上面目标的修改版本:

print-%:
    . ./make-util printvar $@

这里是 make-util

#!/bin/sh

printvar()
{
    @echo $*=$(*)
}

最后,运行 上面的脚本...

j3d@j3ds-macbook-pro myproject % make print-CURDIR

...未产生预期结果:

. ./make-utils CURDIR

我应该如何调用脚本函数才能正确打印给定的变量?

你快到了:

由于您将函数名称作为第一个参数传递,因此您可以执行

#!/bin/sh
printvar()
{
  @echo $*=$(*)
}
""

执行功能。如果你想要更高的安全性(捕捉你错误地传递了一些危险的命令而不是函数名的情况),你可以做一个

[ "" = printvar ] && printvar
[ "" = other_function ] && other_function

相反。

如果你想处理你的脚本生成变量,你可以将它们作为附加参数传递:

func=
shift
[ "$func" = printvar ] && printvar "$@"
[ "$func" = other_function ] && other_function "$@"

您可以创建一套 make 配方(如果您使用的是 GNU make),您可以在多个 makefile 中包含和使用这些配方,但您必须使用 make语法,而不是 shell 语法,因为它们是 make 配方,即使配方在扩展后变成 shell 脚本。

您可以研究 GNU make define statement and eval and call 函数,了解在 GNU make 中创建用户定义函数的方法。例如,您可以编写这样的 makefile:

$ cat macros.mk
print-%:
        @echo $*=$($*)

然后在您的其他 makefile 中您可以使用:

include macros.mk

您会自动获得该规则。

这里有很多很多的可能性,但细节取决于你想做什么。