C++ 将文件信息(字符数组)嵌入到已编译的二进制文件中 有没有办法将(每个翻译单位)字符串嵌入到优化的二进制文件中?

C++ 将文件信息(字符数组)嵌入到已编译的二进制文件中 有没有办法将(每个翻译单位)字符串嵌入到优化的二进制文件中?,c++,visual-c++,C++,Visual C++,在我们的开发环境中,生成构建非常简单。有时,客户最终会得到一个定制的构建,当他们遇到该构建的问题时,很难确定二进制代码来自哪个代码库 我试图找到一个合理的策略,以便在只有对二进制文件进行取证分析的情况下重建构建环境 将版本信息嵌入到每个翻译单元中 我的一个想法是将版本信息嵌入到每个cpp文件中。差不多 static const char *__FILEVERSIONINFO = __FILE__ "___$Revision$___Build:" PRODUCT_VER_STR; 然后将svn:

在我们的开发环境中,生成构建非常简单。有时,客户最终会得到一个定制的构建,当他们遇到该构建的问题时,很难确定二进制代码来自哪个代码库

我试图找到一个合理的策略,以便在只有对二进制文件进行取证分析的情况下重建构建环境

将版本信息嵌入到每个翻译单元中 我的一个想法是将版本信息嵌入到每个cpp文件中。差不多

static const char *__FILEVERSIONINFO = __FILE__ "___$Revision$___Build:" PRODUCT_VER_STR;
然后将
svn:keywords
属性添加到文件中,这样在构建时,我至少可以知道文件的svn版本。这不会告诉我它是否是从那个修订版中修改的,但它至少能让我接近它

缺点是我无法将这些符号放入发布版本中。因为它们没有被引用,所以得到了优化(我想把优化作为一个全局设置)。我试图(
\uu FILEVERSIONINFO
作为链接器设置中“强制符号引用”的值),但链接器抱怨它找不到符号

error LNK2001: unresolved external symbol __FILEVERSIONINFO
dumpbin
将对象文件中的符号列为

09E 00000004 SECT5  notype       Static       | ___FILEVERSIONINFO
但在“强制符号引用”中使用此名称也不起作用

微软的文档并没有给出它的使用实例,我的谷歌浏览器也没有找到任何相关的东西

我试着用一个#pragma来强制输出它

__pragma(comment (linker, "/export:__FILEVERSIONINFO"))
但是从链接器中得到了相同的错误如何指定此符号的名称?

如果我不必对每个翻译单元的符号名称进行随机化/单列化,这会很方便,但我不知道
/INCLUDE
参数,因为链接器能够包含具有相同名称的所有符号

实际上,我并不关心符号本身是否可以访问,我只是希望能够从二进制文件中提取字符串,并grep“Revision”以查看生成时二进制文件的修订版本

将报表嵌入二进制文件 似乎可以构造一个报告(例如
svn diff
)并将某种形式的报告嵌入二进制文件中。这样做的好处是可以封装对文件/项目所做的任何未提交的源代码级更改)

这似乎有点乏味,但它是可以做到的

其他解决方案? 改变开发人员/支持人员的构建方式对我们来说不是一个可行的选择。我正在寻找一些我能做的事情,而不是依赖于他们阅读更多的文档和遵循程序规则。我意识到这并不理想,但增加更多人为驱动的政策是不值得的

出于我所看到的所有实际目的,我可能只会使用这些信息来查找源文件的特定版本中的问题,而不是实际尝试修补自定义版本


是否有更好的方法标记/标记二进制文件,使我能够找到相关源文件的接近版本以供检查?

SVN标记如何?您可以标记每个构建


更新: 也许可以这样做:

#ifndef SRC_ID
  #ifdef __GNUC__
    #define SRC_ID(X, Y) static const char* const __attribute__((used)) X = Y
  #else
    #define SRC_ID(X, Y) static const char* const X = Y
  #endif
#endif

SRC_ID(build_id, "SOMETHING TO IDENTIFY YOUR BUILD");
\uuuu属性\uuuu((已使用))
变量属性用于向链接器发出信号,表明此变量已被使用,即使它似乎未被使用:

此属性附加到具有静态存储的变量,表示 即使变量看起来是无效的,也必须发出该变量 未引用

资料来源:


问题在于关键字
static
。这就给出了变量,这意味着“这将只在这个文件中使用;请不要将它包含在编译的对象文件中,或者对它进行优化”。如果删除该关键字,编译器会将其包含在对象文件中,您可以使用强制符号引用来保留该关键字

编辑:对
extern
的引用不正确,它用于声明,而不是定义


编辑2:强制符号引用的另一种方法是实际引用它,这种方法适用于其他编译器,可能更有用。添加一个命令行标志
--build info
,用于打印字符串并退出,或者在启动时打印它(如果设置了详细标志),或者类似的东西。然后你不需要检查二进制文件,你知道字符串不会被优化掉。

可能更适合这个问题。强制包含符号是我真正想要的答案,不管它是否是一个伟大的软件工程解决方案。我对其他想法持开放态度,但这只是一种谦逊的表达,而不是我的主要关注点。@RSahu在提及其他网站时,指出为什么
静态
?这有内部链接。@KlitosKyriacou我不希望符号名称必须是全局唯一的,所以我认为将其设置为静态将允许多个翻译单元具有相同的符号和不同的值。我们的版本不都是“正式”版本。任何人都可以一天多次调用构建脚本,我的目标是在“非官方”构建中包含足够的信息,以返回到一组足够接近的源文件。
\uuuuuuu attribute\uuuuuuu((使用))
没有说明它使用的属性(它是属性);它表示使用了变量。但是GCC本身提供的信息几乎足够了。MSVC是否像GCC一样使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?在这种情况下,我被MSVC困住了。在过去的20分钟里,我没有为MSVC找到任何类似的东西(当我没有声明它
static
,我仍然会在尝试导出/包含名称时遇到链接器错误。我不明白为什么内部链接会建议编译器将其从对象文件中删除。这就像声明某些内容“完全无用且不必要”