ti-enxame.com

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

Estou ciente de que objetos compartilhados no Linux usam "so numbers", ou seja, que versões diferentes 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 a "DLL Hell" no Windows). Gostaria de saber como isso funciona na prática? Muitas vezes, vejo que example.so é de fato um link simbólico para example.so.2 Onde .2 é a versão mais recente. Como então um aplicativo depende de uma versão mais antiga de example.so identificá-lo corretamente? Existem regras sobre quais números se deve usar? Ou isso é simplesmente uma convenção? É o caso de que, diferentemente 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 é vinculado à versão mais antiga automaticamente ao compilar a partir da origem?

Eu suspeito que isso esteja relacionado a ldconfig, mas não sei ao certo como.

127
user119

Os próprios binários sabem de qual versão de uma biblioteca compartilhada eles dependem e solicitam-na especificamente. Você pode usar ldd para mostrar as dependências; o meu para ls é:

$ 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, ele aponta para libpthread.so.0, não apenas libpthread.so.


O motivo do link simbólico é para o vinculador. Quando você deseja vincular contra libpthread.so diretamente, você fornece a gcc a flag -lpthread e adiciona o prefixo lib e .so sufixo automaticamente. Você não pode dizer para adicionar no .so.0, então o link simbólico aponta para a versão mais recente da lib para facilitar essa

91
Michael Mrozek

Os números nas bibliotecas compartilhadas são convenção usada 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. O 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 alterados). Normalmente, o MINOR é incrementado para lançamentos de correções de erros ou quando novas APIs são introduzidas sem quebrar as APIs existentes.

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

61
miguel.de.icaza

As bibliotecas compartilhadas devem ter versão de acordo com o seguinte esquema:

blah.so.X.Y.Z

onde

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

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

ldconfig manté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 é criado para algo como o Red Hat, as bibliotecas compartilhadas chamadas no binário serão pesquisadas e adicionadas como dependências do pacote no tempo de criação do RPM. Portanto, quando você instala o pacote, o instalador verifica se hello.so.1 Está instalado ou não no sistema, marcando ldconfig.

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

rpm -qpR hello.rpm

Esse sistema (diferente do Windows) permite que várias versões do hello.so Sejam instaladas em um sistema e sejam usadas por diferentes aplicativos ao mesmo tempo.

25
ascotan

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 é primeiro vinculada a um objeto compartilhado pelo processo de construção. Na verdade, esse SONAME é o que um vinculador armazena em um executável, dependendo do objeto compartilhado que está vinculado a ele. Normalmente, o SONAME está na forma de libNAME.so.MAJOR e é alterado sempre que a biblioteca se torna incompatível com os executáveis ​​existentes vinculados a ela e as duas 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 é aumentado 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 para Linux, GNU GCC, ld, scripts de versão e o formato binário ELF - Como isso funciona?

20
penguin359