计算后替换Makefile变量中的字符



我有一个Makefile,用来构建Docker容器。我正在检测当前的git分支,然后将其用作构建的标记,但有些git分支可能包含斜杠,这对于Docker标记来说是无效字符。

我试图在Makefile中用"-"替换斜杠,但我需要首先检测git分支。这是我所拥有的一个非常简化的版本:

NAME = foo
BRANCH = `git rev-parse --abbrev-ref HEAD`
TAG = $(subst /,-,$(BRANCH))
build:
    docker build --tag=$(NAME):$(TAG) .

问题是,如果BRANCH在检测到git分支后最终被设置为"foo/bar",那么TAG也最终被设置成"foo/bbar"。然而,如果我明确地将BRANCH设置为"foo/bar"(而不是检测它),那么TAG将正确地设置为"foo-bar",这是一个有效的标记。

我对Makefiles还很陌生,但我的猜测是shell命令的评估太晚了,subst命令试图对shell命令本身进行替换,而不是对命令的结果进行替换。

我还尝试过使用":="进行即时评估(如果我正确理解文档):

BRANCH := `git rev-parse --abbrev-ref HEAD`

但无济于事。

有没有更好的方法来完成我正在尝试的操作,或者我不得不手动将分支名称传递给make命令?

Backtick是由shell展开的,而不是make。您的$(BRANCH) make变量的内容是一个包含反标记的文本字符串。您可以通过将$(info BRANCH := $(BRANCH))添加到您的makefile中来查看这一点。

因此,当您的$(subst)调用运行时,分支名称中的斜杠尚未显示,因此无法被替换。

在配方/外壳时间使用sed或替换参数展开进行替换,或者在make变量赋值中使用$(shell)让make执行git调用。

BRANCH = $(shell git rev-parse --abbrev-ref HEAD)

如果你在任何给定的配方中多次使用BRANCH,那么你可能想使用一个简单的扩展变量,并使用

BRANCH := $(shell git rev-parse --abbrev-ref HEAD)

但这将使make在make解析时运行CCD_ 14命令,而不管实际构建的任何东西是否需要它(但在正常分配的情况下,每次扩展CCD_ 16变量时,make都将运行git命令一次)。

最新更新