1

I have a Makefile in which I need to pass an image name to another script but the issue is, Image Name has : and - in its line for eg: image.name-v1:latest. As per google make file having : in variable causes issue. How to resolve this issue in Makefile. Below is the sample code that I am trying in which IMAGE has image.name-v1:latest

IMAGE2 ?= ''
.PHONY: image
image:
    IMAGE2 := $(subst :,\:,$(IMAGE_R)) ## IMAGE_R is a run time variable for make target
    rr/image.sh $(IMAGE2)

Error:

IMAGE2 := docker-rs\:latest ## Test Image using Image Reference
/bin/sh: 1: IMAGE2: not found
Makefile:75: recipe for target 'image' failed
make: *** [image] Error 127

SHELL SCRIPT: image.sh

#!/bin/bash
set -ex
IMAGE="$1"
echo "Image:  $IMAGE"
Saurabh Arora
  • 377
  • 2
  • 4
  • 11
  • The reason you're getting this particular error is that `IMAGE2 := ...` is a makefile line, but you're putting it in a recipe by indenting it with a TAB after the `image:` target. All recipe lines are passed to the shell to be run. The shell can't "run" this make variable assignment. You need to keep the `IMAGE2 := ...` line _outside_ of the recipe, like you have done with the `IMAGE2 ?= ''` line. See how @code_fodder has written it below. – MadScientist Apr 13 '20 at 21:47
  • But this is a variable passed to image target so how can this be passed somewhere else? – Saurabh Arora Apr 14 '20 at 02:44
  • Sorry I don't understand the question. Other than advanced uses, all make variables declared in a makefile are global variables to they're available in all recipes. – MadScientist Apr 14 '20 at 04:18
  • Thanks this worked, just putting IMAGE2 outise of make recipe – Saurabh Arora Apr 14 '20 at 06:07

1 Answers1

1

You could try escaping the colon like this:

# Mock IMAGE with colon in name
IMAGE := test:123
# Create new variable adding an escapeing slash
IMAGE2 := $(subst :,\:,$(IMAGE))

# Use IMAGE2 from here on
$(info IMAGE $(IMAGE))
$(info IMAGE2 $(IMAGE2))

.PHONY: xyz-pp
xyz-pp: $(IMAGE2)

.PHONY: $(IMAGE2)
$(IMAGE2):
    @echo "1234" > $(IMAGE2)
    @ls
    @rr/image.sh $(IMAGE2)

I added a script in sub folder rr:

echo "------------- SCRIPT ----------"
echo PARAM: $1
echo $(find -name "$1")
echo "------------- SCRIPT ----------"

output:

> make
IMAGE test:123
IMAGE2 test\:123
makefile  rr  test:123
------------- SCRIPT ----------
PARAM: test:123
./test:123
------------- SCRIPT ----------

So here I just replace ":" with ":" into a variable IMAGE2 and then use that.

Note: I tested this by just echo'ing your command (since I don't have that file) and touch'ing IMAGE2 to create the file

code_fodder
  • 15,263
  • 17
  • 90
  • 167
  • This is causing another issue, image.sh is not able to find IMAGE2 – Saurabh Arora Apr 13 '20 at 18:43
  • @SaurabhArora this is not an issue of the makefile, it would be an issue in your script. It is not trivial to use filenames with colons. I have updated the answer to show that the filename is passed into the script successfully. The script runs and prints the parameter as expected. Also the find function finds the file as expected. Other bash / shell functions may have issues due to the colon in the filename - I would suggest that you test that out-side of the makefile (by just running the script stand-alone) and raise a separate question to resolve that. – code_fodder Apr 13 '20 at 21:17
  • This works, I just had to put IMAGE2 := $(subst :,\:,$(IMAGE_R)) outside the recipe as mentioned by @MadScientist, thanks for help!!! – Saurabh Arora Apr 14 '20 at 06:07
  • @SaurabhArora ...ummm, lol... when I said to ask a another question, I did not mean to change *this* question! - it would have been better to ask a new question. My answer now no longer answers the posted question - so it does not really make sense, please remember for next time - the idea is to keep the quality of the question and answers high so that people searching/reading them later can gain maximum benefit : ) – code_fodder Apr 14 '20 at 19:09