4

I am trying to set an env var which is git sha1 commit for a makefile target. I am setting a lot of env vars and only this fails with no such file or directory error. I am hell confused. Please help me pass this as env var to my makefile target. This is what I do in the beginning of my Makefile.

SHA1 := $(shell git log | head -1 | awk '{print $2}')
BUILD_STAMP := $(shell date +%s)
export SHA1
export BUILD_STAMP

And one of the makefile targets have like this.

target: dep-target
     env \
              VAR1=$(VAR1) \
              GIT_SHA1=$(SHA1) \
     my-command for the target

This fails with

env: a6d23d14b0fbb613e567cc647ebfe2808ce47af1: No such file or directory

Please help me set this as env var.

Medhamsh
  • 303
  • 1
  • 4
  • 8

2 Answers2

3
 VAR1=$(VAR1)
 GIT_SHA1=$(SHA1)

The round braces, parentheses, used with a $ just before them in this way will cause the text between the parentheses to be sent to Bash as a command line to try to execute.

Replace with curly braces instead, i.e. GIT_SHA1=${SHA1} and you will get the intended variable assignment instead.

Hannu
  • 8,740
  • 3
  • 21
  • 39
  • Are you sure? Make should do its variable replacement first (and it sees $() as a variable replacement) and THEN bash won't see any $() because Make replaced them first. – user253751 Dec 29 '16 at 02:27
  • I assume, based on "No such file of directory" that I am right. – Hannu Jan 02 '17 at 17:57
  • You might notice that A) the file or directory that wasn't found is called `a6d23d14b0fbb613e567cc647ebfe2808ce47af1`, not `SHA1`, and B) that the message was printed by `env`, not `bash`. – user253751 Jan 03 '17 at 06:35
  • I assume `SHA1 := $(shell git log | head -1 | awk '{print $2}')` sets the variable to that value, and the fact that env prints it implies for me that env was run via Bash ( or "system()" ). – Hannu Jan 03 '17 at 21:30
  • if `$(...)` meant "send this to bash as a command line to try to execute" then `$(SHA1)` would try to execute the command `SHA1` which would print an error saying the command `SHA1` was not found. What happens if you type `SHA1` in your terminal? – user253751 Jan 03 '17 at 23:32
1

I don't have enough rep to comment on @Hannu's wrong answer (curly and round parenthesis are equivalent in Make).

To debug this sort of thing, create a separate short Makefile and try things like this:

SHA1 := $(shell git log | head -1 | awk '{print $2}')
all:
        echo "$(SHA1)"

This shows what is happening is SHA1 gets assigned the entire first line of git log output, not just the SHA, and that includes spaces. The expanded env command would then have invalid syntax.

In this case, the dollar sign in the awk command needs to be doubled (print $$2) so that expands to a literal dollar sign and not as the empty variable $(2).

Curt
  • 366
  • 2
  • 6