GNU/Linux >> Linux Esercitazione >  >> Linux

A cosa serve l'opzione 'soname' per la creazione di librerie condivise?

soname è usato per indicare quale compatibilità API binaria è supportata dalla tua libreria.

SONAME viene utilizzato in fase di compilazione dal linker per determinare dal file della libreria quale versione effettiva della libreria di destinazione. gcc -lNAME cercherà libNAME .so link o file quindi cattura il suo SONAME che sarà sicuramente più specifico ( ex libnuke.so link a libnuke.so.0.1.4 che contiene SONAME libnuke.so.0 ).

In fase di esecuzione si collegherà con this viene quindi impostato nella sezione dinamica ELF NEEDED , dovrebbe esistere una libreria con questo nome (o un collegamento ad essa). In fase di esecuzione SONAME viene ignorato, quindi è sufficiente solo il collegamento o l'esistenza del file.

Nota:SONAME viene applicato solo in fase di collegamento/build e non in fase di esecuzione.

'SONAME' della libreria può essere visto con 'objdump -p file |grep SONAME'.'NEEDED' dei binari può essere visto con 'objdump -p file |grep NEEDED'.

[EDIT] ATTENZIONE Quella che segue è un'osservazione generale, non quella distribuita in Linux. Vedi alla fine.

Supponiamo che tu abbia una libreria con il nome libnuke.so.1.2 e sviluppi una nuova libreria libnuke :

  • se la tua nuova libreria è una correzione della precedente senza modifiche all'API, dovresti semplicemente mantenere lo stesso soname, aumentare la versione del nome file. cioè il file sarà libnuke.so.1.2.1 ma soname sarà ancora libnuke.so.1.2.
  • se hai una nuova libreria che ha solo aggiunto una nuova funzione ma non ha interrotto la funzionalità ed è ancora compatibile con la precedente, ti piacerebbe usare lo stesso soname della precedente più un nuovo suffisso come .1. cioè file e soname saranno libnuke.so.1.2.1. Qualsiasi programma collegato a libnuke.1.2 funzionerà comunque con quello. I nuovi programmi collegati a libnuke.1.2.1 funzioneranno solo con quello (fino a quando non arriverà una nuova sovversione come libnuke.1.2.1.1).
  • se la tua nuova libreria non è compatibile con nessun libnuke:libnuke.so.2
  • se la tua nuova libreria è compatibile con la vecchia versione:libnuke.so.1.3 [ovvero ancora compatibile con libnuke.so.1]

[EDIT] per completare:caso linux.

Nella vita reale di Linux SONAME come forma specifica :lib[NAME][API-VERSION].so.[major-version]major-version è solo un valore intero che aumenta ad ogni modifica principale della libreria.API-VERSION è vuota per impostazione predefinita

ex libnuke.so.0

Quindi il nome file reale include versioni secondarie e sottoversioni es:libnuke.so.0.1.5

Penso che non fornire un soname sia una cattiva pratica poiché la ridenominazione del file ne cambierà il comportamento.


Hai creato una libreria dinamica denominata libx.1.0.0 nella tradizione dei nomi libname.{a}.{b}.{c}

{a} stand for primary version, should changes when APIs changes(which making things incompatible).
{b} stand for sub version, should changes by adding APIs.
{c} stand for mirror version, should changes by bug fixing or optimizing

Ora stai rilasciando libx.1.2.0 e devi dichiarare che libx.1.2.0 è compatibile con libx.1.0.0 poiché la semplice aggiunta di funzioni e l'eseguibile delle persone non si arresterebbe in modo anomalo, basta collegarlo come ai vecchi tempi tramite:

Impostare libx.1.0.0 e libx.1.2.0 in modo che abbiano lo stesso soname, ad esempio libx.1

Questo è ciò che fa soname.


Ecco un esempio a sostegno della risposta di Johann Klasek.

In breve, SONAME è necessario in fase di esecuzione. Al momento della compilazione, è necessario solo il nome del linker o il nome reale (ad es. g++ main.cpp -L. -ladd o g++ main.cpp -L. -l:libadd.so.1.1 ). Le definizioni di nome linker e nome reale seguono Program Library HOWTO:3. Librerie condivise.

Albero dei sorgenti:

├── add.cpp
├── add.h
├── main.cpp
└── Makefile

Makefile:

SOURCE_FILE=add.cpp
# main.cpp includes `add.h`, whose implementation is `add.cpp`
MAIN_FILE=main.cpp
SONAME=libadd.so.1
REAL_NAME=libadd.so.1.1
LINKER_NAME=libadd.so
OUTPUT_FILE=a.out

all:
   g++ -shared -fPIC -Wl,-soname,${SONAME} -o ${REAL_NAME} ${SOURCE_FILE}
   ln -s ${REAL_NAME} ${LINKER_NAME}
   g++ main.cpp -I. -L. -ladd -o ${OUTPUT_FILE} 
   # Same as `ldconfig -n .`, creates a symbolic link
   ln -s ${REAL_NAME} ${SONAME}
   #./a.out: error while loading shared libraries: libadd.so.1: cannot open 
   # shared object file: No such file or directory
   LD_LIBRARY_PATH=. ./${OUTPUT_FILE}
clean:
   rm ${SONAME} ${REAL_NAME} ${LINKER_NAME} ${OUTPUT_FILE}

Linux
  1. Qual è la migliore distribuzione Linux per principianti?

  2. "quale" equivalente per le biblioteche condivise?

  3. Come verificare quali librerie condivise vengono caricate in fase di esecuzione per un determinato processo?

  4. Qual è l'equivalente C++ per AutoResetEvent in Linux?

  5. Qual è la password di root predefinita per MySQL 5.7

Qual è l'equivalente del comando updatedb di Linux per Mac?

Qual è l'equivalente del comando File Linux per Windows?

Qual è il motivo per cui rmdir(1) e rm(1) coesistono?

A cosa serve il gruppo `ombra`?

Qual è la posizione corretta per la variabile PS1 Shell?

Qual è la dimensione consigliata per una partizione Linux /boot?