Como funcionam os números SO (objeto compartilhado)?

Como funcionam os números SO (objeto compartilhado)?

Estou ciente de que objetos compartilhados no Linux usam "so numbers", ou seja, diferentes versões de um objeto compartilhado recebem extensões diferentes, por exemplo:

  • example.so.1
  • example.so.2

Entendo que a idéia é ter dois arquivos distintos, de modo que duas versões de uma biblioteca possam existir em um sistema (em oposição ao "DLL Hell" no Windows). Gostaria de saber como isso funciona na prática? Freqüentemente, vejo que example.soé na verdade um link simbólico para example.so.2onde .2está a versão mais recente. Como então um aplicativo que depende de uma versão mais antiga example.soo identifica corretamente? Existem regras sobre quais números devem ser usados? Ou isso é simplesmente uma convenção? Será que, ao contrário do Windows, onde os binários de software são transferidos entre sistemas, se um sistema tiver uma versão mais recente de um objeto compartilhado, ele será vinculado automaticamente à versão mais antiga ao compilar a partir da fonte?

Suspeito que isso esteja relacionado, ldconfigmas não sei como.

Responder1

Os próprios binários sabem de qual versão de uma biblioteca compartilhada eles dependem e a solicitam especificamente. Você pode usar lddpara mostrar as dependências; os meus lssão:

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

Como você pode ver, aponta para, por exemplo libpthread.so.0, não apenas libpthread.so.


A razão do link simbólico é para o vinculador. Quando você deseja vincular libpthread.sodiretamente, você fornece gcco sinalizador -lpthreade ele adiciona o libprefixo e .soo sufixo automaticamente. Você não pode dizer para adicionar o .so.0sufixo, então o link simbólico aponta para a versão mais recente da lib para facilitar isso

Responder2

Os números nas bibliotecas compartilhadas são convenções usadas no Linux para identificar a API de uma biblioteca. Normalmente o formato é:

libFOO.so.MAJOR.MINOR

E como você notou, geralmente há um link simbólico de libFOO.so para libFOO.so.MAJOR.MINOR. ldconfig é responsável por atualizar este link para a versão mais recente.

O MAJOR normalmente é incrementado quando a API é alterada (novos pontos de entrada são removidos ou os parâmetros ou tipos são alterados). O MINOR normalmente é incrementado para lançamentos de correção de bugs ou quando novas APIs são introduzidas sem quebrar as APIs existentes.

Uma discussão mais extensa pode ser encontrada aqui:Dissecando bibliotecas compartilhadas

Responder3

As bibliotecas compartilhadas devem ser versionadas de acordo com o seguinte esquema:

blah.so.X.Y.Z

onde

  • X = versão ABI incompatível com versões anteriores
  • Y = versão ABI compatível com versões anteriores
  • Z = Somente alterações internas - nenhuma alteração na ABI

Normalmente você vê apenas o primeiro dígito hello.so.1porque o primeiro dígito é a única coisa necessária para identificar a "versão" da biblioteca, já que todos os outros dígitos são compatíveis com versões anteriores.

ldconfigmantém uma tabela de quais bibliotecas compartilhadas estão disponíveis em um sistema e onde existe o caminho para essa biblioteca. Você pode verificar isso executando:

ldconfig -p

Quando um pacote é compilado para algo como o Red Hat, as bibliotecas compartilhadas chamadas no binário serão pesquisadas e adicionadas como dependências do pacote no momento da compilação do RPM. Portanto, quando você for instalar o pacote, o instalador irá verificar se está ou não hello.so.1instalado no sistema marcando ldconfig.

Você pode ver as dependências de um pacote fazendo algo como:

rpm -qpR hello.rpm

Este sistema (ao contrário do Windows) permite que várias versões do hello.sosejam instaladas em um sistema e usadas por diferentes aplicativos ao mesmo tempo.

Responder4

libNAME.so é o nome do arquivo usado pelo compilador/vinculador ao procurar pela primeira vez uma biblioteca especificada por -lNAME. Dentro de um arquivo de biblioteca compartilhada há um campo chamado SONAME. Este campo é definido quando a própria biblioteca é vinculada pela primeira vez a um objeto compartilhado (so) pelo processo de construção. Este SONAME é na verdade o que um vinculador armazena em um executável, dependendo do objeto compartilhado que está vinculado a ele. Normalmente o SONAME está no formato libNAME.so.MAJOR e é alterado sempre que a biblioteca se torna incompatível com os executáveis ​​existentes vinculados a ela e ambas as versões principais da biblioteca podem ser mantidas instaladas conforme necessário (embora apenas uma seja apontada para desenvolvimento como libNAME.so) Além disso, para oferecer suporte à atualização fácil entre versões secundárias de uma biblioteca, libNAME.so.MAJOR normalmente é um link para um arquivo como libNAME.so.MAJOR.MINOR. Uma nova versão secundária pode ser instalada e, uma vez concluída, o link para a versão secundária antiga é alterado para apontar para a nova versão secundária, atualizando imediatamente todas as novas execuções para usar a biblioteca atualizada. Além disso, veja minha resposta paraLinux, GNU GCC, ld, scripts de versão e formato binário ELF - Como funciona?

informação relacionada