I have a makefile with the following script:
build:
DOCKER_BUILDKIT=1 docker build --build-arg GITHUB_ACTOR=${GITHUB_ACTOR} --build-arg GITHUB_TOKEN=${GITHUB_TOKEN} -t ${DOCKER_REGISTRY}/strick:${IMAGE_BRANCH}-${IMAGE_TAG} -t ${DOCKER_REGISTRY}/strick:${IMAGE_BRANCH}-latest .
and I just realized that when ${IMAGE_BRANCH]
has a slash in it, like feature/a-b-c
then the docker build step will fail. I’d like to create a new env var which replaces slashes in IMAGE_BRANCH
with dashes.
I tried several variants including the following
build:
CLEANED_IMAGE_BRANCH=$(echo ${IMAGE_BRANCH} | sed 's///-/g')
DOCKER_BUILDKIT=1 docker build --build-arg GITHUB_ACTOR=${GITHUB_ACTOR} --build-arg GITHUB_TOKEN=${GITHUB_TOKEN} -t ${DOCKER_REGISTRY}/strick:${CLEANED_IMAGE_BRANCH}-${IMAGE_TAG} -t ${DOCKER_REGISTRY}/strick:${CLEANED_IMAGE_BRANCH}-latest .
and they all seemed to fail because CLEANED_IMAGE_BRANCH
ends up being an empty string.
❮❮❮ DOCKER_REGISTRY=docker IMAGE_BRANCH="a/b" IMAGE_TAG="lol" make build
CLEANED_IMAGE_BRANCH=
DOCKER_BUILDKIT=1 docker build --build-arg GITHUB_ACTOR= --build-arg GITHUB_TOKEN= -t docker/strick:-lol -t docker/strick:-latest .
invalid argument "docker/strick:-lol" for "-t, --tag" flag: invalid reference format
See 'docker build --help'.
make: *** [build] Error 125
What’s the correct way to perform string substitution in a makefile script?
2
Answers
You could just use the
subst
function:If I run this
Makefile
:I get as output:
First, when you want to pass a
$
to the shell you have to escape it from make, because$
is special to make.Second, every logical line in the recipe is run in a separate shell so if you want shell variables set in one line to be visible in another line you have to connect them via backslash.
Of course using make functions is also a fine idea, as long as you’re willing to commit (or have already committed) to requiring GNU make.