Зачем использовать библиотеку?

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

Как работают библиотеки

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

Некоторые отличия

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

Создание общей библиотеки

$ gcc -g -c -fPIC -Wall module0.c module1.c module2.c
$ gcc -g -shared -o libnew.so module0.o module1.o module2.o

Использование общей библиотеки

$ gcc -g -Wall -o new_prog new_prog.c libnew.so

Теперь, когда мы попытаемся запустить нашу программу new_prog, динамический компоновщик будет искать в списке каталогов нашу новую разделяемую библиотеку libnew.so. Обычно каталоги включают /lib/ или /usr/lib/, хотя они могут отличаться.

Отсюда мы можем либо переместить библиотеку в один из каталогов, проверенных динамическим компоновщиком, либо мы можем установить макрос LD_LIBRARY_PATH в наш текущий каталог (или любой другой каталог, содержащий вашу общую библиотеку) при запуске программы через:

$ LD_LIBRARY_PATH=. ./new_prog

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