g++的-g选项相当于VS2010 cl编译器的哪个选项?

24

使用带有-g选项的g++,我可以使用gdb进行调试。

Visual Studio 2010 cl.exe编译器中与此选项相当的是什么?

这个页面有不同的库(debug/release)用于链接。

如果我使用cl.exe进行编译调试选项,是否必须使用相应的库链接选项(/MD/MT vs /MDd/MTd)?

2个回答

41
这个问题涉及到几个不同的部分:如何告诉编译器/链接器生成和保留“调试信息”(源代码和目标代码之间的映射),如何告诉编译器以不同的方式编译代码以便更容易进行调试(例如,使用assert()和#ifdef _DEBUG),以及您链接到项目中的预编译库是否包含调试信息。
-Zi(告诉CL编译器生成调试信息的标志)相当于gcc的-g标志。
(还有其他形式的-Z选项:-ZI如果您想要在Visual Studio IDE中支持“编辑并继续”功能,但是如果您使用IDE,则通常会使用其界面来设置编译器设置,而不是直接操作它们;如果您需要使用CL,则通常需要使用-Zi。)
请注意,使用-Zi(或-ZI)选项将在每个目录中生成一个.pdb文件,但是当您链接代码时,可能会来自表示在不同.pdb文件中的.obj文件,因此您还需要将这些单独的.pdb文件组合成代表您链接的代码的主.pdb文件--这就是链接器的-debug开关所用的地方。
另请注意:这听起来可能有些违反直觉,但始终使用-Zi(对于CL)和-debug(对于link.exe)。即使是您要发布的代码也一样。它不会增加可执行文件的大小,也不会向您的客户公开秘密,因为调试信息会存储在单独的.pdb文件中(您不会将其发送给客户)。如果有任何可能需要进行调试的机会,您都需要.pdb文件。 (-Zi甚至与优化兼容,尽管-ZI则不兼容。因此,您可能需要使用-ZI编译“调试”构建,并使用“-Zi -O2”编译“发布”构建。)关于库文件:你不一定需要严格匹配 C 运行时库的 debug/release 属性和你的代码是否包含调试信息,但通常这是个好主意——如果你要调试项目,你需要能够对其进行全面调试;如果你不打算对其进行调试,那么就不需要额外的负担。使用给定库的 debug/release 版本不会影响它是否有可用的调试符号(希望编译库的人理解我在上一段中提到的重点),但会影响该库中的 assert 和额外的 #ifdef _DEBUG 代码等内容。
这适用于您链接的所有库,但尤其适用于C运行时库,因为微软添加了额外的错误检测代码到 malloc() 和 free() 中。所以,如果您的项目中有任何部分使用CRT库的debug版本,则应全部使用。
/M选项(/MTd和/MDd)在我看来很奇怪而神奇——它们只是别名,代表幕后发生的一系列复杂操作。以/MDd为例,它被记录为“定义_DEBUG、_MT和_DLL,并导致应用程序使用调试多线程和DLL特定版本的运行时库。它还使编译器将库名MSVCRTD.lib放入.obj文件中。”。在这里,它影响预处理器(定义_DEBUG和其他预处理器符号)和链接器(实际上在您的源代码中放置了#pragma comment(linker))。如果你关心正在发生的事情,而又不理解它,这可能会导致真正的问题——我看到很多不使用IDE的项目都因链接了msvcrt.lib和msvcrtd.lib等库而出现警告。当你学会如何安全地使用这些/M选项时,你实际上不再需要它们!我更喜欢使事情变得明确:直接在需要的地方指定“-D_DEBUG”,明确指定要链接的库(并使用-nodefaultlib),然后就不需要/M选项了。

5
+1 哇,我可以问一下你是怎么熟悉微软工具链的个性化特点的吗? :) (翻译):哇,我能问一下你是如何对微软工具链的个性化特点有这么深入的了解吗? :) - Frédéric Hamidi
12
多年来我们一直在使用不同版本的MSVC,并且有许多跨平台项目,所以我们使用makefiles或其他方式绕过IDE的构建系统,使用由第三方构建的开源库,在升级到新版本的MSVC或SDK时保持整个系统运行正常。 :) - metamatt

8

您正在寻找调试信息生成选项之一(/Z7/Zi/ZI)。

如果您使用其中之一,还应该向链接器传递/DEBUG选项。

您还需要链接到运行时库的调试版本/MDd/MTd)。这很重要,因为这些版本与其发布版本不同(例如,它们的内存分配例程不兼容)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接