Як використовувати команду ar Linux для створення статичних бібліотек

Використовуйте команду ar Linux для створення бібліотек функцій, коли ви розробляєте програмне забезпечення. Цей підручник покаже вам, як створити статичну бібліотеку, змінити її та використовувати в програмі разом із прикладом коду.

Команда ar є справжнім ветераном — вона існує з 1971 року. Назва ar посилається на початкове призначене використання інструменту, яке було для створення архівних файлів. Архівний файл – це один файл, який виконує роль контейнера для інших файлів. Іноді для багатьох інших файлів. Файли можна додавати, видаляти або витягувати з архіву. Люди, які шукають такий тип функціональності, більше не звертаються до ar. Цю роль взяли на себе інші утиліти, такі як tar.

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

Ми розглянемо кроки, необхідні для створення та зміни статичної бібліотеки, і продемонструємо, як використовувати бібліотеку в програмі. Для цього нам потрібна вимога для виконання статичної бібліотеки. Метою цієї бібліотеки є кодування рядків тексту та декодування закодованого тексту.

Зверніть увагу, це швидкий і брудний хак для демонстраційних цілей. Не використовуйте це шифрування для чогось, що має цінність. Це найпростіше у світі шифр підстановки, де A стає B, B стає C тощо.

Функції cipher_encode() і cipher_decode().

Ми будемо працювати в каталозі під назвою «бібліотека», а пізніше ми створимо підкаталог під назвою «test».

У цьому каталозі є два файли. У текстовому файлі під назвою 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. Це заголовний файл, що містить визначення двох функцій у нашій новій бібліотеці.

Будь-хто, хто має бібліотеку та файл заголовка, зможе використовувати ці дві функції у своїх власних програмах. Їм не потрібно заново винаходити велосипед і переписувати функції; вони просто використовують примірники нашої бібліотеки.

  Як транслювати, щоб Twitch з командного рядка в Linux

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

Для компіляції файлів вихідного коду ми будемо використовувати gcc, the стандартний компілятор 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 (індекс) для створення індексу файлів всередині файл бібліотеки.

Ми збираємося викликати файл бібліотеки libcipher.a. Ми надаємо це ім’я в командному рядку разом з іменами об’єктних файлів, які ми збираємося додати до бібліотеки.

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

Якщо ми перерахуємо файли в каталозі, ми побачимо, що тепер у нас є файл libcipher.a.

ls -l

Якщо ми використовуємо параметр -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» у каталозі тесту.

#include 
#include 

#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

Хід програми дуже простий:

  Як грати в Dead Rising на Linux

Він містить файл libcipher.h, щоб він міг бачити визначення функцій бібліотеки.
Він створює рядок під назвою «текст» і зберігає в ньому слова «How-To Geek loves Linux».
Він друкує цей рядок на екрані.
він викликає функцію cipher_encode() для кодування рядка і друкує закодований рядок на екран.
Він викликає cipher_decode() для декодування рядка і друкує декодований рядок на екран.

Щоб згенерувати тестову програму, нам потрібно скомпілювати програму test.c і посилання в бібліотеці. Параметр -o (виведення) повідомляє gcc, як викликати виконувану програму, яку він створює.

gcc test.c libcipher.a -o test

Якщо gcc мовчки повертає вас до командного рядка, все добре. Тепер давайте протестуємо нашу програму. Момент істини:

./test

І ми бачимо очікуваний результат. Тестова програма друкує звичайний текст, друкує зашифрований текст, а потім друкує розшифрований текст. Він використовує функції нашої нової бібліотеки. Наша бібліотека працює.

Успіх. Але чому на цьому зупинятися?

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

Додамо ще одну функцію до бібліотеки. Ми додамо функцію, яку програміст може використовувати для відображення версії бібліотеки, яку він використовує. Нам потрібно створити нову функцію, скомпілювати її та додати новий об’єктний файл до наявного файлу бібліотеки.

Введіть наступні рядки в редактор. Збережіть вміст редактора у файлі з іменем cipher_version.c у каталозі бібліотеки.

#include 

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

} // 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 
#include  

#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

Запустимо нову версію тесту:

  Як зберегти музичні компакт-диски на ПК з Linux за допомогою звукової соковижималки

Нова функція працює. Ми бачимо версію бібліотеки на початку виводу з тесту.

Але може виникнути проблема.

Заміна модуля в бібліотеці

Це не перша версія бібліотеки; це другий. Номер нашої версії неправильний. У першій версії не було функції cipher_version(). Цей робить. Отже, це має бути версія «0.0.2». Нам потрібно замінити функцію cipher_version() у бібліотеці на виправлену.

На щастя, ar робить це дуже легко.

Спочатку відредагуємо файл cipher_version.c у каталозі бібліотеки. Змініть текст «Version 0.0.1 Alpha» на «Version 0.0.2 Alpha». Це має виглядати так:

#include 

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

} // end of cipher_version

Збережіть цей файл. Нам потрібно скомпілювати його знову, щоб створити новий об’єктний файл cipher_version.o.

gcc -c cipher_version.c

Тепер ми замінимо існуючий об’єкт cipher_version.o у бібліотеці на нашу нещодавно скомпільовану версію.

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

ar -rsv libcipher.a cipher_version.o

Цього разу ar повідомляє, що він замінив модуль cipher_version.o. «r» означає замінено.

Використання оновленої функції cipher_version().

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

Ми скопіюємо файли бібліотеки в тестовий каталог.

cp libcipher.* ./test

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

cd ./test

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

gcc test.c libcipher.a -o test

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

./test

Результат тестової програми – це те, чого ми очікували. У рядку версії відображається правильний номер версії, а процедури шифрування та дешифрування працюють.

Видалення модулів з бібліотеки

Після всього цього здається прикро, але давайте видалимо файл cipher_version.o з файлу бібліотеки.

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

ar -dsv libcipher.a cipher_version.o

ar повідомляє, що він видалив модуль. «d» означає «видалено».

Якщо ми попросимо ar перерахувати модулі у файлі бібліотеки, ми побачимо, що ми повернулися до двох модулів.

ar -t libcipher.a

Якщо ви збираєтеся видалити модулі зі своєї бібліотеки, не забудьте видалити їх визначення із заголовного файлу бібліотеки.

Поділіться своїм кодом

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