Существует 3 вида объектных файлов.
Перемещаемые объектные файлы
Содержит машинный код в форме, которая может быть объединена с другими перемещаемыми объектными файлами во время соединения, чтобы сформировать исполняемый объектный файл.
Если у вас есть a.c
исходный файл, чтобы создать его объектный файл с GCC, вы должны выполнить:
gcc a.c -c
Полный процесс будет следующим: препроцессор (cpp) будет работать над a.c. Его вывод (все еще источник) будет передан в компилятор (cc1). Его вывод (сборка) поступит в ассемблер (как), который выдаст relocatable object file
. Этот файл содержит объектный код и ссылки (и может отлаживать, если использовался -g
), метаданные и не может быть непосредственно выполнен.
Общие объектные файлы
Специальный тип перемещаемого объектного файла, который может быть загружен динамически, либо во время загрузки, либо во время выполнения. К таким библиотекам относятся общие библиотеки.
Исполняемые объектные файлы
Они содержат машинный код, который может быть непосредственно загружен в память (загрузчиком, например, execve) и впоследствии выполнен.
Результатом работы компоновщика над несколькими relocatable object files
является executable object file
. Компоновщик объединяет все файлы входных объектов из командной строки слева направо, объединяя все входные секции одного типа (например, .data
) с выходными секциями того же типа. Он использует symbol resolution
и relocation
.
Бонус:
При связывании с static library
функции, на которые имеются ссылки во входных объектах, копируются в конечный исполняемый файл.
С dynamic libraries
вместо этого создается таблица символов, которая обеспечивает динамическое связывание с функциями / глобалами библиотеки. Таким образом, результатом является частично исполняемый объектный файл, так как он зависит от библиотеки. (простыми словами, если библиотека исчезла, файл больше не может выполняться).
Процесс связывания может быть выполнен следующим образом:
ld a.o -o myexecutable
Команда: gcc a.c -o myexecutable
вызовет все команды, упомянутые в точке 1 и в точке 3 (cpp -> cc1 -> as -> ld 1 )
1: фактически это collect2, которое является оберткой над ld.