使用带有-g option的g ++,我可以使用gdb进行调试。
Visual Studio 2010 cl.exe编译器与此选项的等价物是什么?
这个page有不同的库(调试/发布)用于链接。
如果我使用cl.exe编译调试选项,是否必须使用相应的库链接选项(/ MD / MT vs / MDd / MTd)?
答案 0 :(得分:33)
这个问题有几个独立的部分:如何告诉编译器/链接器生成并保留“调试信息”(源代码和目标代码之间的映射),如何告诉编译器以不同的方式编译代码调试更容易(想想assert()和#ifdef _DEBUG),以及链接到项目中的预编译库是否包含调试信息。
-Zi(CL编译器的标志,告诉它生成调试信息)相当于gcc的-g标志。
(还有其他形式的-Z选项:-ZI如果你想在Visual Studio IDE中使用“编辑和继续”支持,但是如果你使用的是IDE,你可能正在使用它的编译器接口设置而不是直接操作它们,而-Z7如果你想要旧的CodeView格式调试信息;每当我直接调用CL时,它总是-Zi我想要的。)
请注意,使用-Zi(或-ZI)选项通常会为每个目录生成.pdb文件,但是当您将代码链接在一起时,它可能来自不同.pdb文件中表示的.obj文件,而您还希望将这些单独的.pdb文件组合成一个表示您链接在一起的代码的主文件 - 这就是链接器的-debug开关所用的内容。
另请注意:这可能听起来违反直觉,但始终使用-Zi(对于CL)和-debug(对于link.exe)。即使对于你要发布的代码也是如此。它不会增加可执行文件的大小,也不会向客户泄露秘密,因为调试信息位于单独的.pdb文件中(您不会将其发送给客户)。如果您有可能需要调试它,那么您将需要.pdb。 (-Zi甚至与优化不兼容,但-ZI是。所以你可能想用-ZI编译你的“debug”版本,你的“release”版本用“-Zi -O2”构建。)
至于库:您不需要将C运行时库的调试/发布属性与您的代码是否包含调试信息相匹配,但通常是一个好主意 - 如果您要调试你希望能够调试所有项目的项目,如果你不打算调试它,你不需要额外的重量。使用给定库的调试/发布版本不会影响它是否具有可用的调试符号(希望,如果编译库的人理解我在上一段中所做的观点),但它会影响诸如assert和extra之类的内容#ifdef _DEBUG该库中的代码。
这适用于您链接的所有库,但特别是对于C运行时库 - Microsoft向malloc()和free()添加了额外的错误检测代码。因此,如果项目中的任何内容都使用了CRT库的调试风格,那么所有内容都应该是。
/ M选项(/ MTd和/ MDd)在我看来是奇怪而神奇的 - 它们只是在幕后进行的一系列复杂事情的别名。以/ MDd为例,记录为“定义_DEBUG,_MT和_DLL,并使您的应用程序使用运行时库的调试多线程和DLL特定版本。它还会使编译器放置库名称MSVCRTD。 lib进入.obj文件。“这里,它影响预处理器(定义_DEBUG和一些其他预处理器符号)和链接器(它实际上在源代码中放置了#pragma注释(链接器))。如果你关心发生了什么并且不理解它,这可能会导致真正的问题 - 我已经看到许多不使用IDE的项目陷入了关于msvcrt.lib和msvcrtd.lib的警告中当您了解如何安全地使用这些(/ M选项)时,您不再需要它们了!我更喜欢明确指出:在我需要的地方直接指定“-D _DEBUG”,指定要显式链接的库(并使用-nodefaultlib),然后不需要/ M选项。
答案 1 :(得分:6)
您正在寻找其中一个debug information generation options(/Z7
,/Zi
或/ZI
)。
如果您使用其中一个,则还应将/DEBUG选项传递给链接器。
您还需要链接运行时库的debug version(/MDd
或/MTd
)。这很重要,因为这些版本与它们的版本不同(例如,它们的内存分配例程不兼容)。