5

Desenvolvimento de Bibliotecas

 

 

 

Sumário:

 

  • Tipos de bibliotecas: arquivo (.a) e partilhada (.so)

 

  •  
  • Bibliotecas do sistema (libc, libm, ...)
  • Criação duma biblioteca estática (arquivo) e dinâmica (partilhada)
  • Visualização do conteúdo duma biblioteca estática
  • Substituição dos módulos objecto duma biblioteca estática
  • Adição de módulos objecto a uma biblioteca estática
  • Eliminação de módulos objecto duma biblioteca estática
  • Sumário das chaves do comando ar
  • Comunicação entre funções

 

  • Onde colocar as bibliotecas estáticas?
  • Unificação de bibliotecas e programas

 

 

  • Bibliotecas dinâmicas
  • Gestor de compilação de programas (make)

 

 

 

 

 

 

 


Tipos de bibliotecas

Há dois tipos básicos de bibliotecas:

 

 

 

Criação duma biblioteca

 

Há duas fases principais na criação duma biblioteca de código:

 

Nesta fase usa-se o compilador cc com a opção –c.

 

 

Para uma biblioteca estática nesta fase usa-se o arquivador ar  (Linux) ou libtool -static (MAcOS)

 

 

 

 

 

 

 

 

 

 

 

 

 


Conteúdo duma biblioteca estática

 

Uma biblioteca estática está dividida em três secções:

 

Identifica o ficheiro referente à biblioteca como um ficheiro arquivador (archive file) criado por ar

 

É usada pelo unificador (linker) para encontrar a localização, o tamanho e ainda informação adicional relativa a cada rotina e a cada dado existentes na biblioteca.

 

Existe um para cada ficheiro objecto especificado no comando ar.

 

 

Compilação e a construção duma biblioteca estática: libunits.a

 

Pretende-se construir uma biblioteca de funções que estão contidas em três ficheiros distintos, nomeadamente: length.c, volume.c e mass.c. Os protótipos das funções estão contidas no ficheiro units.h

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

$ cc  –c  length.c  volume.c  mass.c

 

 

Exemplo de compilação sem biblioteca:

 

Pretende-se, primeiro, criar um ficheiro executável convert.exe, cujo código fonte é o seguinte, sem recorrer a nenhuma biblioteca

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

$ cc  –o   convert.exe  convert.c   length.o mass.o volume.o

 

 

 $ convert.exe 

   


O ficheiro de protótipos units.h  para a biblioteca libunits.a

 

Para se poder usar a biblioteca libunits.a deverá criar um ficheiro de protótipos das funções implementadas pela biblioteca. Seja units.h o ficheiro de protótipos da biblioteca libunits.a.

 

 

 

 

 

 


A utilização de qualquer função desta biblioteca num programa requer a inclusão do ficheiro units.h no início do dito programa através da directiva #include. Isto é necessário para que o compilador poderá verificar a correcta utilização destas funções.

 

Assim se satisfaz o princípio fundamental das linguagens imperativas: só se pode usar uma variável (ou função) se tiver sido declarada previamente. No entanto em C a declaração duma função (o seu protótipo) não é obrigatória embora o compilador poderá emitir um aviso caso não o encontre.

 

Colocação da biblioteca libunits.a no sistema de ficheiros do UNIX

 

Após a criação da biblioteca libunits.a, há que guardá-la num local facilmente acessível a outros programadores. Existem dois locais principais que o unificador (ou linker) procura por defeito na fase de

junção ou unificação do código objecto:

 

 

Colocação do ficheiro de protótipos units.h no sistema de ficheiros do UNIX

 

Após a criação do ficheiro units.h, há que guardá-lo num local facilmente acessível a outros programadores, por exemplo numa directoria standard

 

 

Deste modo, qualquer programa que pretenda usar a biblioteca libunits.a, deve fazer a inclusão do ficheiro de protótipos units.h do seguinte modo:

 

·         #include <units.h>

 

Se, porventura, o programador não colocou o ficheiro units.h numa das duas directorias estandardizadas acima indicadas, mas o colocou na directoria corrente de trabalho, a sua inclusão é feita do seguinte modo:

 

·         #includeunits.h

 

Se, o programador colocou o ficheiro units.h na directória /home/users/projects/include a sua inclusão seria feita usando as aspas onde se pode escrever rum caminho absoluto como no exemplo em cima ou até um caminho relativo.

 

·         #include “../../users/projects/include/units.h


 

 

Exemplo de criação e utilização duma biblioteca estática: libunits.a

 

Pretende-se criar e utilizar a biblioteca libunits.a na criação dum ficheiro executável convertst.exe, cujo código fonte é igual em tudo do ficheiro convert.sh excepto no primeiro printf:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

$ ar  r  libunits.a  length.o  volume.o  mass.o

 

 

 

$ cc  –o   convertst.exe  convertst.c   libunits.a

 

Exercícios:

·         Inserir código para pedir ao utilizador um numero de “Pints” e fazer a conversão para litros. (Um pint de cerveja é um oitavo dum gallon.

 

·         Alterar o constante no ficheiro length.c para o valor 2.54,actualize a biblioteca estática libunits.a e criar de novo o executável. Para saber como substituir apenas uma parte duma biblioteca estática consulte o “man ar”.

 

 

Criação duma biblioteca dinâmica ou partilhada

 

Há duas fases principais:

 

Nesta fase usa-se o compilador cc com a opção –c as vezes será necessário compilar os ficheiro com  a opção –fPIC (position independent code)

 

Nesta fase usa-se o compilador cc (Linux) ou libtool (Mac/Darwin).

 

cc –shared -fPIC  -o nome_biblioteca ficheiros_objectos

 

 

 

 

 

Exemplo de construção duma biblioteca estática: libunits.so

 

            Criação da biblioteca

 

$ cc  shared  fPIC  –o libunits.so  length.o  volume.o  mass.o

 

Nota que pode ser necessário gerar de novo os ficheiros objectos com a opção –fpic

$  cc –fpic  –c  length.c  volume.c  mass.c

 

Exemplo de utilização duma biblioteca dinâmica: libunits.so

 

Pretende-se utilizar a biblioteca libunits.a na criação dum ficheiro executável convertsh.exe, cujo código fonte é igual em tudo do ficheiro convert.sh excepto no primeiro printf:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

$ cc  –o   convertsh.exe  convertsh.c   libunits.so

 

Exemplo de execução dum programa que utilize bibliotecas dinâmicas

 

Problemas na execução do convertsh.exe ! Utilizar a ferramenta ldd (otool -L no MacOs) para investigar quais as bibliotecas partilhadas que um executável necessita e se podem ser localizados e se se encontrem em memoria.

 

$ ldd convertsh.exe

 

Investigue a variável do shell LD_LIBRARY_PATH para resolver qualquer problema encontrado.

 

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

$ export LD_LIBRARY_PATH

 

References

 

http://www.tldp.org/HOWTO/Program-Library-HOWTO/index.html

http://docstore.mik.ua/orelly/linux/run/ch13_01.htm

http://www.ibm.com/developerworks/linux/library/l-dynamic-libraries/index.html

 

Makefile for this section