Come utilizzare il comando ar di Linux per creare librerie statiche

Usa il comando ar di Linux per creare librerie di funzioni quando sviluppi software. Questo tutorial ti mostrerà come creare una libreria statica, modificarla e usarla in un programma, completa di codice di esempio.

Il comando ar è un vero veterano: esiste dal 1971. Il nome ar fa riferimento all’uso originale previsto per lo strumento, che era per creare file di archivio. Un file di archivio è un singolo file che funge da contenitore per altri file. A volte per molti altri file. I file possono essere aggiunti, rimossi o estratti dall’archivio. Le persone alla ricerca di quel tipo di funzionalità non si rivolgono più ad ar. Questo ruolo è stato assunto da altre utility come tar.

Tuttavia, il comando ar è ancora utilizzato per alcuni scopi specialistici. ar viene utilizzato per creare librerie statiche. Questi sono usati nello sviluppo del software. E ar viene anche usato per creare file di pacchetti come i file “.deb” usati nella distribuzione Debian Linux e nei suoi derivati ​​come Ubuntu.

Eseguiremo i passaggi necessari per creare e modificare una libreria statica e dimostreremo come utilizzare la libreria in un programma. Per fare ciò abbiamo bisogno di un requisito che la libreria statica soddisfi. Lo scopo di questa libreria è codificare stringhe di testo e decodificare testo codificato.

Si prega di notare che questo è un trucco rapido e sporco a scopo dimostrativo. Non utilizzare questa crittografia per tutto ciò che è di valore. È il più semplice del mondo cifratura di sostituzione, dove A diventa B, B diventa C e così via.

Le funzioni cipher_encode () e cipher_decode ()

Lavoreremo in una directory chiamata “library” e in seguito creeremo una sottodirectory chiamata “test”.

Abbiamo due file in questa directory. In un file di testo chiamato cipher_encode.c abbiamo la funzione cipher_encode ():

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

} // end of cipher_encode

La corrispondente funzione cipher_decode () si trova in un file di testo chiamato cipher_decode.c:

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

} // end of cipher_decode

I file che contengono istruzioni di programmazione sono chiamati file di codice sorgente. Creeremo un file di libreria chiamato libcipher.a. Conterrà le versioni compilate di questi due file di codice sorgente. Creeremo anche un breve file di testo chiamato libcipher.h. Questo è un file di intestazione contenente le definizioni delle due funzioni nella nostra nuova libreria.

Chiunque disponga della libreria e del file di intestazione potrà utilizzare le due funzioni nei propri programmi. Non hanno bisogno di reinventare la ruota e riscrivere le funzioni; fanno semplicemente uso delle copie nella nostra libreria.

Compilazione dei file cipher_encode.c e cipher_decode.c

Per compilare i file del codice sorgente, useremo gcc, il compilatore GNU standard. L’opzione -c (compile, no link) dice a gcc di compilare i file e poi fermarsi. Produce un file intermedio da ogni file di codice sorgente chiamato file oggetto. Il linker gcc di solito prende tutti i file oggetto e li collega insieme per creare un programma eseguibile. Stiamo saltando questo passaggio utilizzando l’opzione -c. Abbiamo solo bisogno dei file oggetto.

Controlliamo di avere i file che pensiamo di avere.

ls -l

I due file di codice sorgente sono presenti in questa directory. Usiamo gcc per compilarli in file oggetto.

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

Non dovrebbe esserci alcun output da gcc se tutto va bene.

output da gcc in una finestra di terminale

Questo genera due file oggetto con lo stesso nome dei file del codice sorgente, ma con estensioni “.o”. Questi sono i file che dobbiamo aggiungere al file della libreria.

ls -l

output da ls -l in una finestra di terminale

Creazione della libreria libcipher.a

Per creare il file di libreria, che in realtà è un file di archivio, useremo ar.

Stiamo usando l’opzione -c (crea) per creare il file della libreria, l’opzione -r (aggiungi con sostituisci) per aggiungere i file al file della libreria e l’opzione -s (index) per creare un indice dei file all’interno il file della libreria.

Chiameremo il file della libreria libcipher.a. Forniamo quel nome sulla riga di comando, insieme ai nomi dei file oggetto che aggiungeremo alla libreria.

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

ar -crs libcipher.a cipher_encode.o cipher_decode.o in una finestra di terminale

Se elenchiamo i file nella directory, vedremo che ora abbiamo un file libcipher.a.

ls -l

output di ls in una finestra di terminale

Se usiamo l’opzione -t (table) con ar possiamo vedere i moduli all’interno del file della libreria.

ar -t libcipher.a

ar -t libcipher.a in una finestra di terminale

Creazione del file di intestazione libcipher.h

Il file libcipher.h sarà incluso in qualsiasi programma che utilizzi la libreria libcipher.a. Il file libcipher.h deve contenere la definizione delle funzioni che si trovano nella libreria.

Per creare il file di intestazione, dobbiamo digitare le definizioni di funzione in un editor di testo come gedit. Assegnare un nome al file “libcipher.h” e salvarlo nella stessa directory del file libcipher.a.

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

Utilizzando la libreria libcipher

L’unico modo sicuro per testare la nostra nuova libreria è scrivere un programmino per usarla. Per prima cosa, creeremo una directory chiamata test.

mkdir test

Copieremo la libreria e i file di intestazione nella nuova directory.

cp libcipher.* ./test

Passeremo alla nuova directory.

cd test

Controlliamo che i nostri due file siano qui.

ls -l

cp libcipher. * ./test in una finestra di terminale

Dobbiamo creare un piccolo programma che possa utilizzare la libreria e dimostrare che funziona come previsto. Digita le seguenti righe di testo in un editor. Salvare il contenuto dell’editor in un file denominato “test.c” nella directory di test.

#include 
#include 

#include "libcipher.h"

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

 puts(text);

 cipher_encode(text);
 puts(text);

 cipher_decode(text);
 puts(text);

 exit (0);

} // end of main

Il flusso del programma è molto semplice:

Include il file libcipher.h in modo che possa vedere le definizioni delle funzioni di libreria.
Crea una stringa chiamata “testo” e memorizza le parole “winadmin.it loves Linux” in essa.
Stampa quella stringa sullo schermo.
chiama la funzione cipher_encode () per codificare la stringa e stampa la stringa codificata sullo schermo.
Chiama cipher_decode () per decodificare la stringa e stampa la stringa decodificata sullo schermo.

Per generare il programma di test, dobbiamo compilare il programma test.c e collegarlo alla libreria. L’opzione -o (output) dice a gcc come chiamare il programma eseguibile che genera.

gcc test.c libcipher.a -o test

gcc test.c libcipher.a -o test in una finestra di terminale

Se gcc ti riporta silenziosamente al prompt dei comandi, va tutto bene. Ora testiamo il nostro programma. Momento della verità:

./test

./test in una finestra di terminale

E vediamo l’output previsto. Il programma di test stampa il testo normale stampa il testo crittografato e quindi stampa il testo decrittografato. Utilizza le funzioni all’interno della nostra nuova libreria. La nostra biblioteca sta funzionando.

output del programma di test in una finestra di terminale

Successo. Ma perché fermarsi qui?

Aggiunta di un altro modulo alla libreria

Aggiungiamo un’altra funzione alla libreria. Aggiungeremo una funzione che il programmatore può utilizzare per visualizzare la versione della libreria che sta utilizzando. Avremo bisogno di creare la nuova funzione, compilarla e aggiungere il nuovo file oggetto al file di libreria esistente.

Digita le seguenti righe in un editor. Salvare i contenuti dell’editor in un file denominato cipher_version.c, nella directory della libreria.

#include 

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

} // end of cipher_version

Dobbiamo aggiungere la definizione della nuova funzione al file di intestazione libcipher.h. Aggiungi una nuova riga in fondo a quel file, in modo che assomigli a questo:

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

Salva il file libcipher.h modificato.

Abbiamo bisogno di compilare il file cipher_version.c in modo da avere un file oggetto cipher_version.o.

gcc -c cipher_version.c

gcc -c cipher_version.c in una finestra di terminale

Questo crea un file cipher_version.o. Possiamo aggiungere il nuovo file oggetto alla libreria libcipher.a con il seguente comando. L’opzione -v (verbose) fa sì che l’ar solitamente silenzioso ci dica cosa ha fatto.

ar -rsv libcipher.a cipher_version.o

ar -rsv libcipher.a cipher_version.o in una finestra di terminale

Il nuovo file oggetto viene aggiunto al file della libreria. ar stampa la conferma. La “a” significa “aggiunto”.

output da ar in una finestra di terminale

Possiamo usare l’opzione -t (tabella) per vedere quali moduli sono all’interno del file della libreria.

ar -t libcipher.a

ar -t libcipher.a in una finestra di terminale

Ora ci sono tre moduli all’interno del nostro file di libreria. Usiamo la nuova funzione.

Utilizzo della funzione cipher_version ().

Rimuoviamo la vecchia libreria e il file di intestazione dalla directory di test, copiamo nei nuovi file e quindi torniamo alla directory di test.

Elimineremo le vecchie versioni dei file.

rm ./test/libcipher.*

Copieremo le nuove versioni nella directory di test.

cp libcipher.* ./test

Passeremo alla directory di test.

cd test

rm ./test/libcipher.* in una finestra di terminale

E ora possiamo modificare il programma test.c in modo che utilizzi la nuova funzione di libreria.

Dobbiamo aggiungere una nuova riga al programma test.c che chiama la funzione cipher_version (). Lo posizioneremo prima del primo put (testo); linea.

#include 
#include  

#include "libcipher.h" 

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

Salvalo come test.c. Ora possiamo compilarlo e verificare che la nuova funzione sia operativa.

gcc test.c libcipher.a -o test

gcc test.c libcipher.a -o test in una finestra di terminale

Eseguiamo la nuova versione di test:

output dal programma di test in una finestra di terminale

La nuova funzione sta funzionando. Possiamo vedere la versione della libreria all’inizio dell’output di test.

Ma potrebbe esserci un problema.

Sostituzione di un modulo nella libreria

Questa non è la prima versione della libreria; è il secondo. Il nostro numero di versione non è corretto. La prima versione non aveva la funzione cipher_version () al suo interno. Questo lo fa. Quindi questa dovrebbe essere la versione “0.0.2”. Dobbiamo sostituire la funzione cipher_version () nella libreria con una corretta.

Per fortuna, ar lo rende molto facile da fare.

Per prima cosa, modifichiamo il file cipher_version.c nella directory della libreria. Modificare il testo “Versione 0.0.1 Alpha” in “Versione 0.0.2 Alpha”. Dovrebbe sembrare come questo:

#include 

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

} // end of cipher_version

Salva questo file. Dobbiamo compilarlo di nuovo per creare un nuovo file oggetto cipher_version.o.

gcc -c cipher_version.c

gcc -c cipher_version.c in una finestra di terminale

Ora sostituiremo l’oggetto cipher_version.o esistente nella libreria con la nostra versione appena compilata.

Abbiamo già utilizzato l’opzione -r (aggiungi con sostituzione) per aggiungere nuovi moduli alla libreria. Quando lo usiamo con un modulo che già esiste nella libreria, ar sostituirà la vecchia versione con quella nuova. L’opzione -s (index) aggiornerà l’indice della libreria e l’opzione -v (verbose) farà in modo che ar ci dica cosa ha fatto.

ar -rsv libcipher.a cipher_version.o

ar -rsv libcipher.a cipher_version.o in una finestra di terminale

Questa volta ar segnala di aver sostituito il modulo cipher_version.o. La “r” significa sostituito.

ar output in una finestra di terminale

Utilizzo della funzione cipher_version () aggiornata

Dovremmo usare la nostra libreria modificata e verificare che funzioni.

Copieremo i file della libreria nella directory di test.

cp libcipher.* ./test

Passeremo alla directory di test.

cd ./test

Dobbiamo compilare nuovamente il nostro programma di test con la nostra nuova libreria.

gcc test.c libcipher.a -o test

E ora possiamo testare il nostro programma.

./test

cp libcipher. * ./test in una finestra di terminale

L’output del programma di test è quello che ci aspettavamo. Il numero di versione corretto viene visualizzato nella stringa della versione e le routine di crittografia e decrittografia funzionano.

Eliminazione di moduli da una libreria

Sembra un peccato dopo tutto questo, ma cancelliamo il file cipher_version.o dal file della libreria.

Per fare ciò, useremo l’opzione -d (elimina). Useremo anche l’opzione -v (verbose), in modo che ar ci dica cosa ha fatto. Includeremo anche l’opzione -s (index) per aggiornare l’indice nel file della libreria.

ar -dsv libcipher.a cipher_version.o

ar -dsv libcipher.a cipher_version.o in una finestra di terminale

ar segnala di aver rimosso il modulo. La “d” significa “cancellato”.

Se chiediamo ad ar di elencare i moduli all’interno del file della libreria, vedremo che siamo tornati a due moduli.

ar -t libcipher.a

ar -t libcipher.a in una finestra di terminale

Se hai intenzione di eliminare moduli dalla tua libreria, ricordati di rimuovere la loro definizione dal file di intestazione della libreria.

Condividi il tuo codice

Le biblioteche rendono il codice condivisibile in modo pratico ma privato. Chiunque fornisca il file della libreria e il file di intestazione può utilizzare la libreria, ma il codice sorgente effettivo rimane privato.