混合调试和发布库:Windows 与 Linux、静态与共享

Jon*_*rin 3 c++ linux windows linker

这个问题已经被问过几次 ,但我发现它总是指 Windows。这是有道理的,因为 MSVC 失败并出现以下错误:

错误 LNK2038:检测到“_ITERATOR_DEBUG_LEVEL”不匹配:值“0”与 main.obj 中的值“2”不匹配

在我看来,在 Linux 上,它在构建时不会失败。

答案提到了构建类型之间不同的 C++ 运行时,并且在此类库之间不共享 CRT 资源。不过,我不清楚 Linux/Windows 和共享/静态库中的行为有何不同。

我想更好地理解这一点。问题可能是:

  1. Windows 和 Linux 之间有什么不同吗?
  2. 如果这在 Linux 中也是未定义的行为,那么为什么它在构建时不会失败呢?
  3. 静态库和共享库有什么不同吗?
  4. 我的 Linux 包管理器是否下载所有开发包的调试版本?调查一下usr/lib/,我似乎找不到发布库和调试库......

spe*_*ras 6

是的,Linux 和 Windows 是不同的。对于 Windows,我无法透露太多信息,但对于 Linux 工具链,我们实际上没有分开的“调试”与“发布”构建。

我们有几个选择:

  • 启用了哪些优化?
  • 应该发出调试符号吗?
  • 其他一些不太相关的东西。

构建工具链所指的“发布”或“调试”只是一组选项。例如,CMake 的最小大小发布版本使用-Os -DNDEBUG,而 CMake 的调试版本使用-g。发行版在打包内容时还会添加额外的选项。

但除了这些选项之外,ABI 是相同的,因此它们都是兼容的(除了专门标记为 [*] 的选项 - 但这些选项在典型构建中不使用)。所以没关系。您可以混合“调试”或“发布”对象,它会起作用。

至于 4),许多发行版的做法是使用分割调试符号进行构建。这意味着调试信息在单独的文件中发出,并且通常独立打包。例如:

ii  libc6:amd64       2.27-3ubuntu1  GNU C Library: Shared libraries
ii  libc6-dbg:amd64   2.27-3ubuntu1  GNU C Library: detached debugging symbols
Run Code Online (Sandbox Code Playgroud)

通常不安装第二个软件包。我手动安装它以使用完整的调试信息逐步执行 libc6。


[*] 例如,请查看GCC 代码生成选项。您将看到那些生成不兼容对象的对象上有警告。