【问题标题】:Inserting terminal output into source file before compilation编译前将终端输出插入源文件
【发布时间】:2015-12-15 16:43:00
【问题描述】:

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

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

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

差不多吧。你会如何回答这个问题? makefile 是否运行脚本将该命令的输出插入到适当的源文件中?有对此的宏观解决方案吗?等等?

我对任何和所有聪明的解决方案都持开放态度,因为我在这个问题上画了一个受过教育的空白。 =D

【问题讨论】:

  • 您可以使用 -D 编译器标志为 g++ 和 clang++ 定义宏:g++ -DVERSION_STRING="revision $(bzr revno)" file.cpp -c -o file.o
  • 啊,完美。这会优先于在同名源中定义的宏吗?我问的原因是因为我认为我应该包含一个#define VERISON_STRING "000",以防在调用g++ 时内联bash 失败。
  • 扩展为完整答案。
  • 这对你有用吗?
  • 它做到了! ...但事实证明,该项目的结构使该解决方案不可行。唉。但是你肯定回答了,所以你肯定会得到分数。 =)

标签: c++ linux bash makefile bazaar


【解决方案1】:

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

【讨论】:

  • 唯一的改变是我需要在makefile中使用$(shell bzr revno)。 =)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 2014-12-21
  • 1970-01-01
  • 2018-03-06
相关资源
最近更新 更多