user308827
user308827

Reputation: 21971

Insert time stamp into executable name using makefile

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

Answers (1)

Bartosz Moczulski
Bartosz Moczulski

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

Related Questions