Подтвердить что ты не робот

Что такое Microsoft Visual Studio, эквивалентная опции GCC ld - whall-archive

При связывании статической библиотеки с исполняемым файлом символы без ссылок обычно отбрасываются. В моем случае некоторые другие неиспользуемые объекты используются для регистрации их соответствующих классов в factory, и если объекты отбрасываются, эта регистрация не выполняется.

В Unix, где мы используем gcc, я могу передать флаг -whole-archive в компоновщик ld (см. выдержку из документации ld ниже), что делает ld не отбрасывать какие-либо объекты. Есть ли что-то подобное для Visual С++?

- весь-архив

    Для каждого архива, указанного в командной строке после        `--whole-archive ', включите каждый объектный файл в архив
         в ссылке, а не поиск в архиве для требуемого        объектные файлы. Обычно это используется для преобразования архивного файла в          общая библиотека, заставляющая каждый объект быть включенным в        в результате общая библиотека. Эта опция может использоваться несколько раз.

4b9b3361

Ответ 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 -все-архив в двух словах.

Изменить: Однако соответствующая библиотека должна быть частью решения.