Hur man använder Linuxs ar-kommando för att skapa statiska bibliotek

Använd Linuxs ar-kommando för att skapa funktionsbibliotek när du utvecklar programvara. Denna handledning visar dig hur du skapar ett statiskt bibliotek, modifierar det och använder det i ett program, komplett med exempelkod.

Kommandot ar är en riktig veteran – det har funnits sedan 1971. Namnet ar refererar till den ursprungliga avsedda användningen för verktyget, som var för att skapa arkivfiler. En arkivfil är en enda fil som fungerar som en behållare för andra filer. Ibland för många andra filer. Filer kan läggas till, tas bort från eller extraheras från arkivet. Människor som letar efter den typen av funktionalitet vänder sig inte längre till ar. Den rollen har tagits över av andra verktyg som tjära.

Kommandot ar används dock fortfarande för några specialiständamål. ar används för att skapa statiska bibliotek. Dessa används i mjukvaruutveckling. Och ar används också för att skapa paketfiler som ”.deb”-filerna som används i Debian Linux-distributionen och dess derivator som Ubuntu.

Vi kommer att gå igenom stegen som krävs för att skapa och modifiera ett statiskt bibliotek och demonstrera hur man använder biblioteket i ett program. För att göra det behöver vi ett krav som det statiska biblioteket ska uppfylla. Syftet med detta bibliotek är att koda textsträngar och att avkoda kodad text.

Observera att detta är ett snabbt och smutsigt hack för demonstrationsändamål. Använd inte den här krypteringen för något som är av värde. Det är världens enklaste substitutionschifferdär A blir B, B blir C, och så vidare.

Funktionerna cipher_encode() och cipher_decode()

Vi kommer att arbeta i en katalog som heter ”bibliotek”, och senare kommer vi att skapa en underkatalog som heter ”test.”

Vi har två filer i den här katalogen. I en textfil som heter cipher_encode.c har vi funktionen cipher_encode():

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

} // end of cipher_encode

Motsvarande cipher_decode()-funktion finns i en textfil som heter cipher_decode.c:

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

} // end of cipher_decode

Filer som innehåller programmeringsinstruktioner kallas källkodsfiler. Vi ska göra en biblioteksfil som heter libcipher.a. Den kommer att innehålla de kompilerade versionerna av dessa två källkodsfiler. Vi kommer också att skapa en kort textfil som heter libcipher.h. Detta är en rubrikfil som innehåller definitionerna av de två funktionerna i vårt nya bibliotek.

Alla som har biblioteket och rubrikfilen kommer att kunna använda de två funktionerna i sina egna program. De behöver inte återuppfinna hjulet och skriva om funktionerna; de använder sig helt enkelt av kopiorna i vårt bibliotek.

Kompilera filerna cipher_encode.c och cipher_decode.c

För att kompilera källkodsfilerna kommer vi att använda gcc, den standard GNU-kompilator. Alternativet -c (kompilera, ingen länk) säger åt gcc att kompilera filerna och sedan stoppa. Den producerar en mellanliggande fil från varje källkodsfil som kallas en objektfil. Gcc-linkern tar vanligtvis alla objektfiler och länkar ihop dem för att göra ett körbart program. Vi hoppar över det steget genom att använda alternativet -c. Vi behöver bara objektfilerna.

Låt oss kontrollera att vi har filerna vi tror att vi har.

ls -l

De två källkodsfilerna finns i den här katalogen. Låt oss använda gcc för att kompilera dem till objektfiler.

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

Det bör inte finnas någon utdata från gcc om allt går bra.

Detta genererar två objektfiler med samma namn som källkodsfilerna, men med tillägget ”.o”. Det här är filerna vi behöver lägga till i biblioteksfilen.

ls -l

Skapar biblioteket libcipher.a

För att skapa biblioteksfilen – som faktiskt är en arkivfil – kommer vi att använda ar.

Vi använder alternativet -c (skapa) för att skapa biblioteksfilen, alternativet -r (lägg till med ersätt) för att lägga till filerna till biblioteksfilen och alternativet -s (index) för att skapa ett index över filerna inuti biblioteksfilen.

Vi kommer att kalla biblioteksfilen libcipher.a. Vi anger det namnet på kommandoraden, tillsammans med namnen på objektfilerna vi ska lägga till i biblioteket.

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

Om vi ​​listar filerna i katalogen kommer vi att se att vi nu har en libcipher.a-fil.

ls -l

Om vi ​​använder alternativet -t (tabell) med ar kan vi se modulerna inuti biblioteksfilen.

ar -t libcipher.a

Skapar rubrikfilen libcipher.h

Filen libcipher.h kommer att inkluderas i alla program som använder biblioteket libcipher.a. Filen libcipher.h måste innehålla definitionen av de funktioner som finns i biblioteket.

För att skapa rubrikfilen måste vi skriva in funktionsdefinitionerna i en textredigerare som gedit. Namnge filen ”libcipher.h” och spara den i samma katalog som filen libcipher.a.

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

Använder libcipher Library

Det enda säkra sättet att testa vårt nya bibliotek är att skriva ett litet program för att använda det. Först gör vi en katalog som heter test.

mkdir test

Vi kopierar biblioteket och rubrikfilerna till den nya katalogen.

cp libcipher.* ./test

Vi byter till den nya katalogen.

cd test

Låt oss kontrollera att våra två filer finns här.

ls -l

Vi måste skapa ett litet program som kan använda biblioteket och bevisa att det fungerar som förväntat. Skriv in följande textrader i en editor. Spara innehållet i editorn till en fil med namnet ”test.c” i testkatalogen.

#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

Programflödet är väldigt enkelt:

Den inkluderar filen libcipher.h så att den kan se biblioteksfunktionsdefinitionerna.
Den skapar en sträng som kallas ”text” och lagrar orden ”How-To Geek loves Linux” i den.
Den skriver ut den strängen på skärmen.
den anropar cipher_encode()-funktionen för att koda strängen, och den skriver ut den kodade strängen på skärmen.
Den anropar cipher_decode() för att avkoda strängen och skriver ut den avkodade strängen på skärmen.

För att generera testprogrammet måste vi kompilera test.c-programmet och länka i biblioteket. Alternativet -o (utgång) talar om för gcc vad den ska kalla det körbara programmet som det genererar.

gcc test.c libcipher.a -o test

Om gcc tyst återgår till kommandotolken är allt bra. Låt oss nu testa vårt program. Sanningens stund:

./test

Och vi ser den förväntade produktionen. Testprogrammet skriver ut den vanliga texten skriver ut den krypterade texten och skriver sedan ut den dekrypterade texten. Den använder funktionerna i vårt nya bibliotek. Vårt bibliotek fungerar.

Framgång. Men varför stanna där?

Lägga till ytterligare en modul till biblioteket

Låt oss lägga till ytterligare en funktion till biblioteket. Vi lägger till en funktion som programmeraren kan använda för att visa versionen av biblioteket som de använder. Vi måste skapa den nya funktionen, kompilera den och lägga till den nya objektfilen till den befintliga biblioteksfilen.

Skriv in följande rader i en editor. Spara innehållet i editorn i en fil med namnet cipher_version.c, i bibliotekskatalogen.

#include 

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

} // end of cipher_version

Vi måste lägga till definitionen av den nya funktionen i rubrikfilen libcipher.h. Lägg till en ny rad längst ner i filen så att den ser ut så här:

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

Spara den modifierade filen libcipher.h.

Vi måste kompilera filen cipher_version.c så att vi har en cipher_version.o objektfil.

gcc -c cipher_version.c

Detta skapar en cipher_version.o-fil. Vi kan lägga till den nya objektfilen till biblioteket libcipher.a med följande kommando. Alternativet -v (verbose) gör att den vanligtvis tysta ar berättar för oss vad den har gjort.

ar -rsv libcipher.a cipher_version.o

Den nya objektfilen läggs till i biblioteksfilen. ar skriver ut bekräftelse. ”a” betyder ”tillagt”.

Vi kan använda alternativet -t (tabell) för att se vilka moduler som finns inuti biblioteksfilen.

ar -t libcipher.a

Det finns nu tre moduler i vår biblioteksfil. Låt oss använda den nya funktionen.

Använder funktionen cipher_version().

Låt oss ta bort det gamla biblioteket och rubrikfilen från testkatalogen, kopiera in de nya filerna och sedan byta tillbaka till testkatalogen.

Vi tar bort de gamla versionerna av filerna.

rm ./test/libcipher.*

Vi kopierar de nya versionerna till testkatalogen.

cp libcipher.* ./test

Vi byter till testkatalogen.

cd test

Och nu kan vi modifiera test.c-programmet så att det använder den nya biblioteksfunktionen.

Vi måste lägga till en ny rad i test.c-programmet som anropar cipher_version()-funktionen. Vi placerar detta före de första puts(text); linje.

#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

Spara detta som test.c. Vi kan nu kompilera den och testa att den nya funktionen fungerar.

gcc test.c libcipher.a -o test

Låt oss köra den nya versionen av testet:

Den nya funktionen fungerar. Vi kan se versionen av biblioteket i början av utdata från test.

Men det kan finnas ett problem.

Byta ut en modul i biblioteket

Detta är inte den första versionen av biblioteket; det är den andra. Vårt versionsnummer är felaktigt. Den första versionen hade ingen cipher_version() funktion i sig. Den här gör det. Så detta borde vara version ”0.0.2”. Vi måste ersätta cipher_version()-funktionen i biblioteket med en korrigerad.

Tack och lov gör ar det väldigt enkelt att göra.

Låt oss först redigera filen cipher_version.c i bibliotekskatalogen. Ändra ”Version 0.0.1 Alpha”-texten till ”Version 0.0.2 Alpha”. Det ska se ut så här:

#include 

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

} // end of cipher_version

Spara den här filen. Vi måste kompilera den igen för att skapa en ny cipher_version.o objektfil.

gcc -c cipher_version.c

Nu kommer vi att ersätta det befintliga cipher_version.o-objektet i biblioteket med vår nyligen kompilerade version.

Vi har använt alternativet -r (lägg till med ersätt) tidigare för att lägga till nya moduler till biblioteket. När vi använder den med en modul som redan finns i biblioteket kommer ar att ersätta den gamla versionen med den nya. Alternativet -s (index) kommer att uppdatera biblioteksindexet och alternativet -v (verbose) kommer att få ar att berätta vad det har gjort.

ar -rsv libcipher.a cipher_version.o

Denna gång rapporterar ar att den har ersatt modulen cipher_version.o. ”r” betyder ersatt.

Använder funktionen Uppdaterad cipher_version()

Vi bör använda vårt modifierade bibliotek och kontrollera att det fungerar.

Vi kommer att kopiera biblioteksfilerna till testkatalogen.

cp libcipher.* ./test

Vi byter till testkatalogen.

cd ./test

Vi behöver kompilera vårt testprogram igen med vårt nya bibliotek.

gcc test.c libcipher.a -o test

Och nu kan vi testa vårt program.

./test

Resultatet från testprogrammet är vad vi hade förväntat oss. Rätt versionsnummer visas i versionssträngen, och rutinerna för kryptering och dekryptering fungerar.

Ta bort moduler från ett bibliotek

Det verkar synd efter allt det, men låt oss ta bort filen cipher_version.o från biblioteksfilen.

För att göra detta använder vi alternativet -d (radera). Vi kommer också att använda alternativet -v (verbose), så att ar berättar vad den har gjort. Vi kommer också att inkludera alternativet -s (index) för att uppdatera indexet i biblioteksfilen.

ar -dsv libcipher.a cipher_version.o

ar rapporterar att den har tagit bort modulen. ”d” betyder ”raderad”.

Om vi ​​ber ar att lista modulerna i biblioteksfilen ser vi att vi är tillbaka till två moduler.

ar -t libcipher.a

Om du ska ta bort moduler från ditt bibliotek, kom ihåg att ta bort deras definition från bibliotekshuvudfilen.

Dela din kod

Bibliotek gör kod delbar på ett praktiskt men privat sätt. Alla som du ger biblioteksfilen och rubrikfilen till kan använda ditt bibliotek, men din faktiska källkod förblir privat.