1

I am trying to create a rule within a make file to read a git commit and append into the name of a binary, so far I am struggling with the fact that the variable that will hold the commit seems to be empty,

append_git_commit: $(preName)/FLASH.bin
    GIT_COMMIT=$(git log -1 --pretty=format:%h)
    echo "$(info GIT_COMMIT="$(GIT_COMMIT)")"

shows this

GIT_COMMIT=
echo ""

Why is this? I would expect that GIT_COMMIT holds my hash like GIT_COMMIT=62f9926a

And secondly, how would it be the rule to append this GIT_COMMIT content to my FLASH.bin so that the result is

FLASH_62f9926a.bin

Thanks

ndarkness
  • 1,011
  • 2
  • 16
  • 36

1 Answers1

1

There are multiple problems with your current Makefile.

GIT_COMMIT=$(git log -1 --pretty=format:%h)

Doesn't do what you expect it to do, because, it's a make variable expansion and not a command expansion in shell. For that it to be passed to the underlying shell, you'd have to escape the $:

GIT_COMMIT=$$(git log -1 --pretty=format:%h)

On the next line, the $(GIT_COMMIT) refers to GIT_COMMIT make variable and not a shell variable.

Which then runs into a problem that:

  • setting variable in shell executed from make does not set a make variables (also meaning info would have no access to what happened in the shell command above); that shell is a child process of make
  • and each line of the recipe runs in its own shell instance (so variables from one line are not visible on the next one)

If I understand what you are after, I would probably do it like this:

GIT_COMMIT := $(shell git log -1 --pretty=format:%h)

append_git_commit: $(preName)/$(GIT_COMMIT)_FLASH.bin

$(preName)/$(GIT_COMMIT)_FLASH.bin: $(preName)/FLASH.bin
        cp "$<" "$@"

Using a make variable and introducing an intermediate target, as long as there is not new revision and the $(preName)/FLASH.bin did not get updated, there is not need to do anything for append_git_commit either, because it now knows it needs to create $(preName)/$(GIT_COMMIT)_FLASH.bin from $(preName)/FLASH.bin and all details are know at the time Makefile is being evaluated.

Ondrej K.
  • 8,841
  • 11
  • 24
  • 39
  • I have another small question. In case I wanted to delete the previous binary within this rule, how could I make it? Meaning that if I had `FLASH_62f9926a.bin`, the commit changes and this rule creates a new image, let's call it `FLASH_62f9945b.bin`, how could I remove the old `FLASH_62f9926a.bin`? – ndarkness Apr 03 '20 at 06:56
  • If you've moved (your repo) on, you don't really know the name unless you've also saved a previous state (e.g. in a text file). So if not a problem (getting something you did not want), you can clean by deleting `FLASH_*.bin` (or even use 8 `?`s instead). Otherwise you'd need to introduce secondary target/product saving the filename and them remove what is saved there (and the file holding the information). – Ondrej K. Apr 03 '20 at 11:26
  • Do you mean deleting prior to call the rule? – ndarkness Apr 10 '20 at 09:39
  • I was thinking more in terms of implementing `clean` target (which you manually call when you want previous results wiped). – Ondrej K. Apr 10 '20 at 11:17