Предисловие: От исходного файла к исполняемому файлу

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

В gcc прямо из main.c в main:

gcc main.c -o main

Процессор: этап препроцессора удаляет все ваши комментарии из файла, включает и расширяет все ваши файлы заголовков и заменяет все ваши макросы значениями.
Компилятор: затем компиляция берет ваш предварительно обработанный код и преобразует его в код сборки.
Ассемблер: код сборки - это код, который в некоторой степени является удобочитаемым представлением. машинного кода (язык программирования низкого уровня). Ассемблер переводит ассемблерный код в машинный код.
Компоновщик: на этапе связывания весь ваш объектный код или машинный код нескольких файлов связывается в один исполняемый файл.
Обратите внимание, что библиотеки на приведенном выше графике - это именно то, о чем мы сегодня поговорим.
Когда программа на C компилируется, компилятор генерирует объектный код (объектный код - это часть машинного кода, которая содержит еще не связаны в полную программу). После создания объектного кода компилятор также вызывает компоновщик. Одна из основных задач компоновщика - сделать код библиотечных функций (например, printf (), scanf (), sqrt (), ..etc) доступным для вашей программы. Компоновщик может выполнить эту задачу двумя способами, скопировав код библиотечной функции в ваш объектный код (статическая компоновка) или сделав некоторые меры, чтобы полный код библиотечных функций не копировался, а был доступен по адресу время выполнения (динамическое связывание).

Статическая библиотека (.a в linux, .lib в windows)

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

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

минусы:

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

Пример (Linux):

Скомпилировать файлы библиотеки:

gcc -c libmylib.c -o libmylib.o 

Создать статическую библиотеку:

ar rcs libmylib.a libmylib.o 

Скомпилируйте программу драйвера:

gcc -c driver.c -o driver.o

Свяжите скомпилированную программу драйвера со статической библиотекой. Обратите внимание, что -L передал путь к статической библиотеке, -l передал имя библиотеки при компоновке (имя * в lib * .a).

gcc -o driver driver.o -L. -lmylib

Или прямо из исходного файла:

gcc driver.c -L. -lmylib -o driver

Запускаем программу драйвера:

./driver

Динамическая библиотека (.so в Linux, .dll в Windows)

плюсы:

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

минусы:

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

Пример (Linux):

Параметры компилятора:

-Wall: включить предупреждения. См. Справочную страницу для указанных предупреждений.
-fPIC: Директива компилятора для вывода независимого от позиции кода, характеристика, необходимая для разделяемых библиотек. См. Также «-fpic».
-shared: создать общий объект, который затем может быть связан с другими объектами для формирования исполняемого файла.
-Wl, options: передать параметры компоновщику. В этом примере компоновщику передаются следующие параметры: «-soname libctest.so.1». Имя, переданное с параметром «-o», передается в gcc.

Скомпилируйте файлы библиотеки, создайте коды объектов:

gcc -Wall -fPIC -c *.c

Создать динамическую библиотеку:

gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o

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

ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so

Скомпилируйте основную программу и свяжите с библиотекой общих объектов:

gcc -Wall -L/opt/lib prog.c -lctest -o prog

Где имя библиотеки libctest.so. (Вот почему вы должны создавать символические ссылки, иначе вы получите ошибку «/ usr / bin / ld: cannot find -lctest».)
НО! Если затем вы запустите исполняемый файл, он не будет работать, потому что вам нужно сделать один шаг перед выполнением исполняемого файла. Вам необходимо установить переменную среды LD_LIBRARY_PATH, чтобы компоновщик времени выполнения мог найти и загрузить ваш файл .so в исполняемый файл во время выполнения, например export LD_LIBRARY_PATH = / opt / lib: $ LD_LIBRARY_PATH, если ваш .so находится в / opt / lib.

Отличие статической и динамической библиотеки

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

Ссылка:

Https://www.cnblogs.com/skynet/p/3372855.html
https://www.geeksforgeeks.org/static-vs-dynamic-libraries/
https: //medium.com/@nickteixeira/how-to-explain-to-my-wife-what-i-do-gcc-main-c-dc5d48a96d24
https://medium.com/@nickteixeira / какие-статические-библиотеки-в-с-и-почему-инженеры-программисты-используют-их-eb7022d89135
https://medium.com/@nickteixeira/shared-dynamic-libraries -vs-static-libraries-sizes-in-performance-2716f5b3c826
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
http: / /www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html