florin
florin

Reputation: 14326

Defining and using a build timestamp for GNU Make on Windows

I am trying to build some software on Windows using both GNU make 3.81 and an ancient make distributed with Wind River Tornado (make 3.76).

So far, I managed to capture the date from windows:

NOW=\"$(shell cmd /C date /T) $(shell cmd /C time /T)\"

but when I am passing it on the compiler

CFLAGS = ... -DBUILD_TIMESTAMP=$(NOW) ...

I am getting build errors because of the spaces and colons and slashes in the timestamp. If I echo the $(NOW) variable, it is properly quoted, but when I echo the $(CFLAGS) variable, the quotes disappear.

Upvotes: 3

Views: 3920

Answers (3)

slowdog
slowdog

Reputation: 6216

You might find the problem easier to debug if you eliminate the trickiness of passing quoted strings on a compiler commandline, like so:

.PHONY: force
timestamp.h: force
    echo "#define BUILD_TIMESTAMP \"`cmd /c date /t` `cmd /c time /t`\"" > $@

...and #include "timestamp.h" in your code. This way you only have to worry about the quoting behaviour of your shell, not of make and the compiler.

It's been a while, but I think I remember that Tornado ships with a csh-style shell, which handles quoting, er, differently than the more common Bourne shells. It also includes a TCL interpreter, which you could use instead by creating a timestamp.tcl with content like

puts "#define BUILD_TIMESTAMP \"[clock format [clock seconds] -format {%D %T}]\""

and writing

timestamp.h: force
    tclsh timestamp.tcl > $@

in the makefile.

Upvotes: 0

an0nym0usc0ward
an0nym0usc0ward

Reputation: 1227

I think you should set: CFLAGS = ... -DBUILD_TIMESTAMP="$(NOW)" ...

i.e. add quotes.

There is another "hacky" solution - removing the spaces in $(NOW) --> Try:

empty:=
space:= $(empty) $(empty)
NOW:=$(subst $space,_,$(NOW))

Upvotes: 0

Jack Kelly
Jack Kelly

Reputation: 18667

You want to quote the variable for the shell (so it isn't subject to word splitting) and quote it again for C (so when it's substituted by cpp, you have a string literal). Try this:

NOW := "\"$(shell cmd /C date /T) $(shell cmd /C time /T)\""

Note also that I'm using := instead of =. Unless your old make doesn't support it, use :=, which evaluates the substitution at the point of definition, not the point of expansion. Using = will make it call those two shell commands twice every time you try to compile a file. Not so good for performance.

Upvotes: 1

Related Questions