Bibliotecas: Estáticas ou compartilhadas?

Bibliotecas: Estáticas ou compartilhadas?

As bibliotecas originais eram simplesmente um arquivamento de rotinas a partir do qual as rotinas necessárias eram extraídas e vinculadas ao aplicativo executável. Elas são descritas como bibliotecas estáticas, com nomes no formato libfoo.a em sistemas operacionais do tipo UNIX. Em alguns sistemas operacionais antigos elas são o único tipo disponível.

Em quase todas as plataformas Linux também existem bibliotecas compartilhadas (ou equivalentemente dinâmicas) (com nomes no formato libfoo.so) – uma cópia da biblioteca é carregada na memória virtual e compartilhada por todos os aplicativos que chamam alguma das funções dela. Isso é eficiente em termos de espaço.

No passado, aplicativos essenciais, como um "shell", frequentemente eram vinculados estaticamente, de forma que existisse alguma forma de sistema mínimo de recuperação, mesmo se bibliotecas compartilhadas, como libc.so, se tornassem danificadas (por exemplo, movidas para lost+found depois de fsck após um desligamento incorreto). Hoje em dia, a maioria das pessoas usa uma instalação alternativa de sistema ou um pendrive se precisar se recuperar. Os sistemas de arquivos com registro em diário também reduzem a probabilidade desse tipo de problema.

Dentro do livro, existem vários locais onde chaves de configuração, tais como --disable-static, são empregadas; e outros locais onde a possibilidade de usar versões de sistema das bibliotecas em vez das versões inclusas em outro pacote é discutida. A razão principal para isso é a de simplificar as atualizações de bibliotecas.

Se um pacote for vinculado a uma biblioteca dinâmica, [então] a atualização para uma versão mais recente da biblioteca é automática tão logo a biblioteca mais recente seja instalada e o aplicativo for (re)iniciado (condicionada a que a versão maior da biblioteca não seja modificada, por exemplo, indo de libfoo.so.2.0 para libfoo.so.2.1. Ir para libfoo.so.3 exigirá recompilação – o ldd pode ser usado para encontrar quais aplicativos usam a versão antiga). Se um aplicativo for vinculado a uma biblioteca estática, [então] o aplicativo sempre tem de ser recompilado. Se você souber quais aplicativos estão vinculados a uma biblioteca estática em particular, [então] isso é meramente um aborrecimento. Entretanto, normalmente você não saberá quais aplicativos recompilar.

Uma forma de identificar quando uma biblioteca estática é usada é a de tratar disso ao final da instalação de cada pacote. Escreva um script para achar todas as bibliotecas estáticas em /usr/lib ou onde quer que você esteja instalando, e, ou mova-as para outro diretório, de forma que não mais sejam encontradas pelo vinculador; ou renomeie-as, de forma que libfoo.a se torne, por exemplo. libfoo.a.oculta. A biblioteca estática pode então ser restaurada temporariamente se for efetivamente necessária, e o pacote que precisa dela pode ser identificado. Isso não deveria ser feito às cegas, pois muitas bibliotecas existem somente em uma versão estática. Por exemplo, algumas bibliotecas originárias dos pacotes glibc e gcc deveriam sempre estar presentes no sistema (libc_nonshared.a, libg.a, libpthread_nonshared.a, libssp_nonshared. a, libsupc++.a desde "glibc-2.36" e "gcc-12.2").

Se você usar essa abordagem, [então] você possivelmente descubra que mais pacotes que o que estava esperando usam uma biblioteca estática. Esse foi o caso com o nettle-2.4 na configuração padrão somente estática dele: Ele era exigido pelo GnuTLS-3.0.19, porém vinculado também em pacote(s) que usa(m) o GnuTLS, tais como o glib-networking-2.32.3.

Muitos pacotes colocam algumas das funções comuns deles em uma biblioteca estática que somente é usada pelos aplicativos dentro do pacote e, crucialmente, a biblioteca não é instalada como uma biblioteca independente. Essas bibliotecas internas não são um problema – se o pacote tiver de ser reconstruído para corrigir um defeito ou uma vulnerabilidade, [então] nada mais é vinculado a elas.

Quando o BLFS menciona bibliotecas de sistema, significa versões compartilhadas de bibliotecas. Alguns pacotes como Firefox-128.1.0 e ghostscript-10.03.1 agrupam muitas outras bibliotecas na árvore de construção deles. A versão que eles enviam geralmente é mais antiga que a versão usada no sistema, portanto possivelmente contenham defeitos – às vezes os(as) desenvolvedores(as) se dão ao trabalho de consertar defeitos nas bibliotecas incluídas deles(as), outras vezes não.

Ocasionalmente, decidir usar as bibliotecas do sistema é uma decisão fácil. Outras vezes, possivelmente exija que você altere a versão do sistema (por exemplo, para a libpng-1.6.43, se usada pelo Firefox-128.1.0). De vez em quando, um pacote envia uma biblioteca antiga e não mais pode se vincular à versão atual, porém pode se vincular a uma versão mais antiga. Nesse caso, o BLFS normalmente usará apenas a versão enviada. De quando em quando, a biblioteca inclusa não mais é desenvolvida separadamente; ou o(a) desenvolvedor(a) dela é o(a) mesmo(a) que o desenvolvedor(a) do pacote e você não tem outros pacotes que a usarão. Nesses casos, você será levado(a) a usar a biblioteca inclusa, mesmo se geralmente preferir usar as bibliotecas do sistema.