对 Visual Studio C++ 项目使用 /Zi 和 /Z7 有什么影响?(转)
背景
有几种不同的调试标志可用于 Visual Studio C++ 编译器。他们是:
- (没有任何)
- 不创建调试信息
- 更快的编译时间
- /Z7
- 使用 CodeView 格式在 .obj 文件中生成全符号调试信息
- /子
- 使用程序数据库格式在 .pdb 文件中为目标生成全符号调试信息。
- 启用对最小重建 (/Gm) 的支持,这可以减少重新编译所需的时间。
- /子
- 生成类似 /Zi 的调试信息,但不支持编辑并继续
问题
-
/Gm 标志与多进程构建的 /MP 标志不兼容(Visual Studio 2005/2008)
-
如果你想启用最少的重建,那么 /Zi 标志是必需的,而不是 /Z7 标志。
-
如果你打算使用 /MP 标志,那么在 MSDN 上 /Z7 和 /Zi 之间似乎没有区别。但是,SCons 文档声明您必须使用 /Z7 来支持并行构建。
问题
-
在 Visual Studio C++ 项目中使用 /Zi 与 /Z7 的含义是什么?
-
我错过了这些选项中的任何一个还有其他优点或缺点吗?
-
具体来说,目标的单个程序数据库格式 (PDB) 文件与每个源的多个 CodeView 格式 (.obj) 文件相比有什么好处?
参考
Codeview 是一种更古老的调试格式,它是在 1980 年代中期的“Microsoft C 编译器”时代与 Microsoft 旧的独立调试器一起引入的。它占用更多磁盘空间,调试器解析所需时间更长,并且在链接期间处理起来非常痛苦。当我在 1998-2000 年为 Windows 开发 CodeWarrior 时,我们从我们的编译器生成了它。
一个优点是 Codeview 是一种文档化格式,当其他工具无法处理 PDB 格式的调试数据库时,它们通常可以处理它。此外,如果您一次构建多个文件,则不会争用项目的调试数据库。然而,对于如今的大多数用途而言,使用 PDB 格式是一个巨大的胜利,无论是在构建时间还是在调试器启动时间方面。
旧 C7 格式的一个优点是它是一体的,存储在 EXE 中,而不是单独的 PDB 和 EXE。这意味着您永远不会有不匹配的情况。VS 开发工具将确保 PDB 在使用它之前与其 EXE 相匹配,但是拥有一个包含你需要的一切的 EXE 肯定更简单。
这增加了新的问题,即在发布时需要能够去除调试信息,以及巨大的 EXE 文件,更不用说古老的格式和缺乏对其他现代功能(如 minrebuild)的支持,但当你试图让事情尽可能简单。一个文件比两个文件容易。
并不是说我曾经使用过 C7 格式,我只是把它作为一个可能的优势放在那里,因为你在问。
顺便说一句,这就是 GCC 在我使用的几个平台上做事的方式。DWARF2 格式隐藏在输出 ELF 中。Unix 人认为他们很搞笑。:)
顺便说一句,可以使用DIA SDK解析 PDB 格式。
/Z7将调试信息保存在 CodeView 格式的 .obj 文件中,并让链接器将它们提取到 .pdb 中,同时/Zi在编译期间通过与 mspdbsrv.exe 同步将其合并到一个通用的 .pdb 文件中。
这/Z7意味着更多的文件 IO、正在使用的磁盘空间以及链接器的更多工作(除非使用 /DEBUG:FASTLINK),因为这些 obj 文件中有很多重复的调试信息。但这也意味着每个编译都是独立的,因此实际上仍然比/Zi足够的并行化更快。
到目前为止,他们已经/Zi通过减少与 mspdbsrv.exe 的进程间通信来改善这种情况: https: //learn.microsoft.com/en-us/cpp/build/reference/zf
的另一个用例是“独立”(虽然更大)的静态库,如果您需要,/Z7不需要单独运送。只要您不使用正确.pdb的https://learn.microsoft.com/en-us/cpp/build/reference/fd-program- database-file-name,大多数人都忘记了。vcxxx.pdb
/ZI类似/Zi,但添加了额外的数据等以使“编辑并继续”功能起作用。
/Z7 还有一个缺点:它与增量链接不兼容,这可能是避免使用它的唯一原因。链接:http ://msdn.microsoft.com/en-us/library/4khtbfyf%28v=vs.100%29.aspx
顺便说一句:即使微软说当“使用 /Yu /Z7 选项编译的对象被更改”时执行完整链接(而不是增量链接),似乎这仅适用于使用 / 构建的静态库Z7,不适用于目标文件。
/Z7 的另一个缺点是目标文件的大小。这已经在此处提到,但是这可能会升级到链接器无法链接可执行文件的程度,因为它打破了链接器或 PE 格式的大小限制(它会给您链接器错误 LNK1248)。似乎 Visual Studio 或 PE 格式有 2GB 的硬限制(也在 x64 机器上)。在构建调试版本时,您可能会遇到此限制。看起来这不仅会影响最终编译的可执行文件的大小,还会影响临时数据。只有 Microsoft 知道链接器的内部结构,但我们在这里遇到了这个问题(尽管可执行文件当然不是 2gigs 大,即使在调试中也是如此)。当我们将项目切换到 /ZI 时,问题奇迹般地消失了,再也没有回来。
浙公网安备 33010602011771号