Reputation: 21971
I have a simple make file and I want to insert the current date and time into the executable it creates.
Something like: NOW=$(date +"%c")
to be appended to the exe name. What is the best way to do it?
thanks!
Upvotes: 5
Views: 6404
Reputation: 1239
I suppose you already have a Makefile
which creates application. So here's something you might add:
# Use ':=' instead of '=' to avoid multiple evaluation of NOW.
# Substitute problematic characters with underscore using tr,
# make doesn't like spaces and ':' in filenames.
NOW := $(shell date +"%c" | tr ' :' '__')
# Main target - your app + "date"
all: foo_$(NOW)
# Normal taget for your app which already have.
foo: foo.cpp
# Copy "normal" app to app_DATE
# You'll rater want copy then move, otherwise make will have
# to link your app again during each execution (unless that's
# exactly what you want).
foo_$(NOW): foo
cp $^ $@
Notice the replacement of ':'
with '_'
. As indicated here if date contains a colon make will probably fail to parse the Makefile.
I have no access to Mac OS X at the moment, so this was only tested on Ubuntu, but I used to work on an Mac machine once and I didn't notice any significant differences in make
. So it should work for you too.
--- edit ---
As Beta rightly commented, the method described above creates new copy with current date every time make
is called. It might be desired sometimes, so I'll leave it be, and propose following alternative for situations when it's not:
# Same as above...
NOW := $(shell date +"%c" | tr ' :' '__')
# Default target
all: foo # <-- not foo_$(NOW) anymore, foo_$(NOW) target is removed altogether
OBJ := foo.o bar.o # other ...
# Normal taget for your app which already have, but...
foo: $(OBJ)
$(CXX) $(LDFLAGS) $^ -o $@
cp $@ $@_$(NOW) # <-- additional copy at the end (read on below)
Why is foo_$(NOW)
target gone? Because you only want to create a date-stampped copy of the app if you modified the app itself. Which means you can't create a target, because then make
would always create the copy (as in above scenario).
This however means that make
is unaware of existence of the copy. The copy is not present in the dependency graph that make
creates upon startup. So the copy can't be used as a prerequisite to any other target. It's not a disadvantage, but direct result of the fact that we don't know upfront if we're going to create the copy or not. (If someone has a way to overcome this without running secondary make run, please indulge me :) ).
Upvotes: 8