GNU/Linux >> Linux Esercitazione >  >> Linux

Introduzione alle librerie condivise Linux (come creare librerie condivise)

Una libreria è un file contenente codice compilato da vari file oggetto inseriti in un unico file. Può contenere un gruppo di funzioni utilizzate in un contesto particolare. Ad esempio, la libreria 'pthread' viene utilizzata quando le funzioni relative ai thread devono essere utilizzate nel programma.

In generale, una libreria (o libreria di programmi) può essere di due tipi:

  1. Libreria condivisa
  2. Libreria statica

In questo articolo parleremo in modo specifico delle biblioteche condivise.

Biblioteche condivise

Le librerie condivise sono le librerie che possono essere collegate a qualsiasi programma in fase di esecuzione. Forniscono un mezzo per utilizzare codice che può essere caricato ovunque nella memoria. Una volta caricato, il codice della libreria condivisa può essere utilizzato da un numero qualsiasi di programmi. Quindi, in questo modo la dimensione dei programmi (usando la libreria condivisa) e l'ingombro di memoria possono essere mantenuti bassi poiché molto codice viene mantenuto comune sotto forma di una libreria condivisa.

Le librerie condivise forniscono modularità all'ambiente di sviluppo poiché il codice della libreria può essere modificato, modificato e ricompilato senza dover ricompilare le applicazioni che utilizzano questa libreria. Ad esempio, per qualsiasi modifica nel codice della libreria pthread, non è richiesta alcuna modifica nei programmi che utilizzano la libreria condivisa pthread. È possibile accedere a una libreria condivisa tramite nomi diversi:

  • Nome utilizzato dal linker ("lib" seguito dal nome della libreria, seguito da ".so" . Ad esempio libpthread.so)
  • Nome completo o soname ("lib" seguito dal nome della libreria, seguito da ".so", seguito da "." e un numero di versione. Ad esempio:libpthread.so.1)
  • Nome reale ('lib' seguito dal nome della libreria, seguito da '.so', seguito da '.' e un numero di versione, seguito da '.' e un numero minore, seguito da '.' e un numero di versione. Il numero di versione è facoltativo. Ad esempio, libpthread.so.1.1)

Un numero di versione viene modificato per una libreria condivisa quando le modifiche apportate al codice rendono la libreria condivisa incompatibile con la versione precedente. Ad esempio, se una funzione viene completamente rimossa, è necessaria una nuova versione della libreria.

Un numero minore viene modificato nel caso vi sia una modifica nel codice che non renda la libreria condivisa incompatibile con la versione precedente in uso. Ad esempio, una piccola correzione di bug non interromperà la compatibilità della libreria condivisa esistente, quindi solo un numero minore viene modificato mentre la versione rimane la stessa.

Ora, ci si potrebbe chiedere perché tanti nomi per una libreria condivisa?

Bene, queste convenzioni di denominazione aiutano più versioni della stessa libreria condivisa a coesistere in un sistema. I programmi che si collegano alla libreria condivisa non devono preoccuparsi dell'ultima versione della libreria condivisa installata nel sistema. Una volta che l'ultima versione della libreria condivisa è stata installata correttamente, tutti i programmi iniziano automaticamente a collegarsi all'ultima versione.

Il nome utilizzato dal linker è solitamente un collegamento simbolico al soname completo che a sua volta è un collegamento simbolico al nome reale.

Posizionamento nel file system

Ci sono principalmente tre posizioni standard nel filesystem in cui è possibile posizionare una libreria.

  • /lib
  • /usr/lib
  • /usr/local/lib

Seguiremo gli standard della gerarchia dei file system (FHS) qui. Secondo gli standard FHS, tutte le librerie che vengono caricate all'avvio e in esecuzione nel filesystem di root sono mantenute in /lib. Mentre le librerie utilizzate internamente dal sistema sono archiviate in /usr/lib. Queste librerie non sono pensate per essere utilizzate direttamente dagli utenti o dagli script della shell. C'è una terza posizione /usr/local/lib( anche se non è definita nell'ultima versione di FHS). Se esiste, contiene tutte le librerie che non fanno parte della distribuzione standard. Queste librerie non standard sono quelle che scarichi e potrebbero essere difettose.

Utilizzo di ldconfig

Una volta creata una libreria condivisa, copia la libreria condivisa nella directory in cui desideri che risieda la libreria (ad esempio /usr/local/lib o /usr/lib). Ora, esegui il comando ldconfig in questa directory.

Cosa fa ldconfig?

Ricorderete che abbiamo discusso in precedenza che un nome di linker per una libreria condivisa è un collegamento simbolico al soname completo che a sua volta è un collegamento simbolico al nome reale. Bene, questo comando fa esattamente lo stesso.

Quando si esegue un eseguibile ELF, per impostazione predefinita viene eseguito per primo il caricatore. Il caricatore stesso è un file oggetto condiviso /lib/ld-linux.so.X dove 'X' è un numero di versione. Questo caricatore a sua volta trova e carica tutte le librerie condivise da cui dipende il nostro programma.

Tutte le directory che vengono cercate dal caricatore per trovare le librerie sono memorizzate in /etc/ld.so.conf. La ricerca in tutte le directory specificate nel file /etc/ld.so.conf può richiedere molto tempo, quindi ogni volta che viene eseguito il comando ldconfig, imposta i collegamenti simbolici richiesti e quindi crea una cache nel file /etc/ld.so.cache dove vengono scritte tutte le informazioni richieste per l'eseguibile. La lettura delle informazioni dalla cache richiede molto meno tempo. Il problema qui è che il comando ldconfig deve essere eseguito ogni volta che viene aggiunta o rimossa una libreria condivisa. Quindi all'avvio il programma usa /etc/ld.so.cache per caricare le librerie che richiede.

Utilizzo di percorsi di libreria non standard

Quando si utilizzano percorsi di libreria non standard. È possibile eseguire uno dei seguenti tre passaggi:

Aggiungi il percorso al file /etc/ld.so.conf. Questo file contiene i percorsi di tutte le directory in cui la libreria viene cercata dal caricatore. Questo file a volte potrebbe contenere una singola riga come :

include /etc/ld.so.conf.d/*.conf

In tal caso, crea semplicemente un file conf nella stessa directory. Puoi aggiungere direttamente una directory da memorizzare nella cache usando il seguente comando:

ldconfig -n [non standard directory path containing shared library]

Si noti che questa è una modifica temporanea e andrà persa una volta riavviato il sistema. Aggiorna la variabile di ambiente LD_LIBRARY_PATH in modo che punti alla tua directory contenente la libreria condivisa. Il caricatore utilizzerà i percorsi menzionati in questa variabile di ambiente per risolvere le dipendenze.

Nota che su alcuni sistemi Unix il nome della variabile d'ambiente potrebbe essere diverso.

Nota:su un argomento correlato, come spiegato in precedenza, ci sono quattro fasi principali attraverso le quali passa un codice sorgente per diventare finalmente un eseguibile.

Esempio (come creare una libreria condivisa)

Facciamo un semplice esempio pratico per vedere come possiamo creare e utilizzare librerie condivise. Quello che segue è il pezzo di codice (shared.c) che vogliamo inserire in una libreria condivisa:

#include "shared.h"
unsigned int add(unsigned int a, unsigned int b)
{
    printf("\n Inside add()\n");
    return (a+b);
}

shared.h assomiglia a :

#include<stdio.h>
extern unsigned int add(unsigned int a, unsigned int b);

Per prima cosa rendiamo shared.c come una libreria condivisa.

1. Eseguire i seguenti due comandi per creare una libreria condivisa:

gcc -c -Wall -Werror -fPIC shared.c
gcc -shared -o libshared.so shared.o

Il primo comando compila il codice shared.c in un codice indipendente dalla posizione, necessario per una libreria condivisa.
Il secondo comando crea effettivamente una libreria condivisa con il nome 'libshared.so'.

2. Ecco il codice del programma che utilizza la funzione di libreria condivisa 'add()'

#include<stdio.h>
#include"shared.h"
int main(void)
{
    unsigned int a = 1;
    unsigned int b = 2;
    unsigned int result = 0;

    result = add(a,b);

    printf("\n The result is [%u]\n",result);
    return 0;
}

3. Quindi, esegui il seguente comando:

gcc -L/home/himanshu/practice/ -Wall main.c -o main -lshared

Questo comando compila il codice main.c e dice a gcc di collegare il codice con la libreria condivisa libshared.so (usando il flag -l) e dice anche la posizione del file condiviso (usando il flag -L).

4. Ora, esporta il percorso in cui è conservata la libreria condivisa appena creata utilizzando il seguente comando:

export LD_LIBRARY_PATH=/home/himanshu/practice:$LD_LIBRARY_PATH

Il comando precedente esporta il percorso nella variabile di ambiente 'LD_LIBRARY_PATH'.

5. Ora esegui l'eseguibile 'main' :

# ./main

Inside add()

The result is [3]

Quindi vediamo che la libreria condivisa è stata caricata e la funzione di aggiunta al suo interno è stata eseguita.


Linux
  1. Come creare uno scambio in Linux

  2. Come creare un file di scambio in Linux

  3. Come mostrare tutte le librerie condivise utilizzate dagli eseguibili in Linux?

  4. Come eseguire il controllo delle versioni di una libreria condivisa in Linux?

  5. Come verificare se è installata una libreria condivisa?

Come creare collegamenti simbolici in Linux

Come creare un file in Linux

Come creare collegamenti su desktop Linux

Come creare alias SSH in Linux

Come creare un alias in Linux

Come elencare le librerie condivise utilizzate dagli eseguibili in Linux