在Windows上为GNU Make定义和使用构build时间戳

我试图在Windows上使用GNU make 3.81和风河龙卷风(make 3.76)发行的古代版本构build一些软件。

到目前为止,我设法从窗口捕获date:

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

但是当我把它传递给编译器时

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

由于时间戳中的空格,冒号和斜线,我正在生成构build错误。 如果我回显$(NOW)variables,它被正确引用,但是当我回显$(CFLAGS)variables,引号消失。

你想引用shell的变量(所以它不受字拆分),再引用它的C(所以当它被cpp替代,你有一个字符串文字)。 尝试这个:

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

还要注意我正在使用:=而不是= 。 除非你的旧版本不支持它,否则使用:= ,它将在定义点评估替换,而不是扩展点。 每当您尝试编译文件时,使用=会使它调用这两个shell命令两次。 表现不佳。

我想你应该设置:CFLAGS = … -DBUILD_TIMESTAMP =“$(NOW)”…

即加引号。

还有另一个“hacky”解决方案 – 删除$(NOW)中的空格 – > Try:

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

如果你消除了在编译器命令行上传递带引号的字符串的诡计,你可能会发现这个问题更容易调试,如下所示:

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

…和#include "timestamp.h"在你的代码中。 这样你只需要担心你的shell的引用行为,而不是make和编译器。

这已经有一段时间了,但是我我记得龙卷风装有一个csh风格的外壳,可以处理引用,呃,与更常见的Bourne外壳不同。 它还包括一个TCL解释器,你可以使用这个类似的内容创建一个timestamp.tcl

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

和写作

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

在makefile中。