Как установить библиотеку на linux

Обновлено: 04.07.2024

В данной статье мы посмотрим, что такое статические и динамические библиотеки. Местоположение библиотек по умолчанию. Определение используемых библиотек. Загрузка библиотек.

Библиотеки это набор функций, которые могут использоваться в различных программах. Библиотеки могут быть статические (библиотека привязывается к определенной программе или софт содержит данную библиотеку в своем теле.) и динамическими (библиотеки грузятся в оперативную память и используются). Плюсы первого варианта нет проблемы совместимости, т. к. софт уже в себе содержит библиотеку, библиотека всегда с собой. Но при этом программы становятся большие по размеры и т.к каждая может загружать свои библиотеки, а иногда и одинаковые. Второй вариант значительно лучше, сами программы по своему размеру меньше. Библиотека загружается один раз в оперативку. И следующая программа, которой необходимы такие же функции, берет и использует эти данные.

По умолчанию библиотеки в Linux находятся в двух папках. Это корневая папка /lib в ней находятся библиотеки, которые используют программы, расположенные в корневой папке /bin.

И есть вторая папка /usr/lib . В ней находятся библиотеки, которые используют программы расположенные /usr/bin . Пути к библиотекам указаны файле /etc/ld.so.conf . Данный файл можно просмотреть стандартным способом, через утилиту cat.

Видим, что написано включить все библиотеки, которые расположены по пути, указанном в файле. Те которые оканчиваются на .conf . Он просто включает в себя все настройки, которые находятся в конфигурационных файлах, в данной директории. Переходим в данную директорию.

В данной директории мы можем видеть 2 файла конфигурации, в зависимости от версии и наполнения операционной системы их может быть и больше. Ну и соответственно в конфигурационных файлах находятся пути к директориям, где лежат необходимые для работы библиотеки. Если мы ставим какое, то свое программное обеспечение, которому необходимы дополнительные библиотеки, не идущие в составе дистрибутива linux, то в данной директории может создаться свой конфигурационный файл. Например: если мы используем систему виртуализации VMware , то к каждой VM устанавливаем VMware tools то данное программное обеспечение создаст свой конфигурационный файл с путями для своих библиотек.

Переходим в директорию cd /etc/ и отсортируем так, чтобы в результатах все, что содержит ld.

Видим 3 основных конфигурационных файла. ld.so.conf - это файл конфигурации в котором написано откуда брать дополнительные библиотеки. Директория ls.so.conf.d в которой находятся дополнительные конфигурационные файлы и ld.so.cache это кэш библиотек. Он у нас выстраивается каждый раз для того, чтобы программы при необходимости при запросе библиотек не копались в файлах, а сразу брали из загруженного в оперативную память кэша. Т.е. если мы вносим какие-то изменения в файл конфигурации, добавляем какие-то конфигурационные файлы нам необходимо обновить этот кэш. Кэш обновляется командой ldconfig . Этого, собственно, достаточно, чтобы прогрузить все библиотеки в кэш.

Давайте посмотрим, как, определить какими библиотеками пользуется какая программа.

Для этого мы будем использовать команду ldd и путь к бинарному файлу. Например: Программа ls которая используется для вывода списка файлов в каталоге. Она находится в каталоге /bin/ls .

В результате получим мы следующее:

Мы видим, какие so использует данная программа и соответственно ссылки на них, где они расположены, собственно, so - это наши библиотеки в данном случае.

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

Все, без исключения, программы используют библиотеки. Даже если это ваша программа и у нее нет своих библиотек, она использует стандартную библиотеку языка программирования С.

В этой статье мы подробно рассмотрим что такое библиотеки Ubuntu, как их устанавливать, где брать и что делать если библиотека установлена, а программа говорит что ее нет. Мы не будем трогать создание библиотек, это совсем не наша тема. Как обычно, начнем с теории.

Что такое библиотеки

Библиотеки в Linux содержат наборы функций или если сказать проще алгоритмов или действий для решения определенных задач. Например, если программе нужно вывести строку на экран она не начинает сама закрашивать нужные пиксели, а просто обращается к отвечающей за это функции из библиотеки, то же самое если программе нужно прочитать содержимое файла, она не работает с секторами жесткого диска, ей достаточно вызвать функцию из стандартной библиотеки с (libc.so) и передать ей в параметрах имя нужного файла, а библиотека уже вернет ей запрашиваемые данные.

На самом деле, такая структура реализации программного обеспечения очень выгодна, поскольку достаточно написать алгоритм лишь один раз и его смогут использовать все программы просто загружая библиотеку.

Не нужно думать что библиотеки есть только в Linux, в Windows они тоже есть, только имеют другой формат и расширение dll. В Linux же все библиотеки находятся в папах /lib/, /usr/lib, /usr/local/lib или для 64 битных систем также появляется папка lib64 во всех этих подкаталогах, для библиотек специфичных для этой архитектуры. Библиотека имеет расширение .so и ее название начинается со слова lib. Например, libfuse.so, libc.so.

Дальше, после расширения файла .so идет номер версии библиотеки. Номер версии меняется всякий раз, когда разработчики вносят в нее изменения ломающие совместимость со всеми рассчитанными на нее программами. В таком случае в системе будут уже две библиотеки и каждая программа будет использовать правильную версию. Например, glibc.so.6 и glibc.so.5.

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

linux-vdso.so.1 (0x00007ffd99167000)
libmount.so.1 => /usr/lib64/libmount.so.1 (0x00007f0f6beb0000)
libc.so.6 => /lib64/libc.so.6 (0x00007f0f6bb08000)
libblkid.so.1 => /usr/lib64/libblkid.so.1 (0x00007f0f6b8c8000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f0f6b6a4000)
/lib64/ld-linux-x86-64.so.2 (0x000055aca8227000)
libuuid.so.1 => /usr/lib64/libuuid.so.1 (0x00007f0f6b49f000)
libpcre.so.1 => /usr/lib64/libpcre.so.1 (0x00007f0f6b238000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f0f6b034000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0f6ae17000)

Также эта информация может быть полезна при создании портативных версий программ. А теперь давайте рассмотрим как устанавливаются библиотеки в Ubuntu.

Установка библиотек в Ubuntu

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

error while loading shared libraries: xxxx.so.0
cannot open shared object file no such file or directory

Обычно, в Ubuntu имена пакетов библиотек соответствуют имени нужной библиотеки. Поэтому чтобы определить точное имя в большинстве случаев достаточно воспользоваться поиском по базе пакетов:

apt search libfuse

library

Как видите, найдено два варианта библиотеки, libfuse2 и libfuse-dev.

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

sudo apt install libfuse2

Если же вам нужно собрать приложение из исходников, то кроме обычной библиотеки понадобятся заголовочные файлы, в которых содержится описание реализованных в библиотеке функций. Такие пакеты имеют приставку dev, например, libfuse-dev, тогда нужно устанавливать этот пакет, а он уже в зависимостях потянет и обычную библиотеку, если она еще не установлена:

sudo apt install libfuse-dev

Много проблем может вызвать ситуация, когда вам нужно запустить 32 битную программу в 64 битной системе. Например, если вы установили 64 битную версию библиотеки, а программа все равно говорит о том, что не может ее найти, возможно это 32 битная программа и ей необходима именно 32 библиотека. Если программа не устанавливается с помощью пакетного менеджера, вам тоже придется устанавливать библиотеки вручную.

Посмотреть разрядность бинарника можно с помощью утилиты file:

library3

На скриншоте показаны два варианта вывода программы, для 32 бит, в нашем случае Skype и для 64 - mount.

Для того чтобы установить библиотеку Ubuntu с архитектурой i386 сначала необходимо добавить поддержку архитектуры i386 в dpkg:

sudo dpkg --add-architecture i386

Затем обновляем наши репозитории:

sudo apt update

А во время установки нужной вам библиотеки теперь необходимо указать архитектуру через двоеточие после имени пакета:

sudo apt install libfuse-dev:i386

library1

Если вы уверенны, что библиотека установлена, но программа все равно говорит, что такой библиотеки нет, то возможно, ей просто нужна другая версия библиотеки. Например, в системе есть libudev.so.0, а программе нужна libudev.so.0.1. Такое случается, если вы попытаетесь установить пакет для другого дистрибутива, особенно в Red Hat системах. Если в репозиториях нет нужной версии библиотеки, то скорее всего, они одинаковы, и можно просто создать символическую ссылку:

ln -s /lib/libudev.so.0 /lib/libudev.so.0.1

Затем программа найдет нужную библиотеку.

Управление библиотеками в Linux

Установка библиотек ubuntu уже рассмотрена, но хотелось бы упомянуть еще пару моментов. Как я сказал, библиотеки ubuntu размещаются в определенных каталогах, но расположение библиотек можно настроить.

Перед тем как библиотека будет подключена к программе, ее должна найти в системе специальная программа - менеджер библиотек. Он берет адреса библиотек из файла /etc/ld.cache, а этот файл формируется утилитой ldconfig, на основе файлов конфигурации /etc/ld.so.conf.

В этом файле перечислены все пути к библиотекам. Если вы хотите добавить свою папку для библиотек просто добавьте ее в этот файл:

Затем обновите кэш просто выполнив:

Теперь ваша библиотека может быть загружена программой, например, вы можете добавить путь /opt/lib или даже /home/user/lib. И система будет нормально грузить оттуда библиотеки.

Посмотреть какие библиотеки находятся в кеше ld.cache можно командой:

Также мы можем проверить находится ли там определенная библиотека:

ldconfig -p | grep libjpeg

library2

Еще один способ указать программе где нужно искать библиотеки - это переменная LD_LIBRARY_PATH. Например:

Теперь программы, запускаемые в этом терминале, кроме стандартных путей поиска библиотек, будут использовать и указанную папку.

Выводы

Вот и все. Теперь вы знаете как работают библиотеки Ubuntu, как выполняется установка библиотек Ubuntu и делать так, чтобы программа видела нужную ей библиотеку. У новичков это может вызвать очень много головной боли, но теперь вы знаете что делать и избежите многих ошибок. Если у вас остались вопросы, пишите в комментариях!

Начиная с 3.0-RELEASE, больше нет необходимости указывать options LINUX или options COMPAT_LINUX в Вашем файле конфигурации ядра.

Поддержка Linux приложений осуществляется посредством специального модуля ядра (KLD объекта, "Kernel LoaDable object" ), то есть его можно загрузить/выгрузить "на лету" , без необходимости перезагрузки. Вам потребуется убедиться в наличии следующей строки в файле /etc/rc.conf :

Это, в свою очередь, повлияет на выполнение следующего кода в файле /etc/rc.i386 :

Если Вы хотите проверить, загружен ли модуль, это можно сделать при помощи команды kldstat :

% kldstat Id Refs Address Size Name 1 2 0xc0100000 16bdb8 kernel 7 1 0xc24db000 d000 linux.ko

Если по какой-либо причине Вы не хотите или не можете загрузить KLD, то Вы можете статически включить поддержку Linux в ядро посредством опции options LINUX в файле конфигурации ядра. Затем соберите и проинсталлируйте новое ядро, следуя описанию в секции, посвященной конфигурации ядра .

Установить все требуемые библиотеки можно двумя путями: либо используя порт linux_base , либо установив их вручную .

Этот метод является самым простым, и мы рекомендуем воспользоваться именно им. Процесс аналогичен установке любого другого порта из коллекции портов . Просто выполните следующие команды:

Теперь Вы можете работать с приложениями для Linux. Некоторые программы, возможно, будут сообщать о несоответствии подверсий некоторых системных библиотек. Однако, практически, это не вызывает каких-либо неудобств.

Если у Вас нет установленной коллекции портов, то можно установить требуемые библиотеки вручную Вам понадобятся разделяемые библиотеки для Linux, которые нужны программам, и runtime-компоновщик. Вам также потребуется создать "теневой корень" : директорию /compat/linux , где будут расположены Linux библиотеки. Если нужно загрузить какую-либо разделяемую библиотеку, FreeBSD сперва будет пытаться найти ее в этом дереве. Так, если программа загружает, например, /lib/libc.so , FreeBSD попытается открыть /compat/linux/lib/libc.so , и если такого файла не существует, будет пытаться открыть /lib/libc.so . Разделяемые библиотеки должны находиться в теневом дереве, а не в пути, сообщаемым командой Linux ld.so .

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

Что, если при установленном linux_base порте Ваше приложение все равно сообщает об отсутствии необходимой библиотеки? Как узнать, какая именно нужна библиотека и где ее взять? В принципе, есть два способа. Вам необходимо иметь привилегии суперпользователя для их осуществления.

Если у Вас есть доступ к машине, на которой установлен Linux, узнайте, какие библиотеки использует Linux приложение, и просто скопируйте из на свою машину. Например:

Допустим, Вы скачали по FTP Linux версию Doom'а (на Linux машине). Вы можете узнать, какие разделяемые библиотеки нужны Doom'у при помощи команды ldd linuxdoom :

% ldd linuxdoom libXt.so.3 (DLL Jump 3.1) => /usr/X11/lib/libXt.so.3.1.0 libX11.so.3 (DLL Jump 3.1) => /usr/X11/lib/libX11.so.3.1.0 libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29

Вам потребуются все файлы, перечисленные в последней колонке. Скопируйте их в директорию /compat/linux на Вашей системе, а также создайте символические ссылки на эти файлы, с именами ссылок из первой колонки соответственно. В итоге у Вас на машине должны быть следующие файлы:

/compat/linux/usr/X11/lib/libXt.so.3.1.0 /compat/linux/usr/X11/lib/libXt.so.3 -> libXt.so.3.1.0 /compat/linux/usr/X11/lib/libX11.so.3.1.0 /compat/linux/usr/X11/lib/libX11.so.3 -> libX11.so.3.1.0 /compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29

Note: Заметьте, что если у Вас уже есть какая-либо из перечисленных библиотек, то ее не нужно копировать заново. Однако, у Вас может быть более старая версия. В этом случае, лучше все-таки скопировать библиотеку поздней версии, изменив соответственно ссылку на нее. Предыдущую версию библиотеки можно удалить. Например, пусть у Вас есть следующие библиотеки:

/compat/linux/lib/libc.so.4.6.27 /compat/linux/lib/libc.so.4 -> libc.so.4.6.27

и какое-либо приложение требует библиотеку более поздней версии, судя по команде ldd :

libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29

Если подверсии немного отличаются, копировать /lib/libc.so.4.6.29 необязательно, так как программа, скорее всего, будет нормально работать и с устаревшей версией. Тем не менее, Вы можете заменить libc.so :

/compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29

Note: Символические ссылки важны только для Linux программ. Runtime-компоновщик FreeBSD самостоятельно подберет правильные номера версий библиотек, и Вам не нужно об этом беспокоиться.

% ./linux-elf-программа ELF binary type not known Abort

то нужно изменить тип исполняемого файла, чтобы ядро FreeBSD правильно определило, что это Linux программа. Это можно сделать при помощи утилиты brandelf (1) :

% brandelf -t Linux linux-elf-программа

Следует отметить, что программы, для которых необходим "branding" , встречаются все реже и реже, и в недалеком будущем Вы вряд ли прибегнете к нему вообще.

resolv+: "bind" is an invalid keyword resolv+: "hosts" is an invalid keyword

может выполнить ldconfig?

makoven ★★★★★ ( 24.01.18 18:13:08 )
Последнее исправление: makoven 24.01.18 18:14:15 (всего исправлений: 2)

Как собирал библиотеку и приложение нам самим догадаться?

slovazap ★★★★★ ( 24.01.18 18:42:04 )
Последнее исправление: slovazap 24.01.18 18:43:45 (всего исправлений: 2)


А надо не в /usr/lib64?

implementing. Алсо, раз уж ловишь плохие случаи, делай аборт вместо эксита, так в отлалчике будет виден бактрейс, а не просто факт выхода.

компоновщик не видит библиотеку, если руками ему не показать.

Что ты имеешь ввиду, что надо -llists передавать, чтобы он подцепил /usr/lib/liblists.so? Тогда так должно быть; автоматом только libc.so подтягивается. Как обычно — пиши что есть, что ожидал, что происходит. Без этого гадать никто не будет.

компоновщик не видит библиотеку, если руками ему не показать

а бывает как-то иначе?

/usr/local/lib, раз уж на то пошло.

Чот всегда казалось, что это loader / link editor, ну про вторую букву.


Вообще-то для таких вещей всегда было /usr/local/lib и /usr/local/include


Глупый вопрос, но где Makefile?


PS: а вообще-то всё уже украдено до вас: sys/queue.h — стандартная имплементация различных связанных списков, которые и быстрее и эффективней. (Оригинал тут и более полный, чем огрызок коротый портировали в линукс)

Нативные для данной архитектуры/платформы вроде в $prefix/lib лежат

Попробуй посмотреть на вывод gcc --print-search-dirs , там должны быть пути, по которым он будет библиотеки искать(ЕМНИП, это при сборке gcc задать можно). Врядли проблема в этом, но всё же

В репе не увидел как оно собирается. Не в имени библиотеки ли косяк?

Последнее предположение: ld сам вызываешь или gcc дёргает?


А надо статическую библиотеку в системные пути? Она на то и статическая, что нужный код из неё будет намертво влинкован в исполняемый файл. Дальше её можно не распространять. И в линуксе не любят статические библиотеки, потому что разные исполняемые файлы надуты одинаковым машинным кодом. Если в коде статической библиотеке проблема, придется пересобирать все приложения, с которыми она компилировалась.

А вообще рекомендую освоить cmake или аналог.

Лучше уж пусть голые мейкфайлы пишет, из них хотя бы можно процесс сборки восстановить и руками собрать, в отличие от этого говна, которое все равно нигде кроме линукса не работает как надо. Хотели/получилось.

Сейчас кажется в почете meson

Так не бывает. Единственное исключение - ВЕСЬ код библиотеки находится в lists.h (безо всяких .c файлов).

Да там 2 файла всего. lists.h и lists.c. Перетащи их в проект и всё, какие проблемы?

А как это работает со стандартной библиотекой?

Перетащи их в проект и всё, какие проблемы?

Проблем нет, просто разобраться хочу.

А как это работает со стандартной библиотекой?

Читайте также: