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

Обновлено: 05.07.2024

Copy raw contents

Copy raw contents

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

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

ЧТО ТАКОЕ БИБЛИОТЕКИ?

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

Библиотеки делятся на два типа - динамические и статические. Статические библиотеки linux подключаются на этапе сборки программы, а динамические - во время выполнения и они общие для нескольких программ. Нас будут интересовать именно динамические библиотеки linux. Они находятся в папках /lib, /lib64, /usr/lib, /usr/lib/x86_64-linux-gnu. Каждая библиотека имеет расширение .so, за которым следует номер версии. Этот номер увеличивается каждый раз, когда разработчики вносят серьезные изменения. Такой подход необходим для того, чтобы сохранить совместимость для программ, использующих старые версии. Например, в системе может быть две библиотеки libfuse.so.0 и libfuse.so.1. Далее мы рассмотрим основные библиотеки и их предназначение.

КАК ПОЛУЧИТЬ ИНФОРМАЦИЮ О БИБЛИОТЕКАХ?

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


Во всех перечисленных здесь каталогах находятся статические и динамически библиотеки Linux:

ls -l /lib/x86_64-linux-gnu/


Информацию о зависимостях каждой библиотеки вы можете посмотреть командой ldd:


А еще можно узнать какому пакету принадлежит библиотека в Ubuntu:

dpkg -S /lib/x86_64-linux-gnu/ld-2.24.so


Как видите, библиотека ld.so принадлежит пакету libc6, точнее она входит в набор инструментов Си. Более подробно, о том, как устанавливать новые библиотеки и решать проблемы с ними, описано в статье библиотеки Ubuntu .

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

  • libanl.so - библиотека работы с DNS;
  • libc.a - основная статическая библиотека языка Си;
  • libdl.a - библиотека, отвечающая за загрузку других библиотек во время запуска программы;
  • libnsl.so - работа со службой NIS;
  • libstdc++.so - стандартная библиотека C++;
  • libutil.so - реализует основные часто используемые функции;
  • libelf.so - библиотека для работы с бинарными файлами ELF;
  • libevent.so - библиотека с реализацией механизма вызова функций после события;
  • libgnutls.so - библиотека с основными методами и возможностями, используемыми в стандартных утилитах Linux;
  • ld-linux.so - главная библиотека, она собрана в виде статической и не имеет зависимостей. Загружает другие библиотеки и исполняемые файлы. Вы можете вызвать эту библиотеку как программу и передать ей адрес исполняемого файла для запуска.

Эти библиотеки содержат наборы кодеков для воспроизведения различных медиа данных. Некоторые из них имеют несвободную лицензию или закрытый исходный код:

Сегодня мы поговорим о библиотеках в Linux (подозреваю также, что многие описанные здесь вещи возможны и в других *nix-операционных системах, но это требует проверки :-) ).

1) Статические библиотеки (создание с помощью Assembler, C/C++; подключение и использование в программах на Assembler,C/C++);
2) Динамические библиотеки (создание с помощью Assembler, C/C++; подключение и использование в программах на C/C++l, Python).

1) Статическая библиотека - это такая библиотека, которая связывается (линкуется) с программой в момент компиляции оной. При этом объектный код библиотеки помещается в исполняемый файл программы. С этой точки зрения статическая библиотека похожа на исходный код программы, с которой она связывается, за исключением того, что библиотека компилируется "кем-то еще" и программист, использующий библиотеку, имеет дело исключительно только с результатом этой компиляции.

В Linux, как правило, файл-статическая_библиотека имеет расширение ".a"

2) Статические библиотеки на языке C.

Исходный код библиотеки:

Сохраните его в файле static.c

Ключевое слово extern необходимо для того, чтобы функция была видна в программе.

Теперь скомпилируем (! без линковки) библиотеку:

gcc -c static.c -o static.o
(на выходе имеем файл static.o, содержащий объектный код нашей библиотеки)

ar rc libMY_STATIC.a static.o

ar упаковывает несколько (! Это важно. Дело не ограничивается только одним объектным файлом) объектных файлов в одну статическую библиотеку. Статическая библиотека имеет расширение ".a", при этом ее название должно начинаться с "lib" (дань традиции).
Параметры ar:
r - предписывает заменять старые версии объектных файлов новыми - необходим для переупаковки библиотеки;
c - создать статическую библиотеку, если та еще не существует.

Проиндексируем функции внутри библиотеки для более быстрой линковки:

Итак, мы получили статическую библиотеку libMY_STATIC.a.

Теперь попытаемся использовать библиотеку в нашей программе:

Исходный текст программы (C):

Сохраните его в файле program1.c

Способы связывания библиотеки и программы:

- Скомпилируем и слинкуем (в том числе с нашей библиотекой) нашу программу:

gcc program1.c libMY_STATIC.a

(предполагается, что в качестве аргумента gcc будут переданы полные пути (!) к вашим библиотекам)

На выходе получим:

- Скомпилируйте с помощью команды:

gcc program1.c -L. -lMY_STATIC -o a1.out

- путь к каталогу, содержащему наши библиотек (используйте "-L

- название нашей библиотеки (это важно - название (!), а не имя файла - собственно, если библиотека имеет своим именем "libBLABLABLA.a", то ее названием будет "BLABLABLA" - т.е. имя без приставки "lib" и расширения ".a") (для нескольких библиотек используйте "-l -l . ")

Запустите файл a1.out на выполнение и удостовертесь, что результаты те же, что и в предыдущем пункте.

- Видоизменим предыдущий способ - уберем аргументы "-L":

В начале проверим значение переменной LD_LIBRARY_PATH и содержимое файла /etc/ld.so.conf:

echo $LD_LIBRARY_PATH ; cat /etc/ld.so.conf

На экране появился некоторый список каталогов - это те каталоги, в которых система ищет библиотеки при их линковке с программой (еще к таким каталогам относятся:
/lib
/usr/lib
. Поместите libMY_STATIC.a в один из этих каталогов:

(Я, к примеру, засуну нашу библиотеку в каталог /usr/lib):

su -c 'cp libMY_STATIC.a /usr/lib'
(в Ubuntu - sudo cp libMY_STATIC.a /usr/lib )
ldconfig
(ldconfig обновляет кеш данных о библиотеках линковщика)

Теперь скомпилируем и запустим нашу программу:

gcc program1.c -lMY_STATIC -o a2.out
./a2.out

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

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

3) Статические библиотеки на языке Assembler.

Представьте, что вам необходимо оптимизировать выполнение некоторых действий в вашей программе. Разумеется, вы может применить ключевое слово asm (если пишите программу на C/C++), но лучшим решением будет создание оптимизированной вами библиотеки на языке Assembler и подключение ее к вашей программе. Давайте попробуем:

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

Итак, имеем вот такую программу:

Сохраните ее в файле program2.c

Скомпилируйте ее и запустите:

Я привел этот пример, чтобы показать действительно возможность оптимизации программы с помощью библиотеки на Assembler'е. Вы можете заметить, что вызов printf в main() не оптимален, т.к. printf, по крайней мере, один раз использует цикл while для поиска вхождений конструкций "%. " в строку. Это не оптимально, т.к. очевидно, что таковых символов у нас нет. Оптимизируем нашу программу с помощью библиотеки на Assebmler'е:

my_printf:
movl $4,%eax
xorl %ebx,%ebx
incl %ebx
movl $hw,%ecx
movl $hw_e,%edx
int $0x80
xorl %eax,%eax
ret

Сохраните исходный код библиотеки в файле static2.s

Это AT&T наречие Assembler'а.

Теперь получим библиотеку:

gcc -c static2.s -o static2.o
ar rc static2.a static2.o
ranlib static2.a

На выходе имеем статическую библиотеку static2.a

Теперь напишем программу, использующую эту статическую библиотеку (язык C):

Сохраните текст программы в файле program3.c

Заметьте, я добавил прототип библиотечной функции для удобства.

Скомпилируем и слинкуем программу с библиотекой, после чего запустим программу на выполнение:

gcc program3.c static2.a
./a.out

На выходе получим:

* Принцип линкования статических библиотек с программами на Assembler'е аналогичен принципу для программ на C. Просто, когда будете использовать статические библиотеки в Assembler'е, помните о соглашениях C по передаче аргументов в функцию и возвращению результата.

4) Статические библиотеки на языке C++.

Принцип создания аналогичен статическим библиотекам на C, но перед каждой экспортируемой функцией не забывайте добавлять:

(экспортировать как функцию на C - т.е. без расширения имен).

* Кстати, используйте g++ вместо gcc, если захотите протестировать приведенные выше примеры.

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

extern "C" PROTOTYPE

Где PROTOTYPE - прототип импортируемой функции.

* При подключении статических библиотек на C++ к программе на C сопряжено с некоторыми трудностями - т.к. при компиляции и линковки программы необходимо будет также вручную подключить системные библиотеки для реализации функционала, предоставляемого библиотекой Standart C++ сверх того, что предоставляет библиотека Standart C.

Динамические библиотеки (shared).

1) Динамическая библиотека - библиотека, подключаемая к программе в момент выполнения. Это означает, что при создании библиотеки производится не только ее компиляция, но и линковка с другими, нужными ей, библиотеками (!).

Динамические библиотеки полезны в случаях, если:
- Важно не перекомпилировать всю программу, а только перекомпилировать ту часть, которая реализует определенные функции - тогда эти функции выносятся в динамическую библиотеку;
- Важно использовать в программах на C библиотеки, подготовленные на C++ и при этом избежать лишних трудностей с линковкой программы;
- Кроме того, динамические библиотеки позволяют экономить место на жестком диске и в оперативной памяти, если одна и таже библиотека используется несколькими программами.

В Linux, обычно, динамические библиотеки имеют расширение ".so".

2) Подготовим исходный код динамической библиотеки (пример на C++).

Исходный код динамической библиотеки по принципам создания ничем (!) не отличается от исходного кода статических библиотек.

Здесь мы подготовим некоторый пример, который в дальнейшем будем использовать повсеместно во всей части 2.

Итак, исходный код библиотеки (C++):

extern "C" int hello()
cout<<"Hello world!\n I'm function hello()"<<endl;
return 0;
>

Сохраните приведенный код в файле dynamic.cpp.

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

3) Компиляция и линковка динамических библиотек.

Давайте получим динамическую библиотеку:

Получим файл с объектным кодом:

g++ -fPIC -c dynamic.cpp -o dynamic.o

(используйте gcc для программ на С и Assembler'е)

-fPIC - использовать относительную адресацию в переходах подпрограмм - во избежание конфликтов при динамическом связывании

А теперь из объектного файла получим библиотеку:

g++ -shared -olibdynamic.so dynamic.o

(используйте gcc для программ на С и Assembler'е)

libdynamic.so - имя результирующей библиотеки;
-shared - предписывает создать динамическую (т.е. "разделяемую") библиотеку.

* Именуйте динамические библиотеки следующим способом:

Итак, на выходе мы имеем libdynamic.so - нашу динамическую библиотеку.

4) Использование динамической библиотеки в программе на C/C++.

- Связывание с библиотекой во время компиляции программы (C/C++):

------ Подготовим исходный код нашей программы:

Сохраните его в файле Dprogram1.c

extern "C" int hello();

Сохраните его в файле Dprogram1.cpp

(единственное отличие, как вы можете заметить, в ключевом слове extern - см. часть 1 пункт 4)

------ Теперь добьемся того, чтобы система смогла найти нашу библиотеку. Поместим libdynamic.so в один из каталогов:

cat /etc/ld.so.conf
и выполните потом " ldconfig "

------ И, наконец, скомпилируем программу и слинкуем ее с библиотекой:

gcc ИСХОДНИК -lИМЯ_БИБЛИОТЕКИ -o РЕЗУЛЬТИРУЮЩИЙ_БИНАРИК

В нашем случае: gcc Dprogram1.c -L/home/amv/c/libs/ -ldynamic

(используйте g++ для программы на C++)

Запустим на исполнение полученный файл:

В итоге должно получится:

- Связывание с библиотекой во время исполнения программы (C/C++):

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

Исходный код примера (C):

Сохраните его в файле Dprogram2.c

В dlfcn.h определены следующие функции:

* Посмотрите на досуге вот этот перевод "man dlopen": Привет, OpenNET

gcc -ldl Dprogram2.c

(используйте g++ для программы на C++)

Запустим на исполнение полученный файл:

В итоге должно получится:

* Важно! Нет необходимости помещать библиотеку в один из специальных каталогов, модифицировать переменные окружения и выполнять "ldconfig"

- Использование динамической библиотеки в программе на Python:

Все предельно просто.

------ Поместим libdynamic.so в один из каталогов:

cat /etc/ld.so.conf
и выполните потом "ldconfig"

Исходный текст программы на python'е:

Модуль ctypes входит в стандартную поставку модулей python версии 2.5 и выше.

Фуф. Мы проделали довольно большую работу, но ведь это только верхушка айсберга.

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

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

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

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

Библиотеки делятся на два типа - динамические и статические. Статические библиотеки linux подключаются на этапе сборки программы, а динамические - во время выполнения и они общие для нескольких программ. Нас будут интересовать именно динамические библиотеки linux. Они находятся в папках /lib, /lib64, /usr/lib, /usr/lib/x86_64-linux-gnu. Каждая библиотека имеет расширение .so, за которым следует номер версии. Этот номер увеличивается каждый раз, когда разработчики вносят серьезные изменения. Такой подход необходим для того, чтобы сохранить совместимость для программ, использующих старые версии. Например, в системе может быть две библиотеки libfuse.so.0 и libfuse.so.1. Далее мы рассмотрим основные библиотеки и их предназначение.

Как получить информацию о библиотеках?

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


Во всех перечисленных здесь каталогах находятся статические и динамически библиотеки Linux:

ls -l /lib/x86_64-linux-gnu/


Информацию о зависимостях каждой библиотеки вы можете посмотреть командой ldd:


А еще можно узнать какому пакету принадлежит библиотека в Ubuntu:

dpkg -S /lib/x86_64-linux-gnu/ld-2.24.so

Как видите, библиотека ld.so принадлежит пакету libc6, точнее она входит в набор инструментов Си. Более подробно, о том, как устанавливать новые библиотеки и решать проблемы с ними, описано в статье библиотеки Ubuntu.

Основные библиотеки

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

  • libanl.so - библиотека работы с DNS;
  • libc.a - основная статическая библиотека языка Си;
  • libdl.a - библиотека, отвечающая за загрузку других библиотек во время запуска программы;
  • libnsl.so - работа со службой NIS;
  • libstdc++.so - стандартная библиотека C++;
  • libutil.so - реализует основные часто используемые функции;
  • libelf.so - библиотека для работы с бинарными файлами ELF;
  • libevent.so - библиотека с реализацией механизма вызова функций после события;
  • libgnutls.so - библиотека с основными методами и возможностями, используемыми в стандартных утилитах Linux;
  • ld-linux.so - главная библиотека, она собрана в виде статической и не имеет зависимостей. Загружает другие библиотеки и исполняемые файлы. Вы можете вызвать эту библиотеку как программу и передать ей адрес исполняемого файла для запуска.

Библиотеки кодеков

Эти библиотеки содержат наборы кодеков для воспроизведения различных медиа данных. Некоторые из них имеют несвободную лицензию или закрытый исходный код:

  • liba52.so - свободный декодер ATSC A/52;
  • libavfilter6.so - библиотека фильтров ffmpeg;
  • libavcodec57.so - библиотека кодеков ffmpeg;
  • libavformat57.so - библиотека форматов ffmpeg;
  • libavutil55.so - библиотека дополнительных функций ffmpeg;
  • libdv.so - программный кодек для DV;
  • libmad.so - MPEG аудио декодер;
  • libmpeg2.so - потоковый декодер видео данных;
  • libmpg123.so - библиотека консольного плеера mpg123;
  • libwebp.so - декодирование формата Webp;
  • libxvidcore.so - медиа кодек MPEG-4.

Звуковые библиотеки

  • libao.so - библиотека проигрывания звука с простым интерфейсом;
  • libasound.so - библиотека взаимодействия со звуковой подсистемой ALSA;
  • libaudio2.so - библиотека работы со звуком, входит в состав ALSA;
  • libespeak.so - библиотека синтеза речи;
  • libpulse.so - библиотека с основными методами PulseAudio;

Работа с архивами

  • libarchive.so - библиотека для работы с архивами различных форматов;
  • liblzma.so - работа с архивами LZMA.

Графические библиотеки

  • libart.so - библиотека с реализацией функций для работы с 3d графикой;
  • libaa.so - библиотека ASCII графики;
  • libgtk-3.so - набор методов графического фреймворка GTK 3;
  • libgd.so - базовые функции работы с графикой и рисования;
  • libgif.so - работа с форматом изображений Gif;
  • libjpeg.so - работа с изображениями Jpeg;
  • libglapi.so - свободная реализация методов для работы с OpenGL;
  • libgtk-x11-2.0.so - набор методов библиотеки GTK 2;
  • libwx_baseu.so, libwx_baseu_net-3.0.so и другие - набор библиотек фремворка создания графических приложений WX;
  • libX11.so - основные методы и функции X сервера;
  • libncurses.so - одна из самых популярных библиотек псевдографики;
  • libQtGui.so, libQt5Svg.so, libQt5Widgets.so и другие - библиотеки фреймворка разработки графических приложений Qt.

Работа с текстом

  • libaspell.so - библиотека проверки орфографии;
  • libfreetype.so - библиотека отрисовки шрифтов;
  • libharfbuzz.so - библиотека обработки символов Unicode;
  • libxml2.so - библиотека разбора XML;
  • libyaml-0.so - библиотека разбора Yaml.

Безопасность

  • libcrack.so - библиотека с реализацией методов перебора паролей для проверки их надежности;
  • libcrypt.so - библиотека, отвечающая за шифрование;
  • libssl3.so - библиотека шифрования SSLv3;
  • libapparmor.so - библиотека управления системой безопасности AppArrmor;
  • libaudit.so - библиотека слежения за состоянием системы и регистрации событий.

Библиотеки драйверов

  • libcups.so - библиотека работы с принтером;
  • libfuse.so - библиотека организации виртуальных файловых систем;
  • libgphoto2.so - библиотека взаимодействия с камерами по USB;
  • libsensors.so - используется для получения информации от датчиков на материнской плате;
  • libudisks2.so - библиотека usisks, которая отвечает за автоматическое монтирование и обнаружение подключенных устройств;
  • libv4l1.so - библиотека работы с веб-камерами;
  • libpci.so - библиотека работы с PCI устройствами;
  • libusb-1.0.so - библиотека управления USB;
  • libdrm.so - библиотека с общими возможностями Direct Rendering Manager, отрисовки графики с помощью видеокарты;
  • libdrm_amdgpu.so - DRM для драйвера AMDGPU;
  • libdrm_intel.so - DRM для карт Intel;
  • libdrm_nouveau.so - свободный DRM для видеокарт Nvidia;
  • libresolv.so - библиотека получения IP адреса по имени хоста;
  • libpcap.so - библиотека анализа и захвата сетевых пакетов;
  • libproxy.so - настройка и управление прокси;

Эмуляция

  • libSDL.so - библиотека эмуляции загрузки компьютера и базовых возможностей BIOS;
  • libwine.so - библиотека прослойки для запуска приложений Windows в Linux.
  • libvirt.so - библиотека управления KVM;

Выводы

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

На завершение урок про библиотеки Linux:

Как мы уже говорили в шаге "Шаг 4 - Библиотеки объектных файлов" динамические библиотеки немного лучше статических, но их использование более сложное. И не из-за того, что процесс загрузки программы замедляется. Проблемы начинаются уже на этапе компиляции :)

Для начала стоит сказать, что объектный файл создаваемый нашим проверенным способом вовсе не подходит для динамических библиотек. Связано это с тем, что все объектные файлы создаваемые обычным образом не имеют представления о том в какие адреса памяти будет загружена использующая их программа. Несколько различных программ могут использовать одну библиотеку, и каждая из них располагается в различном адресном пространстве. Поэтому требуется, чтобы переходы в функциях библиотеки (операции goto на ассемблере) использовали не абсолютную адресацию, а относительную. То есть генерируемый компилятором код должен быть независимым от адресов, такая технология получила название PIC - Position Independent Code. В компиляторе gcc данная возможность включается ключом -fPIC.

Теперь компилирование наших файлов будет иметь вид:

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

В результате получим динамическую библиотеку libfsdyn.so, которая по моей задумке будет динамической версией библиотеки libfs.a, что видно из названия :) Теперь, чтобы компилировать результирующий файл с использованием динамической библиотеки нам надо собрать файл командой:

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

На этом фокусы не кончаются, если Вы сейчас попробуете запустить файл rezultdyn, то получите ошибку:

А сейчас стоит поговорить еще об одном моменте использования библиотек. Я специально создал динамическую библиотеку с названием fsdyn, чтобы она отличалась от названия статической библиотеки fs. Дело в том, что если у Вас две библиотеки статическая и динамическая с одинаковыми названиями, то есть libfs.a и libfs.so, то компилятор всегда будет использовать динамическую библиотеку.

Связано это с тем, что в ключе -l задается часть имени библиотеки, а префикс lib и окончание .a или .so приставляет сам компилятор. Так вот алгоритм работы компилятора таков, что если есть динамическая библиотека, то она используется по умолчанию. Статическая же библиотека используется когда компилятор не может обнаружить файл .so этой библиотеки. Во всей имеющейся у меня документации пишется, что если использовать ключ -static, то можно насильно заставить компилятор использовать статическую библиотеку. Отлично, попробуем.

Как бы я не пробовал играть с позицией ключа -static, результирующий файл rez1 получается размером в 900 Кб. После применения программы strip размер ее уменьшается до 200 Кб, но это же не сравнить с тем, что наша первая статическая компиляция давала программу размером 10 Кб. А связано это с тем, что любая программа написанная на C/C++ в Linux использует стандартную библиотеку "C" library, которая содержит в себе определения таких функций, как printf(), write() и всех остальных. Эта библиотека линкуется к файлу как динамическая, чтобы все программы написанные на C++ могли использовать единожды загруженные функции. Ну, а при указании ключа -static компилятор делает линковку libc статической, поэтому размер кода увеличивается на все 200 Кб.

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

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