Por que não consigo instalar várias versões de uma biblioteca compartilhada?

9

Muitas vezes, há casos em que um determinado programa dependerá da versão da biblioteca x.y e outro do x.z, mas, até onde sei, nenhum gerenciador de pacotes permitirá que eu instale o x.y e o x.z. Às vezes, eles permitirão que as duas versões principais (como qt4 e qt5, que podem ser instaladas ao mesmo tempo), mas (aparentemente), nunca versões menores.

Por que isso? Como, qual é o fator limitante que impede isso? Eu suponho que deve haver uma boa razão para não permitir essa funcionalidade aparentemente útil. Por exemplo, não há um campo para indicar que versão carregar ao carregar um objeto compartilhado e, portanto, não há como o Linux saber como decidir o que carregar? Ou realmente não há razão para isso? Como todas as versões menores devem ser compatíveis de qualquer forma ou algo assim?

    
por Tyler 15.06.2015 / 06:58

2 respostas

11

Na verdade, você pode instalar várias versões de uma biblioteca compartilhada, se isso for feito corretamente.

As bibliotecas compartilhadas geralmente são nomeadas da seguinte forma:

lib<name>.so.<api-version>.<minor>

Em seguida, há links simbólicos para a biblioteca com os seguintes nomes:

lib<name>.so
lib<name>.so.<api-version>

Quando um desenvolvedor vincula-se à biblioteca para produzir um binário, é o nome do arquivo que termina em .so que o vinculador encontra. Na verdade, pode haver apenas um desses instalados por vez para qualquer <name> , mas isso significa que um desenvolvedor não pode segmentar várias versões diferentes de uma biblioteca ao mesmo tempo. Com os gerenciadores de pacotes, este symlink .so é parte de um pacote -dev separado, que somente os desenvolvedores precisam instalar.

Quando o vinculador encontra um arquivo com um nome que termina em .so e o usa, ele procura dentro dessa biblioteca por um campo chamado soname . O soname informa ao vinculador que nome de arquivo deve ser inserido no binário resultante e, portanto, qual nome de arquivo será procurado no tempo de execução. O soname deve estar configurado para lib<name>.so.<api-version> .

Portanto, em tempo de execução, o vinculador dinâmico buscará lib<name>.so.<api-version> e usará isso.

A intenção é que:

  • As atualizações de <minor> não alteram a API da biblioteca e quando o <minor> é direcionado para uma versão superior, é seguro permitir que todos os binários atualizem para a nova versão. Como todos os binários estão procurando a biblioteca sob o lib<name>.so.<api-version> name, que é um link simbólico para o mais recente lib<name>.so.<api-version>.<minor> instalado, eles recebem o upgrade.
  • Os upgrades de <api-version> alteram a API da biblioteca e não é seguro permitir que os aplicativos binários existentes usem a nova versão. No caso em que o <api-version> é alterado, como esses aplicativos estão procurando o nome lib<name>.so.<api-version> , mas com um valor diferente para <api-version> , eles não selecionam a nova versão.

Os gerenciadores de pacotes não costumam empacotar mais de uma versão da mesma biblioteca na mesma versão de distribuição porque toda a distribuição, incluindo todos os binários que fazem uso da biblioteca, é geralmente compilada para usar uma versão consistente de cada biblioteca antes a distribuição é liberada. Certificar-se de que tudo é consistente e de que tudo em uma distribuição é compatível com tudo o mais é uma grande parte da carga de trabalho dos distribuidores.

Mas você pode facilmente acabar com várias versões de uma biblioteca se você tiver atualizado seu sistema de uma versão de sua distração para outra e ainda tiver alguns pacotes mais antigos que requerem versões de bibliotecas mais antigas. Exemplo:

  • libmysqlclient16 de um Debian antigo, contém libmysqlclient.so.16.0.0 e symlink libmysqlclient.so.16 .
  • libmysqlclient18 do Debian atual, contém libmysqlclient.so.18.0.0 e symlink libmysqlclient.so.18 .
por 15.06.2015 / 07:29
4

Essa funcionalidade não é permitida, não é muito comum como resultado da maneira como a maioria das numerações de bibliotecas funciona e por causa da inconveniência das alterações no nome do pacote.

Se o uso de um esquema de número de versão pontilhada X.Y.Z. A versão "micro" Z frequentemente muda em correções de bugs, o número "menor" Y muda em mudanças compatíveis com versões anteriores e o número de versão "principal" X tem que mudar em mudanças de API (e às vezes funcionalidade).

Nunca deve haver uma razão pela qual você não queira que os bugs mais recentes sejam corrigidos, e as alterações compatíveis com versões anteriores também não devem quebrar seu software.

Se a biblioteca for desenvolvida dessa maneira, você deve sempre poder substituir X.Y.Z por X. (Y + m). (Z + n). para qualquer dado m e n. Ou seja você deve sempre ser capaz de substituir sua biblioteca pelo mais recente na mesma série de números principais. E se os desenvolvedores da biblioteca forem cuidadosos e o próximo número maior for compatível (por exemplo, com o anúncio de desaprovar coisas, mas não removê-las ainda), você pode até usar o próximo número principal.

Para desenvolvedores de pacotes, isso significa que eles podem usar o nome com apenas um nome, ou mesmo nenhum número, para fornecer a versão mais recente apenas atualizando o pacote. Se eles enviarem uma biblioteca em um pacote abc2 , terão de passar por aros para mover seu próprio software que confiou em abc2 para atualizar para usar abc3 , às vezes com pacotes de transição. É mais conveniente deixar de fora o número da versão principal de uma biblioteca, se isso funcionar para a maioria dos pacotes dependentes. Portanto, mesmo que abc2 e abc3 estejam disponíveis em algum ponto disponível em uma distribuição, abc3 geralmente é chamado abc (assim como abc2 foi chamado quando ainda não havia abc3 ) e assim que nenhum pacote depender de abc2 dentro da distribuição, será possível eliminar abc2 ao mesmo tempo.

O esquema de numeração não é uniformemente seguido, mas eu posso imaginar que com o advento da internet disseminando informações sobre como usar tal esquema, e a pressão dos usuários da biblioteca (incluindo desenvolvedores de distribuição) para fazer coisas importantes como para trás compatibilidade clara sem ter que ler através de um arquivo CHANGES incluído na biblioteca, contribuíram que isso se tornou mais comum.

Um exemplo de contador, mas não de uma biblioteca, é o intpreter python, que não é compatível com seus objetos compartilhados e o formato de decapagem em uma alteração de número menor. Portanto, você verá os pacotes para python (o mais recente da série 2.7) e python3 (o mais recente atualmente na série python3.4), além de pacotes explícitos para o python 2.6 (não sendo menos comum), além do python 3.3. / p>     

por 15.06.2015 / 07:31