MSVC将调试代码与发行代码混合使用

时间:2010-11-09 12:41:13

标签: visual-c++ build-process compilation cross-compiling toolchain

提问的动机:生成64位和32位代码需要两个单独的完整程序编译,当使用visual studio(如下所述)时,发布和调试版本不兼容,因此看似需要另外两个完整的程序编译(总计最多四个)。我想坚持两个完整的程序编译,但我很困惑。

调试所有我关心的事情:全局状态,堆栈框架以及导致崩溃的代码的行号/文件。另外,我不关心经过同行评审的高度稳定的开源库的调试信息;因此,我不需要这些库的调试信息,这个库的发布版本应该足够了。

证据:我知道,在VS中,如果您编译应用程序的调试版本并将其与Google协议缓冲区的发行版本链接,则生成的代码将因为一方而失败 - 混合释放/调试类型的效果。

我想知道这是否是使用visual studio的副作用,并且某些编译器开关可以实现这一点。

其次检查opensource项目的构建脚本/进程似乎可以将调试模式下生成的代码与发布中生成的代码混合(例如mumble)。我想这与release和ReleaseWithDebugInfo之间的区别有关(从cmake借来的术语,但这在Visual Studio中显然是可以表达的)。 ReleaseWithDebugInfo是二进制文件的优化版本,也会生成调试信息,因此适合发布。

问题:

  1. 有人可以解释或提供参考资料,说明哪些开关会使代码不兼容。
  2. 在Visual Studio中编译的ReleaseWithDebugInfo样式是否足以支持调试和发布用例(根据我的标准,如上所述)? --i.e。,是编译器在调试模式下过度生成或冗余时生成的内容吗?
  3. 在ReleaseWithDebugInfo模式下(对于我的应用程序),我可以在发布模式下编译外部依赖项(没有调试信息)并且没有任何未定义的行为吗?

1 个答案:

答案 0 :(得分:4)

调试模式(我认为它是指未优化的)代码是“过度杀伤”取决于你想用它做什么。

如果您想使用调试器,非常准确地踩线,并检查您遇到的任何变量,您需要关闭优化。如果您对此不太关心,那么您可以将其打开,并在调试器中忍受一些奇怪的行为。

如果编译为编辑并继续,则会在该位置周围放置大量填充以允许部分编译/链接。

因此,未经优化的代码存在大量“过度杀伤”和“冗余”,但它们可能仍然很有价值。

链接不同配置的常见问题是它们共享由运行时库的不同版本/配置分配的对象。如果你在库之间使用Win32风格的“C”风格的接口,那么你很少关心一个人的调试和一个人的发布。如果在堆上使用一个版本的运行时分配CString,然后将其传递给使用不同运行时解除分配的代码,那么通常会出现问题。

您需要在这里考虑三件不同的事情:

  • 我需要调试符号吗? - 您可以在任何调试/发布配置中进行这些操作
  • 我需要良好的可调试性还是需要良好的代码优化?
  • 每个人使用的CRT / STL /版本是什么?

这只是你真正需要完美的最后一个。另外两个是个人偏好。