При связывании статически ли компоновщик включает всю библиотеку?

Например, если я статический ссылка на freeglut, содержит ли компилятор все из freeglut или только те части, которые я использую? Конечно, это означает, что компоновщик (или компилятор?) Делает какой-то анализ зависимости, чтобы выяснить, что он может безопасно исключить.

Если да, есть ли способ увидеть, что было включено или исключено в Visual Studio?

Ответ 1

Отчасти это проблема качества выполнения, но есть реальная готовность.

А именно, по стандарту компоновщик должен добавить во все единицы компиляции, на которые ссылаются. Но скажите, что в библиотеке у вас есть единица компиляции с ничего, кроме статической переменной, чья инициализация регистрирует что-то с реестром чего-либо, например. обработка сообщений, factory, что угодно, или, возможно, его конструктор и выход деструктора, соответственно, "до основного" и "после основного". Если ничто в этой части компиляции не упоминается, то линкер находится в пределах своих прав, чтобы просто пропустить его, удалить.

Таким образом, чтобы гарантировать, что такие статические переменные не оптимизированы, со стандартно-подходящей инструментальной цепочкой необходимо и достаточно, чтобы ссылаться на что-то в этом блоке компиляции.

В Visual Studio увидим, что было включено, насколько я знаю, нет способа, кроме запроса подробного вывода из компоновщика, например, linker option /verbose:ref.

Однако с этой опцией вы получите действительно подробный вывод.

Альтернативой является запрос компоновщика для файла карты, например, вариант компоновщика /map:blah.

Также этот вывод очень многословный.

Ответ 2

Да, компоновщик будет включать только единицы перевода, которые ссылаются на ваш код.

Если вы создаете файл карты для своего исполняемого файла, вы можете точно увидеть, что он содержит.

Ответ 3

Линкером являются только символы, которые необходимы.

Вероятно, вопрос об осмотре *.lib файлов, отвечает на вторую часть (dumpbin также работает для *.exe файлов).

Ответ 4

Я думаю, вы можете написать образец lib, чтобы получить ответ. В С++ lib, 1 напишите класс, чтобы напечатать все имя подкласса. 2 и несколько классов, полученных из него.

В реальной основной программе просто используйте один из подклассов.

И затем напечатайте все имя.

Тогда вы найдете ответ, я думаю.