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

Так что же такое статические библиотеки? Библиотека — это файл, содержащий несколько объектных файлов, которые можно использовать как единое целое на этапе компоновки программы. Проще говоря, библиотека содержит кучу различных объектных файлов (скомпилированных файлов C). Мы можем использовать эту библиотеку в любом другом файле, и на этапе компиляции программа будет знать, что нужно получить доступ к библиотеке.

Как мы создаем библиотеку? На картинке вы можете видеть, что у нас есть множество разных C-файлов, а также заголовочный файл (holberton.h), который содержит все различные прототипы функций.

Первое, что нам нужно сделать, это создать объектные файлы, чтобы связать их вместе в библиотеке. Мы будем использовать команду gcc (что такое команда gcc?) для компиляции наших файлов.

gcc -Wall -pedantic -Werror -Wextra -c *.c

Подстановочный знак звездочки (что такое подстановочный знак?) компилирует сразу все .c файлов, вместо того, чтобы писать команду отдельно для каждого файла. После запуска этой команды у нас теперь будут файлы с расширением .o (объектные файлы), а также исходные файлы.

Теперь, когда у нас есть все наши объектные файлы, пришло время создать библиотеку, чтобы соединить их все вместе. Мы будем использовать команду ar. Что делает эта команда? Давайте заглянем в справочную страницу этой команды — «Программа GNU ar создает, изменяет и извлекает из архивов. Архив — это отдельный файл, содержащий набор других файлов в структуре, позволяющей восстановить исходные отдельные файлы». Структура этой команды выглядит так — ar [OPTIONS] archive_name member_files.

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

ar -rc libmylibrary.a *.o — необходимы оба флага ‘r’ и ‘c’. Флаг ‘r’ указывает программе добавлять новые файлы, если они еще не существуют, и обновлять их, если они существуют. Рекомендуется использовать этот флаг при использовании команды ar. Назначение флагов 'c' — сообщить программе, что мы создаем библиотеку в первый раз. После создания библиотеки предлагается проиндексировать ее с помощью команды ranlib libmylibrary.a. Это создает индекс содержимого библиотеки и сохраняет его внутри. Использование этого ускоряет этап компоновки компиляции.

Поздравляю! Наконец-то у нас есть полезная библиотека. Мы можем взглянуть на его содержимое, используя команду nm как таковую — nm libmylibrary.a. Это отобразит таблицу символов каждого объектного файла в библиотеке. Это также можно сделать с помощью флага ar -t.

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

Мы создадим очень простой файл C только с одной основной функцией.

int main(void)
{
    print_alphabet();
    return 0;
}

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

  • -l ‹имя библиотеки без префикса и расширения lib
  • -Lс путем или, в нашем случае, символом ., чтобы указать, что библиотека находится в текущем рабочем каталоге.

Наша последняя команда будет выглядеть как gcc main.c -L. -lmylibrary -o main.

После запуска скомпилированного файла, который мы только что создали с помощью — ./main, мы получим вывод abcdefghijklmnopqrstuv. Это сработало!