Ответ 1
.a
является "архивом". Хотя архив может содержать любой тип файла, в контексте инструментальной цепочки GNU, это библиотека объектных файлов (для других целей, особенно для WIndows, используется .lib
с той же целью, но формат их обычно не является общим и часто характерны для инструментальной цепочки). Можно извлечь отдельные объектные файлы из архива, который по сути является тем, что делает компоновщик, когда он использует библиотеку.
.o
является объектным файлом. Это код, который скомпилирован в машинный код, но не (как правило) полностью связан - он может иметь неразрешенные ссылки на символы, определенные в других объектных файлах (в библиотеке или отдельно), сгенерированные отдельной компиляцией. Файлы объектов содержат метаданные для поддержки связывания с другими модулями и, необязательно, также для символической отладки исходного уровня (например, в GDB). Другие инструментальные средства, как правило, в Windows, используют расширение .obj
, а не .o
.
.so
- это общая библиотека объектов (или только разделяемая библиотека). Это динамически связано с исполняемым файлом, когда программа запускается, а не статически связана во время сборки. Он позволяет выполнять меньшие исполняемые файлы, а один экземпляр библиотеки объектов используется несколькими исполняемыми файлами. API-интерфейсы операционной системы обычно являются совместно используемыми библиотеками, и они часто используются также в GNU по причинам лицензирования, чтобы отделить код LGPL от закрытого исходного кода (например, я не юрист). Я не претендую на легитимность этого подхода в любая конкретная ситуация). В отличие от файлов .o
или .a
, .so
файлы, используемые приложением, должны быть доступны в системе времени выполнения. Другие системы (опять же обычно Windows) используют .dll
(динамическую библиотеку ссылок) для этой же цели.
Возможно, полезно понять, что файлы .o
связаны с объектным кодом в файлах .a
таким образом, что если разрешение символа удовлетворяется файлом .o
, любая реализация библиотеки не будет связана, что позволит вам существенно замените реализации библиотек собственными, а также для реализации библиотек для вызова пользовательского кода - например, инфраструктура графического интерфейса пользователя может вызывать точку входа приложения.