Ответы
1) Да, будет извлечен только код, на который есть ссылка. Помимо меньшего размера, также увеличивается скорость соединения, поскольку статическая библиотека содержит таблицу индексов всех символов, экспортируемых библиотекой. В этой таблице поиск выполняется быстрее, чем поиск в объектных файлах один за другим.
В качестве альтернативы, если вы хотите добавить все символы в статическую библиотеку независимо от ссылки. Вы можете передать ключ --whole-archive в ld.
2) Правильнее было бы задать этот вопрос в контексте ld (компоновщик gnu), поскольку именно это и привлекает ссылки. GCC просто вызывает компоновщик после завершения компиляции (если вы не выполните gcc -c, что приводит к его остановке после компиляции).
Итак, после завершения компиляции ld вызывается с упорядоченным списком файлов объектов (.o) и библиотек. ld обрабатывает файлы .o по одному и для каждого компоновщика
а) Записывает внешние символы, необходимые для этого файла, которые еще не могут быть решены. Добавляет их в (скажем) неразрешенную таблицу.
б) Проверяет символы (функции, глобальные переменные), экспортированные этим файлом, и разрешает любые предыдущие ссылки, которые могут.
Это очень упрощенный обзор процесса компоновки.
Теперь, когда компоновщик приходит в статическую библиотеку, он делает то же самое, на этот раз используя статическую библиотеку для разрешения символов. Однако есть одно отличие: компоновщик извлекает только неразрешенные символы и их зависимости. Итак, предположим, у нас есть
a.o и libstatic.a, которые в свою очередь содержат b.o и c.o.
b.o определяет bar () и moreBar ();
c.o определяет baz () и moreBaz ();
a.o определяет foo ();
где foo называет бар, который вызывает баз. Теперь, когда вы делаете
gcc -o app a.o libstatic.a
После обработки a.o компоновщик знает, что ему нужно разрешить панель, это разрешается из статической библиотеки, однако, разрешая панель, компоновщик замечает, что для панели требуется база. Это снова решается из libstatic.a. moreBar () и moreBaz () не имеют ссылок и игнорируются.