#c #gcc #link
Как правильно организовать выборочную сборку программы в GCC? Предположим имеется такой набор независимых друг от друга исходных файлов: Vec2.c Vec3.c Mat3.c , которые собираются в библиотэкуlibMegaSuperMath.a. Ясен пень, линкуя такую библиотэку, мы включаем все ее содержимое в конечный исполняемый модуль (или не включаем?). Как организовать выборочную линковку, в случае, если программа, использующая такую библиотэку не нуждается в некоторых из ее компонентов? Вырежет ли GCC неиспользуемые структуры, функции и данные? Какие флаги оптимизации требуются для этого? Приемлем ли в подобной ситуации подход, при котором отдельные "классы" библиотэки собираются в объектные файлы, а инструкция сборки формируется на основании требующихся "классов"? Типа как-то так: Vec2.o Vec3.o Mat3.o и cc NewUberTurboProgramm.c Vec2.o Mat3.o -o Run.exe
Ответы
Ответ 1
Нет, библиотека не линкуется безусловно и целиком. Библиотека - это архив объектных файлов, из которого берутся только "нужные" объектные файлы. В "классическом" алгоритме линковки библиотек из библиотеки берутся те и только те объектные файлы, которые нужны на текущий момент. Линкер просматривает линкуемые компоненты последовательно, слева-направо, как они указаны в командной строке линкера. В процессе такого просмотра он поддерживает список ненайденных/неразрешенных на данный момент символов (в самом начале этот список состоит из просто символа main или его аналога). В процессе обработки слева-направо из очередной встреченной в командной строке библиотеки берутся те и только те объектные файлы, которые разрешают какие-то из не разрешенных на текущий момент символов. Таким образом изъятие кода из библиотеки делается с точностью до объектного файла. Так что ваше утверждение "линкуя такую библиотэку, мы включаем все ее содержимое в конечный исполняемый модуль" - не верно. Из этого также следует, что библиотеки в командной строке линкера лучше указывать где-то в конце - когда линкер уже знает весь список неразрешенных символов и, соответственно, возьмет из библиотеки все, что надо. Если указать библиотеку в командной строке слишком рано, то может получиться так, что линкер возьмет из нее не все, что нужно, ибо в этот момент он еще не знал все, что нужно. В частности, если указать библиотеку самой первой в командной строке, из нее не возьмется вообще ничего (если библиотека не предоставляет main). С прямым указанием отдельных объектных файлов в командной строке линкера ситуация иная: явно указанный объектный файл всегда безусловно целиком линкуется в программу, независимо от того, "нужен" ли он на этот момент или нет. В традиционном "классическом" линкере добиться линковки с точностью до функции можно только помещая каждую функцию в свой отдельный объектный файл. Но многие современные компиляторы и линкеры уже поддерживают линковку с точностью до отдельной функции без необходимости такого индивидуального разбрасывания функций по файлам. В GCC это делается через LTO - link-time optimizations.
Комментариев нет:
Отправить комментарий