【问题标题】:C++ visual studio librariesC++ 视觉工作室库
【发布时间】:2010-09-21 21:40:39
【问题描述】:

有没有办法让 Microsoft Visual Studio 中构建的静态库独立于使用的 CRT(有调试支持/没有它)?

我的意思是,对于简单的 C 库,可以使用 gcc 生成代码,然后在 Visual Studio 中使用相同的静态库。生成的library.a 文件完全独立于/MT/MDd 开关,不会导致警告/链接错误。

与 Visual Studio 默认行为相比,您必须构建同一个库的两个版本 - 独立用于调试/发布模式。如果您尝试在 Debug 配置中使用 Release 版本,反之亦然,这会导致丑陋的警告 (warning LNK4098: defaultlib "LIBCMT" ...),但有时由于运行时不同而无法编译?

有什么办法可以避免这种情况吗?还是我做错了什么?

【问题讨论】:

  • 生成代码的兼容性取决于更多选项,例如异常处理,成员函数指针表示。我希望有办法解决它(除了分发仅限标头的库)。

标签: c++ visual-studio static-libraries


【解决方案1】:

要创建一个无论运行时选择如何都能链接的库,需要使用两个开关:

/MT 针对基本发布运行时进行构建,/Zl 省略默认库名称。

针对 dll 运行时构建将导致编译器用__imp_ 修饰所有运行时符号(例如,它将尝试链接__imp__fread 而不是_fread)。所以你必须选择其中一个静态运行时。

编译器执行隐式默认库编译指示,具体取决于所选的库:

#pragma comment(lib,"libcmtd.lib")

是它在代码中的样子。 /Zl 导致编译器从生成的 .obj(以及 .lib)文件中省略所有这些指令(隐式和显式)。因此,结果应该会干净利落地链接而不会导致默认库冲突。

【讨论】:

    【解决方案2】:

    没有。默认发布和调试配置的目标文件完全不同——调试目标二进制文件是可重定位的机器可执行目标代码,发布目标二进制文件只是原始代码的中间表示。也就是说,后端在发布版本的链接器中,但在调试版本的编译器中。将后端放在链接器中允许编译器后端在优化程序方面做出更明智的决策,但会花费更长的编译时间。

    【讨论】:

    • 这不取决于“链接时间代码生成”是否打开,我见过几个库提供的项目文件已禁用?
    • @Fire:当然可以,但是你无法链接到发布模式的默认设置。
    【解决方案3】:

    分发 2 个版本的库有问题吗?我并不声称代表所有人,但我总是喜欢有一个调试版本,针对静态调试库编译,并编译了断言和额外的检查。(当然,符号也很好!)断言和检查很有帮助,当事物在库代码中崩溃时,堆栈跟踪通常会更好,并且通常更容易阅读反汇编。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 2018-09-04
      相关资源
      最近更新 更多