【问题标题】:What is the Microsoft Visual Studio equivalent to GCC ld option --whole-archive什么是 Microsoft Visual Studio 等效于 GCC ld 选项 --whole-archive
【发布时间】:2011-04-21 12:03:23
【问题描述】:

将静态库链接到可执行文件时,通常会丢弃未引用的符号。在我的情况下,一些其他未使用的对象用于将它们各自的类注册到工厂中,如果这些对象被丢弃,则此注册失败。

在我们使用 gcc 的 Unix 下,我可以将标志 --whole-archive 传递给链接器 ld(参见下面 ld 文档的摘录),这使得 ld 不会丢弃任何对象。 Visual C++ 有这样的东西吗?

--整个存档

    对于命令行中提到的每个存档
`--whole-archive' 选项,包括存档中的每个目标文件
在链接中,而不是在存档中搜索所需的
目标文件。这通常用于将存档文件转换为
一个共享库,强制每个对象都包含在
生成的共享库。此选项可以多次使用。

【问题讨论】:

  • 感谢--whole-archive的解释,我只是在搜索使用它的场景。

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


【解决方案1】:

Visual Studio 2015 Update 2 中的 Visual C++ 版本包括一个名为 /WHOLEARCHIVElink.exe 新标志,它具有与 --whole-archive 选项 ld 等效的功能。根据the flag documentation

/WHOLEARCHIVE 选项强制链接器包含每个对象 来自指定静态库的文件,或者如果没有库 从所有指定给 LINK 命令的静态库中指定。

【讨论】:

  • 哇,这是巨大的。感谢您的信息。
【解决方案2】:

据我所知,没有一个选项可以可靠地保证这一点。有一些优化选项的组合(默默地)禁用它,所以没办法....../INCLUDE 有效,但为此您需要提取和硬编码符号的错位名称。您有两种选择:(1) 确保所有注册商都包含(包含)在包含main 的翻译单元中,并强制使用它们。 (2) 放弃这个“成语”,使用显式注册。

注意:这个答案现在已经快 7 年了,关于 MSVC++ 工具链中选项可用性的声明已经过时了。尽管如此,我仍然建议不要依赖注册商模式并查看替代方案。由于此建议,请随意投反对票,但我认为投反对票有点不公平,因为同时该选项已添加到 Microsoft 链接器中。

【讨论】:

  • 谢谢。我创建了一个小程序,它从静态库中提取所有符号名称并将它们包含在主程序中。
  • 显然,这在近两年后被默默地否决了两次。能否请您谈谈原因?
  • @fschmitt 你有没有找到更好的解决这个问题的方法?
  • 我从静态库转到解决此问题的 dll,因为动态库中没有丢弃任何符号。
【解决方案3】:

我相信最接近的等价物是/OPT:NOREF

【讨论】:

  • 似乎没有任何效果,尤其是。考虑到它隐含在调试版本中。
  • 应该,但根本不起作用,而且不只是对我而言。很不幸。
【解决方案4】:

您可以像这样使用 CMake:

add_executable(hello ${SOURCE_FILES})
target_link_libraries(hello libA libB libC)     # Not need /wholearchive libC 
set_target_properties(hello PROPERTIES LINK_FLAGS "/WHOLEARCHIVE:libA /WHOLEARCHIVE:libB")

注意:/WHOLEARCHIVE 仅适用于 Visual Studio 2015 Update 2+

【讨论】:

    【解决方案5】:

    我使用/INCLUDE: 来强制包含未使用的符号。

    【讨论】:

      【解决方案6】:

      我使用了另一种方法 - 不是将所有内容编译到 .lib 然后将 .lib 链接到可执行文件,而是将可执行文件直接链接到 .obj 文件。

      在 CMake 中,可以这样制作:

      add_library(common OBJECT ${common_sources})
      add_executable(executable1 "main1.cc" $<TARGET_OBJECTS:common>
      add_executable(executable2 "main2.cc" $<TARGET_OBJECTS:common>
      

      更改${common_sources}) 中的任何文件只会重新编译它们的等效对象并重新链接可执行文件,这提供了与通过中间.lib 链接事物相同的好处。同时,所有的静态构造函数都保留在原地,从而解决了这个问题。

      请注意,这仅在静态链接时才有用。

      此方法已使用 gcc 5.2.0、MinGW-w64 5.2.0 和 MSVC 15 进行了测试。

      【讨论】:

        【解决方案7】:

        在可执行文件的属性页面中,查看 Common Properties/References/Use Library Dependency Inputs 将其设置为 true。简而言之,这几乎相当于 MS 的 --whole-archive。

        编辑:但是有问题的库需要成为解决方案的一部分。

        【讨论】:

        • 不,它将所有 obj 文件添加到链接器命令而不是 lib 文件。
        猜你喜欢
        • 2015-08-06
        • 1970-01-01
        • 2010-10-22
        • 2015-09-16
        • 2019-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-05
        相关资源
        最近更新 更多