Jak używać polecenia ar Linuksa do tworzenia bibliotek statycznych

Użyj polecenia ar Linuksa, aby utworzyć biblioteki funkcji podczas tworzenia oprogramowania. Ten samouczek pokaże, jak utworzyć bibliotekę statyczną, zmodyfikować ją i użyć w programie, wraz z przykładowym kodem.

Polecenie ar to prawdziwy weteran – istnieje od 1971 roku. Nazwa ar nawiązuje do pierwotnego zamierzonego zastosowania narzędzia, którym było do tworzenia plików archiwalnych. Plik archiwum to pojedynczy plik, który działa jako kontener dla innych plików. Czasami dla wielu innych plików. Pliki można dodawać, usuwać lub wyodrębniać z archiwum. Osoby szukające tego typu funkcjonalności nie zwracają się już ku ar. Rola ta została przejęta przez inne narzędzia, takie jak tar.

Jednak polecenie ar jest nadal używane do kilku celów specjalistycznych. ar służy do tworzenia bibliotek statycznych. Są one używane w tworzeniu oprogramowania. Ar jest również używany do tworzenia plików pakietów, takich jak „.deb” używanych w dystrybucji Debian Linux i jego pochodnych, takich jak Ubuntu.

Przeprowadzimy kroki wymagane do utworzenia i zmodyfikowania biblioteki statycznej oraz zademonstrujemy, jak używać tej biblioteki w programie. Aby to zrobić, potrzebujemy wymagania, aby biblioteka statyczna spełniała. Celem tej biblioteki jest kodowanie ciągów tekstu i dekodowanie zakodowanego tekstu.

Należy pamiętać, że jest to szybki i brudny hack do celów demonstracyjnych. Nie używaj tego szyfrowania do niczego, co ma wartość. To najprostszy na świecie szyfr podstawieniowy, gdzie A staje się B, B staje się C i tak dalej.

Funkcje cipher_encode () i cipher_decode ()

Będziemy pracować w katalogu o nazwie „biblioteka”, a później utworzymy podkatalog o nazwie „test”.

W tym katalogu mamy dwa pliki. W pliku tekstowym o nazwie cipher_encode.c mamy funkcję cipher_encode ():

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

} // end of cipher_encode

Odpowiednia funkcja cipher_decode () znajduje się w pliku tekstowym o nazwie cipher_decode.c:

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

} // end of cipher_decode

Pliki zawierające instrukcje programowe nazywane są plikami kodu źródłowego. Zamierzamy utworzyć plik biblioteki o nazwie libcipher.a. Będzie zawierał skompilowane wersje tych dwóch plików z kodem źródłowym. Stworzymy również krótki plik tekstowy o nazwie libcipher.h. To jest plik nagłówkowy zawierający definicje dwóch funkcji w naszej nowej bibliotece.

Każdy, kto ma bibliotekę i plik nagłówkowy, będzie mógł używać tych dwóch funkcji we własnych programach. Nie muszą ponownie wymyślać koła i ponownie pisać funkcji; po prostu korzystają z kopii w naszej bibliotece.

Kompilowanie plików cipher_encode.c i cipher_decode.c

Aby skompilować pliki z kodem źródłowym, użyjemy gcc, the standardowy kompilator GNU. Opcja -c (kompilacja, brak łącza) nakazuje gcc skompilować pliki, a następnie zatrzymać. Tworzy plik pośredni z każdego pliku kodu źródłowego zwanego plikiem obiektowym. Konsolidator gcc zwykle pobiera wszystkie pliki obiektowe i łączy je ze sobą, tworząc program wykonywalny. Pomijamy ten krok, używając opcji -c. Potrzebujemy tylko plików obiektowych.

Sprawdźmy, czy mamy pliki, które naszym zdaniem mamy.

ls -l

Znajduje się w oknie terminala

W tym katalogu znajdują się dwa pliki kodu źródłowego. Użyjmy gcc, aby skompilować je do plików obiektowych.

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

Jeśli wszystko pójdzie dobrze, gcc nie powinno wychodzić.

wyjście z gcc w oknie terminala

Spowoduje to wygenerowanie dwóch plików obiektowych o tej samej nazwie co pliki kodu źródłowego, ale z rozszerzeniami „.o”. To są pliki, które musimy dodać do pliku biblioteki.

ls -l

wyjście z ls -l w oknie terminala

Tworzenie biblioteki libcipher.a

Aby utworzyć plik biblioteki – który w rzeczywistości jest plikiem archiwum – użyjemy ar.

Używamy opcji -c (utwórz), aby utworzyć plik biblioteki, opcji -r (dodaj z zastąpieniem), aby dodać pliki do pliku biblioteki, oraz opcji -s (indeks), aby utworzyć indeks plików wewnątrz plik biblioteki.

Nazwiemy plik biblioteki libcipher.a. Nazwę tę podajemy w linii poleceń wraz z nazwami plików obiektowych, które zamierzamy dodać do biblioteki.

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

ar -crs libcipher.a cipher_encode.o cipher_decode.o w oknie terminala

Jeśli wymienimy pliki w katalogu, zobaczymy, że mamy teraz plik libcipher.a.

ls -l

wyjście ls w oknie terminala

Jeśli użyjemy opcji -t (tabela) z ar, możemy zobaczyć moduły wewnątrz pliku biblioteki.

ar -t libcipher.a

ar -t libcipher.a w oknie terminala

Tworzenie pliku nagłówkowego libcipher.h

Plik libcipher.h zostanie dołączony do każdego programu korzystającego z biblioteki libcipher.a. Plik libcipher.h musi zawierać definicję funkcji znajdujących się w bibliotece.

Aby utworzyć plik nagłówkowy, musimy wpisać definicje funkcji do edytora tekstu, takiego jak gedit. Nazwij plik „libcipher.h” i zapisz go w tym samym katalogu, co plik libcipher.a.

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

Korzystanie z biblioteki libcipher

Jedynym pewnym sposobem przetestowania naszej nowej biblioteki jest napisanie małego programu, który będzie z niej korzystać. Najpierw utworzymy katalog o nazwie test.

mkdir test

Skopiujemy bibliotekę i pliki nagłówkowe do nowego katalogu.

cp libcipher.* ./test

Przejdziemy do nowego katalogu.

cd test

Sprawdźmy, czy są tutaj nasze dwa pliki.

ls -l

cp libcipher. * ./test w oknie terminala

Musimy stworzyć mały program, który będzie mógł korzystać z biblioteki i udowodnić, że działa zgodnie z oczekiwaniami. Wpisz następujące wiersze tekstu w edytorze. Zapisz zawartość edytora do pliku o nazwie „test.c” w katalogu test.

#include 
#include 

#include "libcipher.h"

int main(int argc, char *argv[])
{
 char text[]="newsblog.pl loves Linux";

 puts(text);

 cipher_encode(text);
 puts(text);

 cipher_decode(text);
 puts(text);

 exit (0);

} // end of main

Przebieg programu jest bardzo prosty:

Zawiera plik libcipher.h, dzięki czemu można zobaczyć definicje funkcji biblioteki.
Tworzy ciąg o nazwie „tekst” i przechowuje w nim słowa „newsblog.pl loves Linux”.
Drukuje ten ciąg na ekranie.
wywołuje funkcję cipher_encode () w celu zakodowania łańcucha i wypisuje zakodowany łańcuch na ekranie.
Wywołuje cipher_decode () w celu zdekodowania ciągu i wypisuje zdekodowany ciąg na ekranie.

Aby wygenerować program testowy, musimy skompilować program test.c i dowiązać do biblioteki. Opcja -o (wyjście) mówi gcc, co ma wywołać program wykonywalny, który generuje.

gcc test.c libcipher.a -o test

gcc test.c libcipher.a -o test w oknie terminala

Jeśli gcc po cichu powróci do wiersza poleceń, wszystko jest w porządku. Przetestujmy teraz nasz program. Moment prawdy:

./test

./test w oknie terminala

I widzimy oczekiwany wynik. Program testowy drukuje zwykły tekst, drukuje zaszyfrowany tekst, a następnie drukuje odszyfrowany tekst. Korzysta z funkcji w naszej nowej bibliotece. Nasza biblioteka działa.

wyjście programu testowego w oknie terminala

Powodzenie. Ale po co na tym poprzestać?

Dodawanie kolejnego modułu do biblioteki

Dodajmy do biblioteki kolejną funkcję. Dodamy funkcję, której programista może użyć do wyświetlenia wersji biblioteki, której używa. Będziemy musieli stworzyć nową funkcję, skompilować ją i dodać nowy plik obiektu do istniejącego pliku biblioteki.

Wpisz następujące wiersze w edytorze. Zapisz zawartość edytora do pliku o nazwie cipher_version.c, w katalogu biblioteki.

#include 

void cipher_version(void)
{
 puts("newsblog.pl :: VERY INSECURE Cipher Library");
 puts("Version 0.0.1 Alphan");

} // end of cipher_version

Musimy dodać definicję nowej funkcji do pliku nagłówkowego libcipher.h. Dodaj nowy wiersz na dole tego pliku, tak aby wyglądał tak:

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

Zapisz zmodyfikowany plik libcipher.h.

Musimy skompilować plik cipher_version.c, aby uzyskać plik obiektowy cipher_version.o.

gcc -c cipher_version.c

gcc -c cipher_version.c w oknie terminala

Spowoduje to utworzenie pliku cipher_version.o. Możemy dodać nowy plik obiektowy do biblioteki libcipher.a za pomocą następującego polecenia. Opcja -v (gadatliwa) sprawia, że ​​zwykle milczący ar mówi nam, co zrobił.

ar -rsv libcipher.a cipher_version.o

ar -rsv libcipher.a cipher_version.o w oknie terminala

Nowy plik obiektu zostanie dodany do pliku biblioteki. ar drukuje potwierdzenie. „A” oznacza „dodane”.

wyjście z ar w oknie terminala

Możemy użyć opcji -t (tabela), aby zobaczyć, jakie moduły znajdują się w pliku biblioteki.

ar -t libcipher.a

ar -t libcipher.a w oknie terminala

W naszym pliku biblioteki znajdują się teraz trzy moduły. Skorzystajmy z nowej funkcji.

Korzystanie z funkcji cipher_version ().

Usuńmy starą bibliotekę i plik nagłówkowy z katalogu testowego, skopiujmy nowe pliki, a następnie wróćmy do katalogu testowego.

Usuniemy stare wersje plików.

rm ./test/libcipher.*

Skopiujemy nowe wersje do katalogu testowego.

cp libcipher.* ./test

Przejdziemy do katalogu testowego.

cd test

rm ./test/libcipher.* w oknie terminala

Teraz możemy zmodyfikować program test.c, aby używał nowej funkcji biblioteki.

Musimy dodać nową linię do programu test.c, który wywoła funkcję cipher_version (). Umieścimy to przed pierwszym wstawieniem (tekst); linia.

#include 
#include  

#include "libcipher.h" 

int main(int argc, char *argv[]) 
{
 char text[]="newsblog.pl 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

Zapisz to jako test. C. Teraz możemy go skompilować i sprawdzić, czy nowa funkcja działa.

gcc test.c libcipher.a -o test

gcc test.c libcipher.a -o test w oknie terminala

Uruchommy nową wersję testu:

wyjście z programu testowego w oknie terminala

Nowa funkcja działa. Wersję biblioteki możemy zobaczyć na początku wyjścia z testu.

Ale może być problem.

Zastępowanie modułu w bibliotece

To nie jest pierwsza wersja biblioteki; to jest druga. Nasz numer wersji jest nieprawidłowy. Pierwsza wersja nie zawierała funkcji cipher_version (). Ten ma. Więc to powinna być wersja „0.0.2”. Musimy zamienić funkcję cipher_version () w bibliotece na poprawioną.

Na szczęście ar sprawia, że ​​jest to bardzo łatwe.

Najpierw edytujmy plik cipher_version.c w katalogu biblioteki. Zmień tekst „Wersja 0.0.1 Alfa” na „Wersja 0.0.2 Alfa”. To powinno wyglądać tak:

#include 

void cipher_version(void)
{
 puts("newsblog.pl :: VERY INSECURE Cipher Library");  
 puts("Version 0.0.2 Alphan"); 

} // end of cipher_version

Zapisz ten plik. Musimy go ponownie skompilować, aby utworzyć nowy plik obiektowy cipher_version.o.

gcc -c cipher_version.c

gcc -c cipher_version.c w oknie terminala

Teraz zastąpimy istniejący obiekt cipher_version.o w bibliotece naszą nowo skompilowaną wersją.

Wcześniej używaliśmy opcji -r (dodaj z zamianą), aby dodać nowe moduły do ​​biblioteki. Kiedy użyjemy go z modułem, który już istnieje w bibliotece, ar zastąpi starą wersję nową. Opcja -s (indeks) zaktualizuje indeks biblioteki, a opcja -v (szczegółowa) sprawi, że ar powie nam, co zrobił.

ar -rsv libcipher.a cipher_version.o

ar -rsv libcipher.a cipher_version.o w oknie terminala

Tym razem ar donosi, że zastąpił on moduł cipher_version.o. Litera „r” oznacza zastąpienie.

ar w oknie terminala

Korzystanie z zaktualizowanej funkcji cipher_version ()

Powinniśmy skorzystać z naszej zmodyfikowanej biblioteki i sprawdzić, czy działa.

Skopiujemy pliki biblioteki do katalogu testowego.

cp libcipher.* ./test

Przejdziemy do katalogu testowego.

cd ./test

Musimy ponownie skompilować nasz program testowy z naszą nową biblioteką.

gcc test.c libcipher.a -o test

A teraz możemy przetestować nasz program.

./test

cp libcipher. * ./test w oknie terminala

Wynik programu testowego jest taki, jakiego się spodziewaliśmy. W ciągu wersji jest wyświetlany poprawny numer wersji, a procedury szyfrowania i deszyfrowania działają.

Usuwanie modułów z biblioteki

Po tym wszystkim wydaje się szkoda, ale usuńmy plik cipher_version.o z pliku biblioteki.

Aby to zrobić, użyjemy opcji -d (usuń). Użyjemy również opcji -v (verbose), aby ar mówił nam, co zrobił. Dodamy również opcję -s (indeks), aby zaktualizować indeks w pliku biblioteki.

ar -dsv libcipher.a cipher_version.o

ar -dsv libcipher.a cipher_version.o w oknie terminala

ar zgłasza, że ​​usunął moduł. Litera „d” oznacza „usunięte”.

Jeśli poprosimy ar, aby wyświetlić listę modułów w pliku biblioteki, zobaczymy, że wróciliśmy do dwóch modułów.

ar -t libcipher.a

ar -t libcipher.a w oknie terminala

Jeśli zamierzasz usunąć moduły ze swojej biblioteki, pamiętaj o usunięciu ich definicji z pliku nagłówkowego biblioteki.

Udostępnij swój kod

Biblioteki umożliwiają udostępnianie kodu w praktyczny, ale prywatny sposób. Każdy, komu przekażesz plik biblioteki i plik nagłówkowy, może korzystać z Twojej biblioteki, ale rzeczywisty kod źródłowy pozostaje prywatny.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *