我正在使用Makefiles。
但是,有一个命令(zsh脚本)我想在执行任何目标之前执行。 我该怎么做?
谢谢!
答案 0 :(得分:21)
在构建目标之前,有几种技术可以执行代码。你应该选择哪一个取决于你想要做什么,以及为什么要这样做。 (zsh脚本有什么作用?为什么必须执行它?)
你可以这样做@John建议;将zsh脚本作为第一个依赖项。然后,您应该将zsh
目标标记为.PHONY
,除非它实际生成名为zsh
的文件。
另一个解决方案(至少在GNU make中)是调用$(shell ...)
函数作为变量赋值的一部分:
ZSH_RESULT:=$(shell zsh myscript.zsh)
这将在解析makefile后立即执行脚本,并在执行任何目标之前执行。如果以递归方式调用makefile,它也会执行脚本。
答案 1 :(得分:9)
让它成为其他目标之一的依赖
foo.obj : zsh foo.c
rule for compileing foo.c
zsh:
rule for running zsh script.
或者,让你的第一个目标依赖它
goal: zsh foo.exe
答案 2 :(得分:2)
使用MAKECMDGOALS和双冒号规则在makefile中进行预处理和后处理的解决方案。
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..."
答案 3 :(得分:0)
有一个解决方案,无需修改您现有的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,则它们将不会运行。