Makefile:直接使用变量时如何获得与 $@ 相同的行为?

Makefile: how do I get the same behaiour as $@ when using a variable directly?

我使用的代码与 类似,其中包括:

TOPTARGETS := zip test clean

SUBDIRS := $(wildcard */.)

$(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS):
    $(MAKE) -C $@ $(MAKECMDGOALS)

这 运行s 无论哪个 make 命令(从 TOPTARGETS)传递到每个子目录,这就是我想要的。

但是我想要一个目标 deploy,它只有在设置了环境变量时才具有相同的行为。这是我尝试过的:

deploy:
ifdef GITLAB_CI
    @echo "GITLAB_CI variable is defined, running deploy on all subdirectories"
    $(MAKE) -C $(SUBDIRS) $(MAKECMDGOALS)

else
    @echo "snip"
endif

注意 $(MAKE) 行与 $(SUBDIRS) 行相同,只是 $@ 直接替换为 $(SUBDIRS)

所以逻辑是,当它 运行 在我的 CI 中时,它会 运行 在所有子目录上递归部署,但是当它在 运行 本地时,它不会't。问题是部署中的 $(SUBDIRS) 没有按预期运行。当我 运行 make deploy 在一个有 2 个子目录的目录中时:

> make deploy
GITLAB_CI variable is defined, running deploy on all subdirectories
/Library/Developer/CommandLineTools/usr/bin/make -C subdir1/. subdir2/. deploy
make[1]: *** No rule to make target `subdir2/.'.  Stop.
make: *** [deploy] Error 2

make clean相比(我的TOPTARGETS之一):

> make clean
/Library/Developer/CommandLineTools/usr/bin/make -C subdir1/. clean
/Library/Developer/CommandLineTools/usr/bin/make -C subdir2/. clean

因此,当使用 TOPTARGETS 时,$@ 似乎以一种不同的方式展开 $(SUBDIRS),这与我自己写同一行时用 $@ 替换为$(SUBDIRS)。有什么办法可以让我自己在 deploy 行中实现这种行为吗?或者我是否需要在该目标内的 $(SUBDIRS) 上编写自己的 for 循环?

您可以保留有效的方法并添加一个最小的 deploy 规则:

TOPTARGETS := zip test clean

SUBDIRS := $(wildcard */.)

$(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS):
    $(MAKE) -C $@ $(MAKECMDGOALS)

ifdef GITLAB_CI
deploy: $(SUBDIRS)
else
deploy:
    @echo "snip"
endif

或者,也许更简单:

TOPTARGETS := zip test clean
ifdef GITLAB_CI
TOPTARGETS += deploy
else
deploy:
    @echo "snip"
endif

SUBDIRS := $(wildcard */.)

$(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS):
    $(MAKE) -C $@ $(MAKECMDGOALS)