Home > other >  writing Makefiles that are dependent on date and/or time
writing Makefiles that are dependent on date and/or time

Time:01-17

Is there anything in GNU Make that allows for dependency on date and/or time?

Currently I have a Makefile that checks whether or not to download the latest financial data. The target is something like stock_symbol.csv, and the important dependency is a a file called last_updated.txt. last_updated.txt changes once a day, and when it does, make will know to refresh my historical data.

The annoying thing is that I have to change this finally manually, or let some other program (e.g. cron) modify it on a schedule. I'm wondering if there's a way to remove the need for external programs here. Does Make have anything that will achieve this?

This is my present Makefile

.PHONY : run
run :
    R --quiet -e "shiny::runApp(launch.browser=TRUE)"

# update model
model.RData: model.R data/vix.csv
    Rscript fit_model.R

# update data
data/vix.csv: last_updated.txt update_csv.R
    Rscript update_csv.R

## remove all target, output and extraneous files
.PHONY: cleanall
cleanall:
    rm -f *~ *.Rout *.RData *.docx *.pdf *.html *-syntax.R *.RData

CodePudding user response:

I am not 100% sure I understand what you are trying to achieve. The following assumes that you want to run make and get your job done if and only if the last time it was done is 24 hours ago or more.

You can achieve this with GNU make by first executing a shell script with the shell function each time you run make. We do this by first assigning a make variable non recursively (DUMMY := $(shell ...)). The shell script touches an empty file with 24 hours ago date and you use this empty file as a timestamp:

TS24  := .timestamp24
DUMMY := $(shell touch -d 'yesterday' "$(TS24)")

job: last_updated.txt
    @echo "Let's do the job"
    touch "$@"

last_updated.txt: $(TS24)
    touch "$@"

Each time you run make .timestamp24 is touched such that its last modification time is exactly 24 hours ago. So, if last_updated.txt is more than 24 hours old it is older than .timestamp24, its rule is fired and the recipe touches it. Anything that depends on it will also be remade. Else last_updated.txt will be considered as up-to-date and will not cause the re-build of the targets that depend on it.

And then:

$ make
touch "last_updated.txt"
Let's do the job
touch "job"
$ make
make: 'job' is up to date.
$ touch -d '2 days ago' last_updated.txt
$ make
touch "last_updated.txt"
Let's do the job
touch "job"
  •  Tags:  
  • Related