在编译之前将终端输出插入源文件

时间:2015-12-15 16:43:00

标签: c++ linux bash makefile bazaar

我有一个恰好存储在Bazaar仓库中的C ++项目。该项目还使用#define'd字符串来显示其版本号。有人刚刚问我们是否可以简单地将这个显示的版本号绑定到bzr repo修订号。

所以,在伪C,伪bash中,类似于:

#define VERSION_STRING "revision $(bzr revno)"
//...
cout << "Starting " << VERSION_STRING;

或者是这样。你怎么回答这个问题? makefile是否运行将该命令的输出插入相应源文件的脚本?这有宏观解决方案吗?等?

我对任何和所有聪明的解决方案持开放态度,因为我在这个问题上留下了明显的空白。 = d

1 个答案:

答案 0 :(得分:2)

编译器将有一个标志来从外部定义宏值。对于g ++和clang ++,这是-D

g++ -DVERSION_STRING="revision $(bzr revno)" file.cpp -c -o file.o

要在文件中以字符串形式获取,可以在定义中添加额外的引号:

g++ -DVERSION_STRING="\"revision $(bzr revno)"\" file.cpp -c -o file.o

或者您需要知道如何在文件中对该值进行字符串化,这需要一点magic

#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)

然后你也可以有一个默认值。我建议编译器将一个不同的变量设置为你在内部使用的变量,它有助于跟踪:

#include <iostream>

#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)

#ifdef VERSION
#define VERSION_STRING STRINGIFY(VERSION)
#else
#define VERSION_STRING "0.0.0"
#endif

int main()
{
    std::cout << VERSION_STRING << '\n';
}

结果:

$ g++ -DVERSION="1.0.0" SO.cpp
$ ./a.out 
1.0.0
$ g++ SO.cpp
$ ./a.out 
0.0.0

注意,$(bzr revno)是运行bzr revno并将其输出替换为shell 的语法(bash语法,在大多数其他语法中可能相同)。正如musasabi指出的那样,在makefile中,语法略有不同:$(shell bzr revno)