【问题标题】:Warning when linking a MinGW program with a MSVC static lib将 MinGW 程序与 MSVC 静态库链接时发出警告
【发布时间】:2016-06-06 10:34:22
【问题描述】:

我有一个 MinGW64 C++ 程序,我需要将它与作为目标文件 (obj) 提供的 MSVC 64 位静态 C 库链接

我使用以下方法将其转换为 .a:

ar rcs libtest.a test.obj

这创建了没有警告的静态库

当我链接程序时,我得到:

警告:def 文件末尾的 .drectve 损坏

但链接的程序似乎可以正常工作(多长时间?)

我怎样才能摆脱这个警告?该库不是开源的,由商业供应商提供。如果需要,我可以让他用其他标志编译它。

【问题讨论】:

    标签: c visual-c++ mingw static-linking abi


    【解决方案1】:

    我使用以下方法将其转换为 .a:

    ar rcs libtest.a test.obj
    

    实际上,这并没有以任何方式转换 test.obj。一个静态库 (.a) 只是一个目标文件的存档加上一个目录 链接器可以通过它来搜索它。

    您的ar 命令创建了一个仅包含test.obj 的静态库。 如果您知道您的 MinGW64 链接需要test.obj 则没有 把它单独放在图书馆里。链接器将简单地提取test.obj 从库中并将其添加到链接中,因此您不妨 直接链接test.obj

    如果你这样做,MinGW64 的 GNU 链接器将链接它并准确地发出 与从静态库链接它时收到的相同警告。这 向您展示引发警告的原因是在目标文件中,它是这样的:-

    PE 对象文件格式提供了一个“任意信息”部分,编译器通常在 标签.drectve 并用于嵌入它想要与链接器通信的指令, 它将阅读并服从它们 - 如果可以的话。

    MSVC 使用了.drectve 部分,并且很自然地在那里编写了链接器指令,使 MS链接器的意义,例如

    Microsoft (R) COFF/PE Dumper Version 12.00.31101.0
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    
    Dump of file hw.obj
    
    File Type: COFF OBJECT
    
       Linker Directives
       -----------------
       /DEFAULTLIB:LIBCMT
       /DEFAULTLIB:OLDNAMES
    
      Summary
    
               C .data
              64 .debug$S
              2F .drectve
              12 .text$mn
    

    它们对 GNU 链接器没有任何意义,因此它警告说 .drectve 部分已损坏。

    你能取消警告吗?

    不,没有这样的选择。

    您能否通过为您编译 test.obj 来让供应商避免警告?

    取决于“损坏”.drectve 部分的 MSVC 生成的内容是什么(其中 您可以通过dumpbin 发现,可能有一个 MSVC 编译器选项可以抑制 它的一代。但以后会更多。

    链接安全吗?

    嗯,您的链接器认为目标文件已损坏的事实应该可以管理预期。 MinGW64 不保证您可以安全地将 MSVC 的目标文件与其自己的目标文件链接 或者根本没有。 MSVC 不保证您可以将其目标文件与任何其他文件链接。 Windows 不规范静态链接 不同编译器的目标文件。在实践中,您可以将 test.obj 链接到您的其他 GCC C++ 应用程序,因为 所有目标文件都是 Windows COFF pe-x86-64 目标文件,例如您的链接器能够 链接在一起,很高兴,test.obj 包含 C,而不是 C++,符号,所以不兼容 MS 和 GCC C++ 的名称修改并没有阻止它。如果该程序有效,那同样可以保证 你会得到它的安全性。

    如果你真的想要更多的保证 - 或者只是想要一个由 test.obj 制作的二进制文件, 您可以在没有警告的情况下链接到您的应用程序 - 然后尝试使用 test.obj:

    创建一个 DLL
        g++ -shared -o test.dll test.obj
    

    当您执行该一次性步骤时,会出现相同的链接警告,但如果不是这样 成功然后test.dll 可以链接到您的应用程序,至少保证 ABI 兼容性, 因为它是一个DLL。

    这让我们回到了 compile-with-different options 选项。如果供应商将编译 test.obj 满足您的要求,然后要求供应商将其编译为DLL。对于 Windows, DLL 是 ABI 兼容性的标准单元。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-19
      • 2012-07-09
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 1970-01-01
      相关资源
      最近更新 更多