强制Makefile在构建目标之前执行脚本

ano*_*non 22 makefile target

我正在使用Makefiles.

但是,在执行任何目标之前,我需要执行一个命令(zsh脚本).我该怎么做呢?

谢谢!

Jes*_*erE 25

在构建目标之前,有几种技术可以执行代码.你应该选择哪一个取决于你想要做什么,以及为什么要这样做.(zsh脚本有什么作用?为什么要执行它?)

你可以像@John建议的那样做; 将zsh脚本作为第一个依赖项.然后,您应该将zsh目标标记为.PHONY除非它实际生成一个名为的文件zsh.

另一个解决方案(至少在GNU make中)是$(shell ...)作为变量赋值的一部分调用函数:

ZSH_RESULT:=$(shell zsh myscript.zsh)
Run Code Online (Sandbox Code Playgroud)

这将在解析makefile后立即执行脚本,并在执行任何目标之前执行.如果以递归方式调用makefile,它也将执行该脚本.

  • 注意,即使make给出了-n, - just-print, - dr-run, - recon选项,`$(shell ...)`也会运行. (4认同)
  • 我喜欢这种方法。但是,myscript.zsh 的输出不会打印出来。我处于类似的情况,脚本会在调用 `sudo` 时提示输入用户密码。 (2认同)

Joh*_*ler 10

只需使其成为其他目标之一的依赖

foo.obj : zsh foo.c 
   rule for compileing foo.c

zsh: 
   rule for running zsh script.
Run Code Online (Sandbox Code Playgroud)

或者,让你的第一个目标依赖它

goal: zsh foo.exe
Run Code Online (Sandbox Code Playgroud)

  • 这里第一个解决方案的问题是它会强制每次都重建`foo.obj`,即使`foo.c`没有更新.第二个问题是现在你不能用多个目标调用你的makefile. (4认同)

小智 7

使用 MAKECMDGOALS 和双冒号规则在 makefile 中进行预处理和后处理的解决方案。

MAKECMDGOALS 是命令行上列出的目标。

第一步是从命令行获取第一个和最后一个目标,或者如果没有列出目标,则使用默认目标。

ifneq ($(MAKECMDGOALS),)
FIRST_GOAL := $(word 1, $(MAKECMDGOALS))
LAST_GOAL := $(word $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
else
FIRST_GOAL := all
LAST_GOAL := all
endif
Run Code Online (Sandbox Code Playgroud)

双冒号规则允许按顺序执行同一目标的多个配方。您必须将所有命令行目标更改为双冒号规则。

#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..."
Run Code Online (Sandbox Code Playgroud)