【发布时间】:2023-03-10 16:42:01
【问题描述】:
我正在使用 Makefile。
但是,我想在执行任何目标之前执行一个命令(zsh 脚本)。 我该怎么做?
谢谢!
【问题讨论】:
我正在使用 Makefile。
但是,我想在执行任何目标之前执行一个命令(zsh 脚本)。 我该怎么做?
谢谢!
【问题讨论】:
有几种技术可以在构建目标之前执行代码。你应该选择哪一个在一定程度上取决于你想要做什么,以及你为什么要这样做。 (zsh脚本是做什么的?为什么一定要执行?)
您可以像@John 建议的那样做;将 zsh 脚本作为第一个依赖项。然后您应该将zsh 目标标记为.PHONY,除非它实际上生成了一个名为zsh 的文件。
另一个解决方案(至少在 GNU make 中)是调用 $(shell ...) 函数作为变量赋值的一部分:
ZSH_RESULT:=$(shell zsh myscript.zsh)
这将在解析生成文件后立即执行脚本,并且在执行 任何 目标之前。如果您递归调用 makefile,它也会执行脚本。
【讨论】:
$(shell ...) 即使在 make 被赋予 -n、--just-print、--dry-run、--recon 选项时也会运行。
sudo 时提示输入用户密码。
>&2。不确定它是否会让sudo 工作,因为你需要标准输入
只需将其作为其他目标之一的依赖项
foo.obj : zsh foo.c
rule for compileing foo.c
zsh:
rule for running zsh script.
或者,让你的第一个目标依赖它
goal: zsh foo.exe
【讨论】:
foo.obj重建,即使foo.c没有更新。第二个问题是现在你不能用多个目标调用你的makefile。
使用 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..."
【讨论】:
有一个解决方案无需修改您现有的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,它们将不会运行(与已接受答案的其他区别)。
【讨论】: