我正在使用Makefiles。
然而,我想在执行任何目标之前执行一个命令(zsh脚本)。
我应该如何做?
谢谢!
然而,我想在执行任何目标之前执行一个命令(zsh脚本)。
我应该如何做?
谢谢!
有几种技术可以在目标构建之前执行代码。你应该选择哪一种,取决于你想要做什么,以及为什么要这样做。(zsh脚本是做什么的?为什么必须执行它?)
你可以像@John建议的那样,将zsh脚本放置在第一个依赖项中。然后,除非它实际上生成名为zsh
的文件,否则应将 zsh 目标标记为
.PHONY
。
另一种解决方案(至少在GNU make中)是作为变量赋值的一部分调用$(shell ...)
函数:
ZSH_RESULT:=$(shell zsh myscript.zsh)
当解析makefile时,这将立即执行脚本,并在执行任何目标之前执行。如果您递归调用makefile,则也将执行该脚本。
只需将其作为其他目标的依赖项即可。
foo.obj : zsh foo.c
rule for compileing foo.c
zsh:
rule for running zsh script.
或者,作为替代方案,让你的第一个目标依赖于它。
goal: zsh foo.exe
foo.c
没有更新也会强制重新构建foo.obj
。第二个解决方案的问题是,现在您无法使用多个目标调用您的makefile。 - Nate C-K使用MAKECMDGOALS和双冒号规则在makefiles中实现预处理和后处理的解决方案。
MAKECMDGOALS是命令行上列出的目标。
第一步是从命令行获取第一个和最后一个目标,或者如果没有列出任何目标,则使用默认目标。
ifneq ($(MAKECMDGOALS),)
FIRST_GOAL := $(word 1, $(MAKECMDGOALS))
LAST_GOAL := $(word $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
else
FIRST_GOAL := all
LAST_GOAL := all
endif
双冒号规则允许按顺序执行同一目标的多个配方。您需要将所有命令行目标更改为双冒号规则。
#Dummy rule to set the default
.PHONY: all
all ::
#Preprocessing
$(FIRST_GOAL) ::
echo "Starting make..."
all :: normal_prerequistes
normal_recipe
other_stuff
#Postprocessing
$(LAST_GOAL) ::
echo "All done..."
如果不修改现有的Makefile
,也有解决方案(与被接受的答案不同之处在于这一点)。只需创建一个包含以下内容的makefile
:
.PHONY: all
all:
pre-script
@$(MAKE) -f Makefile --no-print-directory $(MAKECMDGOALS) MAKE='$(MAKE) -f Makefile'
post-script
$(MAKECMDGOALS): all ;
--dry-run
选项调用make,它们将不会被运行(与已接受答案的区别)。.PHONY: all
和 all: version
,其中“version”打印库版本。它不会在其他目标(如help
)上执行。 - WestCoastProjects
$(shell ...)
也会运行。 - thejoshwolfesudo
被调用。 - 170730350>&2
。不确定它是否会使sudo
生效,因为你需要 stdin。 - HectorJ