Что такое Microsoft Visual Studio, эквивалентная опции GCC ld - whall-archive
При связывании статической библиотеки с исполняемым файлом символы без ссылок обычно отбрасываются. В моем случае некоторые другие неиспользуемые объекты используются для регистрации их соответствующих классов в factory, и если объекты отбрасываются, эта регистрация не выполняется.
В Unix, где мы используем gcc, я могу передать флаг -whole-archive в компоновщик ld (см. выдержку из документации ld ниже), что делает ld не отбрасывать какие-либо объекты. Есть ли что-то подобное для Visual С++?
- весь-архив
Для каждого архива, указанного в командной строке после `--whole-archive ', включите каждый объектный файл в архив
в ссылке, а не поиск в архиве для требуемого объектные файлы. Обычно это используется для преобразования архивного файла в общая библиотека, заставляющая каждый объект быть включенным в в результате общая библиотека. Эта опция может использоваться несколько раз.
Ответы
Ответ 1
Насколько я знаю, нет единственного варианта, который надежно гарантирует это. Существуют комбинации оптимизирующих опций, которые (молча) дезактивируют это, поэтому никак... /INCLUDE
работает, но для этого вам нужно извлечь и перекодировать искаженное имя символа. У вас есть два варианта: (1) обеспечить, чтобы все регистраторы содержались (включены) в блок переводов, содержащий main
, и применяли их использование. (2) Откажитесь от этой "идиомы" и используйте явную регистрацию.
Внимание: этот ответ сейчас почти 7 лет, и утверждения о доступности опций в инструментальной цепочке MSVС++ устарели. Тем не менее я по-прежнему рекомендую не полагаться на шаблон регистратора и смотреть на альтернативы. Из-за этой рекомендации, пожалуйста, не стесняйтесь голосовать, но я предполагаю, что это немного несправедливо, потому что этот вариант был добавлен к компоновщику Microsoft тем временем.
Ответ 2
Версия Visual С++ в Visual Studio 2015 Update 2 включает новый флаг link.exe
, называемый /WHOLEARCHIVE
, который имеет эквивалентную функциональность опции --whole-archive
для ld
. В соответствии с документация флага:
Опция /WHOLEARCHIVE
заставляет компоновщик включать каждый объект файл из указанной статической библиотеки, или если никакая библиотека не является указанный из всех статических библиотек, указанных в команде LINK.
Ответ 3
Я считаю, что ближайший эквивалент будет /OPT:NOREF
.
Ответ 4
Я использую /INCLUDE: для принудительного включения неиспользуемых символов.
Ответ 5
Вы можете использовать с 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 2+
Ответ 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
На странице свойств исполняемого файла ознакомьтесь с разделом Общие свойства/Ссылки/Использовать вкладки зависимостей библиотеки, установленными в true. Это в значительной степени эквивалент MS -все-архив в двух словах.
Изменить: Однако соответствующая библиотека должна быть частью решения.