使用/ Zi vs / Z7对Visual Studio C ++项目有什么影响?

时间:2008-11-12 18:04:29

标签: visual-studio visual-studio-2008 visual-c++ visual-studio-2005 compiler-construction

背景

您可以在Visual Studio C ++编译器中使用几种不同的debug flags。他们是:

  • (无)
    • 不创建调试信息
    • 更快的编译时间
  • / Z7
    • 使用CodeView格式在.obj文件中生成完整的符号调试信息
  • /紫
    • 使用程序数据库格式在目标的.pdb文件中生成完整的符号调试信息。
    • 支持最小重建(/ Gm),这可以减少重新编译所需的时间。
  • / ZI
    • 生成调试信息,如/ Zi,但支持编辑并继续

问题

  • / Gm标志与/MP flag for Multiple Process builds不兼容(Visual Studio 2005/2008)

  • 如果要启用最小重建,则/ Z7标志上需要/ Zi标志。

  • 如果您打算使用/ MP标志,/ Z7和/ Zi之间看起来似乎没有区别于MSDN。但是,SCons documentation表示您必须使用/ Z7来支持并行构建。

问题

  • 在Visual Studio C ++项目中使用/ Zi vs / Z7有什么含义?

  • 我错过了其中任何一种选择的其他优缺点吗?

  • 具体来说,目标的单个程序数据库格式(PDB)文件与每个源的多个CodeView格式(.obj)文件的好处是什么?

参考

MDSN /Z7, /Zi, /ZI (Debug Information Format)

MSDN /MP (Build with Multiple Processes)

SCons Construction Variables CCPDBFLAG

Debug Info

5 个答案:

答案 0 :(得分:8)

Codeview是一种更老的调试格式,它是在20世纪80年代中期的“微软C编译器”时代与微软的旧独立调试器一起引入的。它在磁盘上占用更多空间,调试器解析需要更长的时间,在链接过程中处理起来很麻烦。当我在1998-2000中使用CodeWarrior for Windows时,我们从编译器生成了它。

一个优点是Codeview是一种文档化的格式,其他工具通常可以在它们无法处理PDB格式的调试数据库时进行处理。此外,如果您一次构建多个文件,则无法写入项目的调试数据库。但是,对于目前大多数用途而言,使用PDB格式是一个巨大的胜利,无论是在构建时,尤其是在调试器启动时。

答案 1 :(得分:7)

旧C7格式的一个优点是它是一体机,存储在EXE中,而不是单独的PDB和EXE。这意味着你永远不会有不匹配。 VS开发工具将确保PDB在使用之前与其EXE匹配,但是只需一个EXE就可以更轻松地获得所需的一切。

这增加了在发布时需要能够剥离调试信息的新问题,以及巨大的EXE文件,更不用说古老的格式和缺乏对minrebuild等其他现代功能的支持,但它仍然有用你试图让事情变得尽可能简单。一个文件比两个文件容易。

不是说我曾经使用过C7格式,我只是把它放在那里作为一个可能的优势,因为你问。

顺便说一句,这就是GCC在我正在使用的几个平台上做事情的方式。 DWARF2格式隐藏在输出ELF中。 Unix人认为他们太热闹了。 :)

BTW可以使用DIA SDK解析PDB格式。

答案 2 :(得分:3)

/ Z7还有一个缺点: 它与增量链接不兼容,增量链接可能单独成为避免增量链接的理由。 链接:http://msdn.microsoft.com/en-us/library/4khtbfyf%28v=vs.100%29.aspx

顺便说一句:即使微软说“使用/ Yu / Z7选项编译的对象发生了变化”,也会执行完整的链接(而不是增量),但这似乎只适用于静态库用/ Z7构建,而不是用于目标文件。

答案 3 :(得分:1)

/ Z7的另一个缺点是对象文件的大小。这里已经提到过,但是这可能会升级到链接器无法链接可执行文件的程度,因为它会破坏链接器的大小限制或PE格式(它会为您提供链接器错误LNK1248)。似乎Visual Studio或PE格式的硬限制为2GB(也适用于x64机器)。构建调试版本时,您可能会遇到此限制。看起来这不仅会影响最终编译的可执行文件的大小,还会影响临时数据。只有Microsoft了解链接器内部,但我们在这里遇到了这个问题(尽管可执行文件当然不是2gig,即使在调试中也是如此)。当我们将项目转换为/ ZI时,这个问题奇迹般地消失了,再也没有回来。

答案 4 :(得分:1)

/Z7将调试信息以CodeView格式保存在.obj文件中,并允许链接程序将其提取到.pdb中,而/Zi将其合并为与mspdbsrv同步的通用.pdb文件。 exe在编译过程中。

因此/Z7意味着更多的文件IO,正在使用的磁盘空间以及链接器的更多工作,因为这些obj文件中有很多重复的调试信息。但这也意味着每个编译都是独立的,因此在足够并行化的情况下,实际上仍然比/Zi更快。

现在,他们通过减少与mspdbsrv.exe的进程间通信来改善/Zi的情况:https://docs.microsoft.com/en-us/cpp/build/reference/zf

/Z7的另一个用例是用于“独立”(虽然更大)的静态库,如果需要的话,它们不需要单独运送.pdb。只要您没有使用正确的https://docs.microsoft.com/en-us/cpp/build/reference/fd-program-database-file-name来解决它,大多数人都会忘记,cl还会使用可怕的默认vcxxx.pdb名称引起麻烦的问题。

/ZI类似于/Zi,但添加了其他数据等以使“编辑并继续”功能正常工作。