29

我正在使用 Makefile。

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

谢谢!

4

4 回答 4

32

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

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

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

ZSH_RESULT:=$(shell zsh myscript.zsh)

这将在解析生成文件后立即执行脚本,并且在执行任何目标之前。如果您递归调用 makefile,它也会执行脚本。

于 2010-01-23T09:38:21.857 回答
10

只需将其作为其他目标之一的依赖项

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

zsh: 
   rule for running zsh script.

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

goal: zsh foo.exe
于 2010-01-23T08:37:26.710 回答
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

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

#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..."
于 2017-01-12T02:14:06.000 回答
3

There is a solution without modifying your existing Makefile (main difference with the accepted answer). Just create a makefile containing:

.PHONY: all

all:
    pre-script
    @$(MAKE) -f Makefile --no-print-directory $(MAKECMDGOALS) MAKE='$(MAKE) -f Makefile'
    post-script

$(MAKECMDGOALS): all ;

The only drawback is that the pre- and post- scripts will always be run, even if there is nothing else to do. But they will not be run if you invoke make with one of the --dry-run options (other difference with the accepted answer).

于 2018-10-10T09:25:32.640 回答