tt_pre
tt_pre

Reputation: 147

Date in Makefile recipes

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

Answers (1)

Tim
Tim

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

Related Questions