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

我有一个C ++项目,恰好存储在一个Bazaar回购站。 该项目还使用# #definestring来显示其版本号。 有人问我们是否可以简单地将这个显示的版本号绑定到bzr回购版本号。

所以,在伪C,伪Bash,如:

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

或者。 你怎么回答这个问题? 生成文件是否运行一个脚本,将该命令的输出插入到相应的源文件中? 有没有这个macros观的解决scheme? 等等?

我对任何和所有聪明的解决scheme都是开放的,因为我在这个问题上得到了一个有教养的空白。 = d

编译器将有一个标志来外部定义一个宏值。 对于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 

或者你需要知道如何将文件中的值进行字符串化,这需要一点魔力 :

 #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语法,在大多数语法中可能是相同的)。 在一个makefile中,正如musasabi指出的那样,语法略有不同: $(shell bzr revno)