I have the following problem: I have a makefile that compiles a C Project and generates a .hex file. I am using Git for the source files Unfortunately the makefile generates an app.hex file, so I would like to add in the makefile a new clause that will generate a hex file with the name containing the short hash of the current commit that I am compiling. I am working under Windows. I already added the following in the Makefile:
tag : prebuild postbuild addtag
addtag : $(BUILD_SDIR)/$(BINARY).hex
@echo ----------------------------------------
@echo Getting Git tag
@echo ----------------------------------------
@echo GIT_TAG = call ./getGitTag.sh
@echo ----------------------------------------
@echo Adding GIT tag to hex file
@echo ----------------------------------------
@echo cp $(BUILD_DIR)\$(BINARY).hex $(BUILD_DIR)\$(BINARY)$(GIT_TAG).hex
with getGitTag.sh as below:
git rev-parse HEAD | cut -c 1-8
Unfortunately this doesn't work and I don't know why, my knowledge is quite basic so I have no idea how to debug this. GIT TAG seems to be always empty even if the .sh script works if I am calling it This is the output I am getting when running make tag in the cmd line:
----------------------------------------
Getting Git tag
----------------------------------------
GIT_TAG = call ./getGitTag.sh
----------------------------------------
Adding GIT tag to hex file
----------------------------------------
cp .\build\app.hex .\build\app.hex
CodePudding user response:
This problem pops up regularly with make
. Recipe lines are executed line by line, each in a separate shell process, which means that you can't simply instantiate shell variables and use them a few lines down, as they are disposed with the shell process immediately at line end. You have two options, #1 is to switch this feature off with the .ONESHELL:
pseudo command - this may have ramification (if not to say problems) for parts of the makefiles which don't come from you personally - or #2: to concatenate the recipe lines with a backslash; thus the shell receives one long line of commands but this can become quite involved for complex scripts.
There is another option circumventing make
, which is to handle everything in a true separate shell script which you call in the recipe line.
As a not so clean method one can introduce a make
variable during recipe execution:
$(eval GIT_TAG := $(shell git rev-parse --short HEAD))
@echo ----------------------------------------
@echo Git tag is: $(GIT_TAG), adding this to hex file now:
cp $(BUILD_DIR)\$(BINARY).hex $(BUILD_DIR)\$(BINARY)$(GIT_TAG).hex
@echo ----------------------------------------
Consider this a workaround tho, for the obvious ad-hoc nature of the code - usually you should not split functionality in half between make
and the shell this way.