Как да използвате командата 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. Това е заглавен файл, съдържащ дефинициите на двете функции в новата ни библиотека.

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

  Как да инсталирате Adobe Creative Cloud приложения на 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

Програмният поток е много прост:

  4-те най-добри текстови редактора за разработчици на 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

Нека стартираме новата версия на теста:

  Как да използвате usermod за добавяне на потребители към групи в Linux

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

Но може да има проблем.

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

Това не е първата версия на библиотеката; това е второто. Номерът на нашата версия е неправилен. Първата версия нямаше функция 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“ означава заменен.

Използване на функцията Updated 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

Ако възнамерявате да изтриете модули от вашата библиотека, не забравяйте да премахнете тяхната дефиниция от заглавния файл на библиотеката.

Споделете своя код

Библиотеките правят кода споделен по практичен, но частен начин. Всеки, на когото дадете библиотечния файл и заглавния файл, може да използва вашата библиотека, но действителният ви изходен код остава частен.