我想要许多不同的 makefile,每个 docker compose profile 一个。这些 makefile 中的每一个都应该包含在根 makefile 中。
Makefile # includes the other makefiles
docker_compose_profile_makefiles/
profile_a.Makefile
profile_b.Makefile
...
我希望每个 makefile 都有许多目标,最终将使用该文件的适当导出值
COMPOSE_PROFILES
来调用 docker compose,无需在每个目标中重新指定相同的值。
如何让
profile_a.Makefile
中的所有目标使用导出变量 COMPOSE_PROFILES=profile_a
,以及 profile_b.Makefile
中的所有目标使用导出变量 COMPOSE_PROFILE=profile_b
?
我尝试过使用
export
顶级指令和 .EXPORT_ALL_VARIABLES
,似乎最后一个写入获胜......在所有 makefile 中。
Makefile
.PHONY: all
include docker_compose_profile_makefiles/*.Makefile
export COMPOSE_PROFILES := default
all:
echo env_var: $$COMPOSE_PROFILES
docker_compose_profile_makefiles/profile_a.Makefile
# profile_a.Makefile
export COMPOSE_PROFILES := profile_a
profile_a:
@echo "profile_a: COMPOSE_PROFILES is set to $(COMPOSE_PROFILES)"
docker_compose_profile_makefiles/profile_b.Makefile
# profile_b.Makefile
export COMPOSE_PROFILES := profile_b
profile_b:
@echo "profile_b: COMPOSE_PROFILES is set to $(COMPOSE_PROFILES)"
$> make make all
echo env_var: $COMPOSE_PROFILES
env_var: default
$> make profile_a
profile_a: COMPOSE_PROFILES is set to default
$> make profile_b
profile_b: COMPOSE_PROFILES is set to default
$> make make all
echo env_var: $COMPOSE_PROFILES
env_var: default
$> make profile_a
profile_a: COMPOSE_PROFILES is set to profile_a
$> make profile_b
profile_b: COMPOSE_PROFILES is set to profile_b
Make 的
include
只是文本替换。不涉及“范围界定”等。 include
之后的结果与用每个包含的 makefile 的完整文本替换 include
语句然后在结果上运行 make 相同,不多也不少。 make 中的变量默认是全局变量,因此如果您设置一个然后稍后重置它,则在展开配方时它将具有第二个值。
此外,您对“导出”感到困惑。它并不意味着“导出到包含的 makefile”。它的意思是,“当您运行 shell 来调用配方时,将此值放入 shell 的环境中”。它与你想要做的事情完全无关(并且,在任何 makefile 中添加
.EXPORT_ALL_VARIABLES
都是一个糟糕的主意,IMO,你不应该这样做)。您使用 export
并不重要,因为您的配置文件配方没有使用 shell 的环境来检索这些值(即使它们是相同的)。
您可以根据目标(例如)使变量的名称唯一并选择正确的变量,也可以使用特定于目标的变量。这些是 makefile 中唯一可用的“范围界定”类型。
作为使用特定于目标的变量的示例,您可以像这样编写 makefile:
.PHONY: all
include docker_compose_profile_makefiles/*.Makefile
COMPOSE_PROFILES := default
all:
echo value $(COMPOSE_PROFILES)
和:
# profile_a.Makefile
profile_a: COMPOSE_PROFILES := profile_a
profile_a:
@echo "profile_a: COMPOSE_PROFILES is set to $(COMPOSE_PROFILES)"
和:
# profile_b.Makefile
profile_b: COMPOSE_PROFILES := profile_b
profile_b:
@echo "profile_b: COMPOSE_PROFILES is set to $(COMPOSE_PROFILES)"
这组博客文章中对两者进行了更详细的描述(从最旧的一篇开始,并在您理解它们时继续前进):https://make.mad-scientist.net/category/metaprogramming/