这个问题并不是make
. Make 在 shell 的上下文中执行命令,如果函数可用,shell 可以执行函数。
问题是当你启动一个新的 shell(或 shell 脚本,或 make 命令)时,Bash 不会自动转发来自调用环境的所有函数。
明确指定 shell 应该/bin/bash
确保 make 不会调用不同的 shell 解释器,这可能会影响函数处理。 有几种方法可以做到这一点。 在下面的示例中,我使用了特定于目标的方法。
例如,下面的 makefile 片段调用它被实现为 bash 函数的集合。nvm
警告:使用先前定义的函数意味着 makefile 取决于您的 shell 环境的(可能不受控制的)状态,因此应该明智地使用这种类型的解决方案。
方法 1:运行“交互式”shell
在此示例中,假定函数被定义为用户的 .bashrc 文件的一部分。在交互模式下运行 Bash(带有-i
)会导致 .bashrc 被处理到命令环境中。
mytarget1: SHELL:=/bin/bash -i
mytarget1:
nvm install 14 && npm version
方法二:按需导入函数
这种方法显式地获取定义感兴趣函数的脚本。
mytarget2:
. ~/.nvm/nvm.sh && nvm install 14 && npm version
为此,您可能更喜欢:
makefile 中的多行 bash 命令
方法三:运行makefile前导出函数
调用make
:export -f nvm ; make mytarget3
将函数导出到任何子命令。
mytarget3: SHELL:=/bin/bash
mytarget3:
nvm install 14 && npm version
注意:此示例无法完全运行,因为nvm
在内部,它依赖于大量子函数,这些子函数也需要导出。