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)
我使用的代码与 类似,其中包括:
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)