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

115

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

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

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

Suspeito que isso esteja relacionado a ldconfig , mas não sei como.

    
por Tshepang 13.08.2010 / 22:36

4 respostas

81

Os próprios binários sabem em qual versão de uma biblioteca compartilhada dependem e solicitam especificamente. Você pode usar ldd para mostrar as dependências; os meus para ls sã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 para o link simbólico é para o linker. Quando você deseja vincular diretamente com libpthread.so , você atribui gcc a sinalização -lpthread e adiciona o lib prefix e .so suffix automaticamente. Você não pode dizer para adicionar o sufixo .so.0 , então o link simbólico aponta para a versão mais nova do lib para facilitar que

    
por 13.08.2010 / 23:11
57

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, 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 são alterados). O MINOR normalmente é incrementado para liberações de correção de bug ou quando novas APIs são introduzidas sem quebrar as APIs existentes.

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

    
por 14.08.2010 / 04:33
18

libNAME.so é o nome do arquivo usado pelo compilador / linker ao procurar pela biblioteca especificada por -lNAME. Dentro de um arquivo de biblioteca compartilhada há um campo chamado SONAME. Esse campo é definido quando a própria biblioteca é vinculada primeiro a um objeto compartilhado (assim) pelo processo de construção. Este SONAME é, na verdade, o que um vinculador armazena em um executável, dependendo do objeto compartilhado 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 ele e ambas as versões principais da biblioteca podem ser mantidas instaladas conforme necessário (embora apenas uma seja apontada para desenvolvimento). Além disso, para suportar facilmente a atualização 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 é colidido para apontar para a nova versão secundária imediatamente atualizando 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 funciona?

    
por 31.03.2011 / 05:28
16

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 anterior
  • Z = alterações internas apenas - sem 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 o caminho para essa biblioteca existe. Você pode verificar isso executando:

ldconfig -p

Quando um pacote é construído para algo como o Red Hat, as bibliotecas compartilhadas que estão sendo chamadas no binário serão consultadas e adicionadas como dependências do pacote no tempo de compilação do RPM. Portanto, quando você for instalar o pacote, o instalador irá procurar se hello.so.1 está ou não instalado no sistema, verificando 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.so sejam instaladas em um sistema e sejam usadas por diferentes aplicativos ao mesmo tempo.

    
por 04.07.2016 / 15:00