Я пытаюсь понять, как / почему определенные файлы библиотеки динамически загружаются компоновщиком в 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.so
→ libfoo.so.1.0.0
- Это символическая ссылка, которая используется при компиляции программного обеспечения против libfoo. Когда вы указываете -lfoo
компоновщику он будет искать именно libfoo.so
. Как обычно, libfoo.so
никогда не является обычным файлом, это всегда символическая ссылка, указывающая на версию libfoo, которую вы хотите использовать для связывания. В сложной среде сборки у вас может быть несколько версий библиотеки, и вы используете эту символическую ссылку, чтобы выбрать, с какой версией вы хотите связать.libfoo.so.1
→ libfoo.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" указывает номер версии. Это позволяет иметь несколько версий одной и той же библиотеки бок о бок, тогда как у наиболее распространенной версии есть ссылка без номера версии.
Если нет необходимости различать разные версии, суффикс версии может отсутствовать.