10. Bibliotecas compartilhadas¶
Bibliotecas compartilhadas são códigos compilados para serem compartilhados entre diversos programas diferentes. Eles são distribuídos como arquivos ”.so” em “/usr/lib/”.
Uma biblioteca exporta símbolos que são versões compiladas de funções, classes e variáveis. Uma biblioteca tem nome chamado de SONAME que inclui o número de versão. Esta versão SONAME não corresponde necessariamente ao número de versão de lançamento público. Um programa é compilado com uma versão SONAME da biblioteca. Se qualquer dos símbolos for removido ou alterado, então o número da versão precisa ser alterado, o que força todos os pacotes que usam aquela biblioteca a serem recompilados com a nova versão. A numeração de versão é geralmente definida pelo uspstream e nós a seguimos em nossos nomes de pacotes binários chamados numeração ABI. Mas às vezes o upstream não utiliza uma numeração de versão prática e os empacotadores têm que manter uma numeração de versão separada.
As bibliotecas são normalmente distribuídas pelo upstream como versões independentes. Às vezes elas são distribuídas como parte de um programa. Neste caso elas podem ser incluídas no pacote binário junto com o programa se você não espera que outros programas utilizem a biblioteca. Geralmente, elas devem ser divididas em pacotes binários separados.
As bibliotecas em si são colocadas em um pacote binário chamado “libfoo1” onde “foo” é o nome da biblioteca e “1” é a versão do SONAME. Arquivos de desenvolvimento do pacote, como os arquivos de cabeçalhos, necessários para compilar programas com a biblioteca, serão colocados em um pacote chamado “libfoo-dev”.
10.1. Um exemplo¶
Vamos usar libnova como um exemplo:
$ bzr branch ubuntu:trusty/libnova
$ sudo apt-get install libnova-dev
Para encontra o SONAME de uma biblioteca, execute:
$ readelf -a /usr/lib/libnova-0.12.so.2 | grep SONAME
O SONAME é “libnova-0.12.so.2”, que corresponde ao nome do arquivo (geralmente é o caso, mas nem sempre). Aqui o upstream colocou o número da versão upstream como parte do SONAME e deu a ele a versão ABI “2”. Nomes de pacotes de bibliotecas devem seguir de acordo como SONAME das bibliotecas que contêm. O pacote binário de biblioteca “libnova-0.12-2” onde “libnova-0.12” é o nome da biblioteca e “2” é o nosso número ABI.
Se o upstream fizer alterações incompatíveis às suas bibliotecas, eles terão que reversionar o SONAME e nós teremos que renomear nossa biblioteca. Quaisquer outros pacotes usando o nosso pacote de biblioteca terão que ser recompilados com a nova versão, o que é chamado “transição” e pode exigir algum trabalho. Com sorte, nosso número ABI continuará a corresponder ao SONAME do uspstream, mas algumas vezes eles introduzem incompatibilidades sem alterar o seu número de versão e nós teremos que alterar o nosso.
Olhando em debian/libnova-0.12-2.install, vemos que inclui dos arquivos:
usr/lib/libnova-0.12.so.2
usr/lib/libnova-0.12.so.2.0.0
A última é a biblioteca real, completa com numeração de versão. A primeira é um link simbólico que aponta para a verdadeira biblioteca. O link simbólico é o que os programas que utilizam a biblioteca irão procurar, os programas em execução não se importam com alterações de versão menores.
libnova-dev.install
includes all the files needed to compile a program
with this library. Header files, a config binary, the .la
libtool file and
libnova.so
which is another symlink pointing at the library, programs
compiling against the library do not care about the major version number
(although the binary they compile into will).
.la
libtool files are needed on some non-Linux systems with poor library
support but usually cause more problems than they solve on Debian systems. It
is a current Debian goal to remove .la files and we should help with this.
10.2. Bibliotecas estáticas¶
The -dev package also ships usr/lib/libnova.a
. This is a static library,
an alternative to the shared library. Any program compiled against the
static library will include the code directory into itself. This gets round
worrying about binary compatibility of the library. However it also means that
any bugs, including security issues, will not be updated along with the library
until the program is recompiled. For this reason programs using static
libraries are discouraged.
10.3. Arquivos de símbolos¶
When a package builds against a library the shlibs
mechanism will add a
package dependency on that library. This is why most programs will have
Depends: ${shlibs:Depends}
in debian/control
. That gets replaced with
the library dependencies at build time. However shlibs can only make it depend
on the major ABI version number, 2
in our libnova example, so if new symbols
get added in libnova 2.1 a program using these symbols could still be
installed against libnova ABI 2.0 which would then crash.
Para fazer as dependências de uma biblioteca mais precisas, nós mantemos os arquivos ”.symbols” que listam todos os símbolos em uma biblioteca e a versão em que eles aparecem.
libnova não tem arquivo de símbolos, então podemos criar um. Inicie compilando o pacote:
$ bzr builddeb -- -nc
O “-nc” irá fazer terminar no final da compilação sem remover os arquivos de compilação. Vá para o diretório de compilação e execute “dpkg-gensymbols” para o pacote de biblioteca:
$ cd ../build-area/libnova-0.12.2/
$ dpkg-gensymbols -plibnova-0.12-2 > symbols.diff
Isto gera um arquivo diff que você pode auto-aplicar:
$ patch -p0 < symbols.diff
Which will create a file named similar to dpkg-gensymbolsnY_WWI
that lists
all the symbols. It also lists the current package version. We can remove the
packaging version from that listed in the symbols file because new symbols are
not generally added by new packaging versions, but by the upstream developers:
$ sed -i s,-0ubuntu2,, dpkg-gensymbolsnY_WWI
Agora mova o arquivo para a seu novo local, submeta e faça uma construção de teste:
$ mv dpkg-gensymbolsnY_WWI ../../libnova/debian/libnova-0.12-2.symbols
$ cd ../../libnova
$ bzr add debian/libnova-0.12-2.symbols
$ bzr commit -m "add symbols file"
$ bzr builddeb
Se a compilação for bem-sucedida, o arquivo de símbolos está correto. Com a próxima versão usptream do libnova, se você executar dpkg-gensymbols novamente ele irá gerar um diff para atualizar o arquivo de símbolos.
10.4. Arquivos de símbolos de bibliotecas C++¶
C++ has even more exacting standards of binary compatibility than C. The Debian Qt/KDE Team maintain some scripts to handle this, see their Working with symbols files page for how to use them.
10.5. Leitura adicional¶
Junichi Uekawa’s Debian Library Packaging Guide goes into this topic in more detail.