Назад | Перейти на главную страницу

Solaris: В чем разница между файлами .so и .so.1?

Я пытаюсь понять, как / почему определенные файлы библиотеки динамически загружаются компоновщиком в Solaris. Я использую ldd, чтобы увидеть это (с переключателем -s, чтобы увидеть, какие пути пробует компоновщик). В качестве примера, если я запускаю «ldd / usr / local / bin / isql -s», я замечаю, что одна из библиотек, которые ищутся, называется «libodbc.so.1». Я заметил, что это НЕ соответствует найденному по пути файлу под названием "libodbc.so". Итак, он, наконец, переходит в место, где есть символическая связь между libodbc.so.1.0.0 и libodbc.so.1. У меня вопрос - какое здесь значение ".1"? Это для обозначения номера версии? Почему одни установщики создают эти символические ссылки, а другие - нет?

Этот вопрос не относится к Solaris.

Когда вы устанавливаете общую библиотеку (или часть программного обеспечения, которая предоставляет общую библиотеку), вы получаете три файла, все они выглядят одинаково, но имеют разные цели.

  • libfoo.so.1.0.0 - Это (обычный) файл данных. Он содержит саму библиотеку. Их может быть несколько, с разными версиями. Внутри этого файла есть Поле ELF называется SONAME, который установлен на libfoo.so.1. В Linux запустите objdump -p libfoo.so.1.0.0 | grep SONAME выяснить.
  • libfoo.solibfoo.so.1.0.0 - Это символическая ссылка, которая используется при компиляции программного обеспечения против libfoo. Когда вы указываете -lfoo компоновщику он будет искать именно libfoo.so. Как обычно, libfoo.so никогда не является обычным файлом, это всегда символическая ссылка, указывающая на версию libfoo, которую вы хотите использовать для связывания. В сложной среде сборки у вас может быть несколько версий библиотеки, и вы используете эту символическую ссылку, чтобы выбрать, с какой версией вы хотите связать.
  • libfoo.so.1libfoo.so.1.0.0 - Это также символическая ссылка, которая используется при запуске двоичных файлов, которым нужна ваша библиотека. Помните поле SONAME, о котором я упоминал? Когда вы связываете двоичный файл с libfoo, двоичный файл записывает SONAME библиотеки и будет использовать его во время выполнения.

Эта настройка позволяет вам иметь несколько версий одной и той же библиотеки, установленных рядом друг с другом. Для разных двоичных файлов могут потребоваться разные версии библиотеки, и каждый двоичный файл найдет правильную версию библиотеки. Обычно SONAME библиотеки изменяется восходящим потоком при изменении обратно несовместимого API. Все старые двоичные файлы по-прежнему используют старый API, в то время как вновь связанные двоичные файлы используют новый.

В некоторых проектах упаковки, например Debian, используйте разные имена пакетов для разных версий библиотеки. Это позволяет независимо устанавливать и удалять каждую версию общей библиотеки.

Есть несколько крайних случаев. Например, зависимости между разделяемыми библиотеками могут привести к одновременному подключению двух версий. Рассматривать:

foo → libbar.so.1, libbaz.so.1
libbar.so.1 → libbaz.so.1

Представьте, что мы устанавливаем новую версию libbaz и перекомпилируем foo. Теперь у нас есть:

foo → libbar.so.1, libbaz.so.2
libbar.so.1 → libbaz.so.1

Во время выполнения foo загрузится libbaz.so.2 и libbar.so.1, и libbar.so.1 загрузит libbaz.so.1. Видите проблему? Одновременно загружаются две версии libbaz. Я не совсем уверен, каковы точные последствия с точки зрения расположения кода в памяти, но на практике это приводит к сбоям.

Да, ".1" указывает номер версии. Это позволяет иметь несколько версий одной и той же библиотеки бок о бок, тогда как у наиболее распространенной версии есть ссылка без номера версии.

Если нет необходимости различать разные версии, суффикс версии может отсутствовать.