Поиск по сайту:

Как использовать команду Linux ar для создания статических библиотек


Используйте команду Linux ar для создания библиотек функций при разработке программного обеспечения. В этом руководстве показано, как создать статическую библиотеку, изменить ее и использовать в программе с примерами кода.

Команда ar — настоящий ветеран, она существует с 1971 года. Название ar указывает на первоначальное предназначение инструмента — создание архивных файлов. Архивный файл — это отдельный файл, который действует как контейнер для других файлов. Иногда для многих других файлов. Файлы можно добавлять, удалять или извлекать из архива. Люди, которым нужна такая функциональность, больше не обращаются к ar. Эту роль взяли на себя другие утилиты, такие как tar.

Однако команда ar по-прежнему используется для некоторых специальных целей. ar используется для создания статических библиотек. Они используются в разработке программного обеспечения. И ar также используется для создания файлов пакетов, таких как файлы «.deb», используемые в дистрибутиве Debian Linux и его производных, таких как Ubuntu.

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

Обратите внимание, это быстрый и грязный хак для демонстрационных целей. Не используйте это шифрование ни для чего ценного. Это простейший в мире шифр замены, в котором A становится B, B становится C и так далее.

Функции cipher_encode() и cipher_decode()

Мы будем работать в каталоге под названием «библиотека», а позже создадим подкаталог под названием «тест».

У нас есть два файла в этом каталоге. В текстовом файле с именем cipher_encode.c у нас есть функция cipher_encode():

void cipher_encode(char *text)
{
 for (int i=0; text[i] != 0x0; i++) {
   text[i]++;
 }

} // end of cipher_encode

Соответствующая функция cipher_decode() находится в текстовом файле с именем cipher_decode.c:

void cipher_decode(char *text)
{
 for (int i=0; text[i] != 0x0; i++) {
   text[i]--;
 }

} // end of cipher_decode

Файлы, содержащие инструкции по программированию, называются файлами исходного кода. Мы собираемся создать файл библиотеки с именем libcipher.a. Он будет содержать скомпилированные версии этих двух файлов исходного кода. Мы также создадим короткий текстовый файл с именем libcipher.h. Это заголовочный файл, содержащий определения двух функций в нашей новой библиотеке.

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

Компиляция файлов cipher_encode.c и cipher_decode.c

Для компиляции файлов исходного кода мы будем использовать gcc, стандартный компилятор GNU. Опция -c (компилировать, без ссылки) указывает gcc скомпилировать файлы, а затем остановиться. Он создает промежуточный файл из каждого файла исходного кода, который называется объектным файлом. Компоновщик gcc обычно берет все объектные файлы и связывает их вместе, чтобы создать исполняемую программу. Мы пропускаем этот шаг, используя параметр -c. Нам нужны только объектные файлы.

Давайте проверим, что у нас есть файлы, которые, как мы думаем, у нас есть.

ls -l

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

gcc -c cipher_encode.c
gcc -c cipher_decode.c

Не должно быть никакого вывода от gcc, если все идет хорошо.

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

ls -l

Создание библиотеки libcipher.a

Чтобы создать файл библиотеки, который на самом деле является файлом архива, мы будем использовать ar.

Мы используем параметр -c (создать) для создания файла библиотеки, параметр -r (добавить с заменой) для добавления файлов в файл библиотеки и параметр Параметр -s (index) для создания индекса файлов внутри файла библиотеки.

Мы собираемся назвать файл библиотеки libcipher.a. Мы указываем это имя в командной строке вместе с именами объектных файлов, которые мы собираемся добавить в библиотеку.

ar -crs libcipher.a cipher_encode.o cipher_decode.o

Если мы перечислим файлы в каталоге, мы увидим, что теперь у нас есть файл libcipher.a.

лс -л

Если мы используем параметр -t (таблица) с ar, мы можем увидеть модули внутри файла библиотеки.

ar -t libcipher.a

Создание файла заголовка libcipher.h

Файл libcipher.h будет включен в любую программу, использующую библиотеку libcipher.a. Файл libcipher.h должен содержать определение функций, которые есть в библиотеке.

Чтобы создать заголовочный файл, мы должны ввести определения функций в текстовый редактор, такой как gedit. Назовите файл «libcipher.h» и сохраните его в том же каталоге, что и файл libcipher.a.

void cipher_encode(char *text);
void cipher_decode(char *text);

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

Единственный верный способ протестировать нашу новую библиотеку — написать небольшую программу для ее использования. Во-первых, мы создадим каталог с именем test.

mkdir test

Мы скопируем файлы библиотеки и заголовков в новый каталог.

cp libcipher.* ./test

Мы перейдем в новый каталог.

cd test

Давайте проверим, что наши два файла находятся здесь.

ls -l

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

#include <stdio.h>
#include <stdlib.h>

#include "libcipher.h"

int main(int argc, char *argv[])
{
 char text[]="How-To Geek loves Linux";

 puts(text);

 cipher_encode(text);
 puts(text);

 cipher_decode(text);
 puts(text);

 exit (0);

} // end of main

Ход программы очень прост:

  • Он включает файл libcipher.h, чтобы он мог видеть определения библиотечных функций.
  • Он создает строку с именем text и сохраняет в ней слова «How-To Geek любит Linux».
  • Он выводит эту строку на экран.
  • он вызывает функцию cipher_encode() для кодирования строки и выводит закодированную строку на экран.
  • Он вызывает cipher_decode() для декодирования строки и вывода декодированной строки на экран.

Чтобы сгенерировать программу test, нам нужно скомпилировать программу test.c и связать ее с библиотекой. Параметр -o (вывод) указывает gcc, как вызывать исполняемую программу, которую он создает.

gcc test.c libcipher.a -o test

Если gcc молча возвращает вас в командную строку, все в порядке. Теперь давайте протестируем нашу программу. Момент истины:

./test

И мы видим ожидаемый результат. Программа test печатает обычный текст, печатает зашифрованный текст, а затем распечатывает расшифрованный текст. Он использует функции в нашей новой библиотеке. Наша библиотека работает.

Успех. Но зачем останавливаться на достигнутом?

Добавление еще одного модуля в библиотеку

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

Введите следующие строки в редактор. Сохраните содержимое редактора в файл с именем cipher_version.c в каталоге library.

#include <stdio.h>

void cipher_version(void)
{
 puts("How-To Geek :: VERY INSECURE Cipher Library");
 puts("Version 0.0.1 Alpha\n");

} // end of cipher_version

Нам нужно добавить определение новой функции в заголовочный файл libcipher.h. Добавьте новую строку в конец этого файла, чтобы он выглядел так:

void cipher_encode(char *text);
void cipher_decode(char *text);
void cipher_version(void);

Сохраните измененный файл libcipher.h.

Нам нужно скомпилировать файл cipher_version.c, чтобы у нас был объектный файл cipher_version.o.

gcc -c cipher_version.c

Это создает файл cipher_version.o. Мы можем добавить новый объектный файл в библиотеку libcipher.a с помощью следующей команды. Параметр -v (подробный) заставляет обычно молчаливый ar сообщать нам, что он сделал.

ar -rsv libcipher.a cipher_version.o

Новый объектный файл добавляется в файл библиотеки. ar распечатывает подтверждение. «А» означает «добавлено».

Мы можем использовать параметр -t (таблица), чтобы увидеть, какие модули находятся внутри файла библиотеки.

ar -t libcipher.a

Теперь в файле нашей библиотеки есть три модуля. Воспользуемся новой функцией.

Использование функции cipher_version().

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

Мы удалим старые версии файлов.

rm ./test/libcipher.*

Мы скопируем новые версии в тестовый каталог.

cp libcipher.* ./test

Мы перейдем в тестовый каталог.

cd test

И теперь мы можем модифицировать программу test.c, чтобы она использовала новую библиотечную функцию.

Нам нужно добавить новую строку в программу test.c, которая вызывает функцию cipher_version(). Мы поместим его перед первой строкой puts(text);.

#include <stdio.h>
#include <stdlib.h> 

#include "libcipher.h" 

int main(int argc, char *argv[]) 
{
 char text[]="How-To Geek loves Linux"; 

 // new line added here
 cipher_version(); 

 puts(text); 
 
 cipher_encode(text); 
 puts(text); 
 
 cipher_decode(text); 
 puts(text); 

 exit (0); 

} // end of main

Сохраните это как test.c. Теперь мы можем скомпилировать его и проверить, работает ли новая функция.

gcc test.c libcipher.a -o test

Давайте запустим новую версию test:

Новая функция работает. Мы можем увидеть версию библиотеки в начале вывода из test.

Но может быть проблема.

Замена модуля в библиотеке

Это не первая версия библиотеки; это второе. Наш номер версии неверен. В первой версии не было функции cipher_version(). Этот делает. Так что это должна быть версия «0.0.2». Нам нужно заменить функцию cipher_version() в библиотеке на исправленную.

К счастью, ar делает это очень легко.

Сначала отредактируем файл cipher_version.c в каталоге library. Измените текст «Версия 0.0.1 Alpha» на «Версия 0.0.2 Alpha». Это должно выглядеть так:

#include <stdio.h>

void cipher_version(void)
{
 puts("How-To Geek :: VERY INSECURE Cipher Library");  
 puts("Version 0.0.2 Alpha\n"); 

} // end of cipher_version

Сохраните этот файл. Нам нужно скомпилировать его снова, чтобы создать новый объектный файл cipher_version.o.

gcc -c cipher_version.c

Теперь мы заменим существующий объект cipher_version.o в библиотеке нашей новой скомпилированной версией.

Ранее мы использовали параметр -r (добавить с заменой), чтобы добавить новые модули в библиотеку. Когда мы используем его с модулем, который уже существует в библиотеке, ar заменит старую версию новой. Параметр -s (index) обновит индекс библиотеки, а параметр -v  (подробный) заставит ar сообщить нам, что он сделал. .

ar -rsv libcipher.a cipher_version.o

На этот раз ar сообщает, что заменил модуль cipher_version.o. «р» означает замененный.

Использование обновленной функции cipher_version()

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

Мы скопируем файлы библиотеки в тестовый каталог.

cp libcipher.* ./test

Мы перейдем в тестовый каталог.

cd ./test

Нам нужно снова скомпилировать нашу тестовую программу с нашей новой библиотекой.

gcc test.c libcipher.a -o test

И теперь мы можем протестировать нашу программу.

./test

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

Удаление модулей из библиотеки

После всего этого кажется обидным, но давайте удалим файл cipher_version.o из файла библиотеки.

Для этого воспользуемся опцией -d (удалить). Мы также будем использовать параметр -v (подробный), чтобы ar сообщил нам, что он сделал. Мы также добавим параметр -s (index) для обновления индекса в файле библиотеки.

ar -dsv libcipher.a cipher_version.o

ar сообщает, что модуль удален. «d» означает «удалено».

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

ar -t libcipher.a

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

Поделитесь своим кодом

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

RELATED: Best Linux Laptops for Developers and Enthusiasts