什么是Microsoft Visual Studio相当于GCC ld选项--whole-archive

时间:2010-10-05 20:02:27

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

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

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

  

- 全 - 归档

     

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

7 个答案:

答案 0 :(得分:23)

Visual Studio 2015 Update 2中的Visual C ++版本包含一个名为link.exe的{​​{1}}新标记,其与/WHOLEARCHIVE --whole-archive选项的功能相同。根据{{​​3}}:

  

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

答案 1 :(得分:7)

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

答案 2 :(得分:7)

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

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

答案 3 :(得分:4)

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

答案 4 :(得分: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 :(得分:1)

我使用了另一种方法 - 而不是将所有内容编译为.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测试了这种方法。

答案 6 :(得分:0)

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

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