Reputation: 147
I want to create log files with time stamps. In my Makefile, I get the date as following:
DATE = $(shell date '+%Y-%m-%d-%H:%M:%S')
In my recipe I do a couple of grep on the log file:
my_long_run:
cd $(MYDIR); Running a tool for a long time | tee -i ./Log/my_long_run_log.$(DATE)
@sleep 2
@grep -iq "Status of the Job:0" Log/my_long_run_log.$(DATE)
@if [ ! -z "$(SOME_ENV_VAR)" ]; then ln -fs $(ANOTHER_ENV_VAR)/my_generate_file; fi; \
echo "$$dependencyTree" > $@; \
echo -e "\nWarning Summary:" >> $@; \
if grep -iq "warn.*total" Log/my_long_run_log.$(DATE) ; then grep -i "warn.*total" Log/my_long_run_log.$(DATE) >> $@; fi; \
if grep -iq "warn.*check" Log/my_long_run_log.$(DATE) ; then grep -i "warn.*check" Log/my_long_run_log.$(DATE) >> $@; fi; \
echo -e "\nError Summary:" >> $@; \
if grep -iq "error.*total" Log/my_long_run_log.$(DATE) ; then grep -i "error.*total" Log/my_long_run_log.$(DATE) >> $@; fi; \
if grep -iq "error.*check" Log/my_long_run_log.$(DATE) ; then grep -i "error.*check" Log/my_long_run_log.$(DATE) >> $@; fi;
The problem is: At the first line, the Date is expanded as: 2020-02-26-09:14:09. But the grep command looks for a file with time stamp: 2020-02-26-09:14:10 grep: Log/my_long_run_log.2020-02-26-09:14:10: No such file or directory gmake: *** [my_long_run] Error 2. And then of course I need repeat this run with a runtime of 6-7 hours just because of this grep failure.
sleep 2
is intentional. As I have some lags in my server and the files take a while to appear. But nevertheless, to my knowledge, Makefile expands all the recipes before executing the commands. Why would $(DATE) have two values for one single recipe? sorry, for not providing an actual MWE, rather an abstracted one. Any help is appreciated.
Upvotes: 1
Views: 1780
Reputation: 1933
You need to use :=
to define your variable, instead of =
. When using =
, it is evaluated every time it is referenced, while when using :=
it is only evaluated when you define it, and its value is then used later on.
This is explained in GNU make's manual: The Two Flavors of Variables, where variables defined with :=
are called simply expanded variables
and variables defined with =
are called recursively expanded variables
.
The value of a simply expanded variable is scanned once and for all, expanding any references to other variables and functions, when the variable is defined.
Your Makefile would then just be like this:
DATE := $(shell date '+%Y-%m-%d-%H:%M:%S')
Upvotes: 4