在Windows上定义和使用GNU Make的构建时间戳

3

我正在尝试在Windows上使用GNU make 3.81和Wind River Tornado附带的古老版本make(make 3.76)构建一些软件。

到目前为止,我已经成功从Windows中获取了日期:

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

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

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

由于时间戳中的空格、冒号和斜杠,我遇到了构建错误。如果我回显$(NOW)变量,它会被正确引用,但是当我回显$(CFLAGS)变量时,引号会消失。

3个回答

1

你想为 shell 引用变量(这样它就不会被分割成多个单词),并且再次为 C 引用它(这样当它被 cpp 替换时,你就有了一个字符串字面值)。试试这个:

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

请注意,我使用的是:=而不是=。除非您的旧版make不支持它,否则请使用:=,它会在定义点而不是扩展点进行替换。使用=将使其每次尝试编译文件时都调用这两个shell命令两次。对于性能来说并不好。

如果我回显 $NOW,我会得到 \Tue 11/09/2010 01:51 PM\。如果我回显 $CFLAGS,我会得到 /Tue 11/09/2010 01:51 PM/。 - florin
我没有看到这个问题,但是我正在使用GNU/Linux盒子进行测试(并运行不同的“date”命令)。将您的终端输出复制/粘贴到某个地方或发布截图。 - Jack Kelly
在Windows上对我有用。 - ACarter

0

我认为你应该设置:

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

即添加引号。

还有另一种“hacky”的解决方案 - 删除$(NOW)中的空格--> 尝试:

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

0

如果您消除编译器命令行中传递带引号字符串的复杂性,那么您可能会发现问题更容易调试,例如:

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

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

虽然已经有一段时间了,但我认为 Tornado 随附一个类似于 csh 的 shell,它处理引用(quoting)的方式与更常见的 Bourne shells 不同。它还包括一个 TCL 解释器,您可以创建一个名为 timestamp.tcl 的文件,并像下面这样填写内容,来代替使用 shell:

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

编程和写作

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

在 Makefile 中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接