将静态库与可执行文件链接时,通常会丢弃未引用的符号。在我的情况下,一些未使用的对象用于将它们各自的类注册到工厂中,如果对象被丢弃,则该注册失败。
在我们使用gcc的Unix下,我可以将标志--whole-archive传递给链接器ld(参见下面的ld文档摘录),这使得ld不会丢弃任何对象。 Visual C ++有这样的东西吗?
- 全 - 归档
对于在命令行之后提到的每个档案 `--whole-archive'选项,包括存档中的每个目标文件
在链接中,而不是搜索存档所需的 目标文件。这通常用于将存档文件转换为
共享库,强制每个对象都包含在中 结果共享库。此选项可以多次使用。
答案 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。
编辑:但是,有问题的库需要成为解决方案的一部分。