我想定义一个shell函数
#!/bin/sh
test ()
{
do_some_complicated_tests $1 $2;
if something; then
build_thisway $1 $2;
else
build_otherway $1 $2;
fi
}
这样我就可以在Makefile的每个规则中使用它,例如:
foo: bar
test foo baz
为了清楚起见,我希望shell函数成为Makefile的一部分。最优雅的方式是什么?如果你能做到这一点,而不需要递归地调用make,那就更好了。
- 背景:我的实际问题是
make -n
产生了一个非常长且不可读的输出。每个规则都使用几乎相同的不可读shell命令序列,并且有许多规则。上述解决方案将使make -n
的输出更有用。*
8条答案
按热度按时间hs1ihplo1#
这个解决方案不依赖于外部临时文件,也不强迫您修改
SHELL
变量。ifneq…endif
块检查命令行上的-n
标志,并将TESTTOOL
的扩展设置为: TESTTOOL
,这易于阅读且安全执行。最好的解决方案可能是将shell函数转换为实际的程序,如果这对您来说是一个选项。
kmpatx3s2#
由于这个问题被标记为
gnu-make
,你可能会对Beta的解决方案感到满意,但我认为最好的解决方案是1)将函数重命名为test
以外的任何东西(也避免像ls
和cd
这样的名称);为了便于讨论,我们假设您已将其重命名为foo
,2)只需编写一个名为foo
的脚本并从Makefile调用它。如果你真的想在Makefile中定义一个shell函数,只需为每个规则定义它:并不是说
foo
定义的每一行都必须有行延续,而且$
都被转义,以便传递给shell。fhity93d3#
我不认为这有资格作为“优雅”,但它似乎做你想要的:
运行此命令将产生:
使用
-n
运行它会产生:这依赖于这样一个事实,即在
define
和endef
之间定义的宏在实际使用之前根本不会被make
解释,因此您可以直接使用shell语法,并且不需要以反斜杠结束每一行。当然,如果你调用shell-functions
宏,它会爆炸。7eumitmz4#
为什么不在Makefile中使用.ONESHELL,并定义一个类似bash函数的Makefile函数:
测试结果:
sigwle7e5#
TL;DR:
在你的makefile中:
长回答
我已经在一个非make的上下文中用bash做了类似的事情,它在这里工作。
我在bash中声明了我的shell函数,然后用以下命令导出它们:
如果同一个shell作为子进程被调用,那么它们自然是可用的,在您的例子中,是从make调用的。
范例:
试用看看
这在环境中看起来如何?
因此,您的问题是如何从Makefile中设置环境变量。该模式似乎是BASH_Function-name**%%=(){function-body}
直接在make内
你觉得怎么样?试试这个makefile
试试看:
它在Makefile中有点丑,但在make -n中没有丑
ijnw1ujt6#
这里真的是贫民窟,不过无所谓了我使用zsh,但我相信有bash和sh的等价物。
生成文件:
.zshenv,与Makefile相同的目录:
ZDOTmap变量使zsh在当前目录中查找dotfiles。然后你只需要把你想要的东西放在
.zshenv
里。lc8prwob7#
有些东西告诉我,你最好过滤
make -n
的输出,但你问的是可能的:sy5wg1nm8#
并不是我提倡这种方法,但是对于Idelic's "elegant" answer,你可以使用这个trick只生成一次shell函数文件:
这样做的目的是,如果文件不存在,那么包含它,这将导致make运行与包含文件名匹配的目标,然后重新执行自己,然后跳过
include
,因为文件现在存在。这必须在默认规则之后,并且一旦创建,如果调用makefile更改,它将不会被重新创建。