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"