在 gmake $(shell) 函数中转义 #

Escaping # in gmake $(shell) function

我有一个环境变量 GITHUB_REFS,我想对其执行一些 bashism 并将结果捕获到 GNU makefile 的另一个变量 GITHUB_BRANCH 中。我天真的方法是这样的:

SHELL:=/bin/bash
GITHUB_BRANCH:=$(shell echo "${GITHUB_REF#refs/heads/}")

如果我 运行 bashism 本身,它工作正常但是当 运行 上面的 makefile 失败时:

Makefile:2: *** unterminated call to function 'shell': missing ')'.  Stop.

我尝试将 # 转义为 \#,因为它可能是罪魁祸首,而且 Makefile 确实可以工作,但 bashism 却没有。双重转义它再次给出相同的错误。

那么我怎样才能做到这一点?

#可以用\转义,但是你也忘了转义$

这个 Makefile 有效:

SHELL:=/bin/bash

foo := $(shell echo "$${SHELL\#/bin/}")

all:
    echo $(foo)

您还需要将美元符号加倍以将其传递给 shell。

GITHUB_BRANCH:=$(shell echo "$${GITHUB_REF\#refs/heads/}")

就其价值而言,这个简单的参数扩展可移植到任何相当现代的 sh,因此根本不是独有的 Bash 功能。

当然,make 完全可以执行相同的替换,而无需调用外部进程。

GITHUB_BRANCH := $(patsubst refs/heads/%,%,${GITHUB_REF})

请注意,这(需要转义 #)是一个错误,将在即将发布的 GNU make 版本中修复。如果你想让你的 makefile 是可移植的 before/after 错误已修复,你应该将它隐藏在这样的变量中:

HASH := \#

foo := $(shell echo "${GITHUB_REF$(HASH)refs/heads/}")

这适用于所有版本的 GNU make。