Criando bibliotecas Unix

No Unix (e alguns outros sitemas operacionais), uma biblioteca é uma coleção de objetos correlatos agrupados conjuntamente. Bibilotecas podem ser lincadas a outras bibliotecas  e a outros arquivos compilados para criar executáveis.

Quando você cria um programa C++, por exemplo, você usa muitas bibliotecas mesmo sem saber. Aqui estão algumas das bibliotecas usadas automaticamente pelo g++

biblioteca uso/propósito
libg++.so g++ specific code
libstdc++.so C++ standard code
libm.so math library
libc.so standard C library code

A tabela mostra versões compartilhadas (shared) ou dinâmicas (dynamic) das bibliotecas que tipicamente tem o sufico “.so”. Existem também versões estáticas (static) que tem o sufixo “.a”, por exemplo, tapestry é instalada como libtapestry.s no sistema acpub.

Você pode criar uma biblioteca com base em arquivos “.o” usando comandos diferentes dependendo de você querer criar uma biblioteca estática ou dinâmica. A informação abaixo é bem básica, mas suficiente para que você possa criar uma biblioteca para ser fornecida ao usuário como uma única biblioteca ao invés de vários arquivos “.o”. Você precisará provavelmente fornecer muitos arquivos de cabeçalho.

Bibliotecas Estáticas

Para criar bibliotecas estáticas, compile todo o código-fonte em arquivos “.0” e use o comando ar para arquivar numa biblioteca os arquivos “.o”. Você pode usar man ar para ver todas as opções, mas um conjunto minimo é descrito abaixo.

opção
c cria uma nova biblioteca
q adiciona o nome do arquivo ao final do arquivo
r substitui um membro da biblioteca
t imprime uma tabela com o conteudo do arquivo

Por exemplo: ar cq libfoo.a *.o cria uma nova biblioteca chamada libfoo.a de todos os arquivos “.o” dentro de um diretório. Normalmente você usará oa comando ar em um makefile então você provavelmente usa uma variavel no makefile ao invés de “*.o”.

Em máquinas não=solaris, você pode precisar executar o comando ranlib na biblioteca para criar um indice ou tabela de conteudo para a biblioteca.

Bibliotecas Estáticas e Makefiles

No sistema acpub você pode encontrar Makefiles que foram usados em 2003 para compilar as bibliotecas Tapestry. Esses makefiles mostram como compilar vários arquivos cpp em  arquivos “.o” e lincar esses arquivos em uma biblioteca estática. As linhas relevantes são reproduzidas aqui.

  • LIBOFILES gera uma lista de arquivos “.o” correspondente aos arquivos cpp em LIB_FILES (o código para a biblioteca).
  • Os comandos make all ou make libtapestry.a resultarão na remoção da biblioteca tabpestry antiga e crição de uma nova.
LIB_FILES = tstring.cpp bigint.cpp strutils.cpp ctimer.cpp date.cpp \
             more .cpp source files listed as needed

...

# All source files have associated object files
LIBOFILES		= $(LIB_FILES:%.cpp=%.o)       

# all is the default rule
all	: libtapestry.a

# remove the old tapestry library and remake the new one
libtapestry.a:	$(LIBOFILES)
	rm -f $@
	ar cq $@ $(LIBOFILES)

Bibliotecas dinâmicas

Bibliotecas dinâmicas são lincadas durante a execução do programa ao invés de serem lincadas durante a compilação. Isso diminui o tamanho dos executáveis e também permite que versões mais novas da biblioteca sejam lincadas em tempo de execução.

Dois passos são necessários para criar uma bibloteca compartilhada (shared). Primeiro, o arquivo precisa ser compilado como um objeto compartilhado. Para fazer isso use a flag -fPIC par ao g++:

g++ -fPIC -o foo foo.cc

compila foo.cc em um arquivo foo.o compartilhado.

Para compilar vários arquivos “.o” compartilhados em um biblioteca compartilhada você usará o comando ld:

ld -G *.o -o libfoo.so

combinará todos os arquivos “.o” em uma biblioteca compartilhada chamada libfoo.so. A opção -o especifica um arquivo de saida, a opção -G criar a biblioteca compartilhadas permitindo referÊncias não resolvidas.

Você pode usar o comando nm -s  para listas todos os simbolos de um arquivo “.so”, por exemplos, nm -s libfoo.so.

Usando bibliotecas

Bibliotecas tradicionalmente começam com um prefixo lib, seguido do nome da biblioteca, seguido do sufixo (.a ou .so). Por exemplo: libm.a, libg++.a, libtapestry.a are archive files for libraries m, g++, and tapestry

Quando você compila a flag -l é usada para especificar as bibliotecas. O prefixo lib é assumido automaticamente, então:

g++ -o foo foo.cc -ltapestry

assume uma biblioteca chamada libtapestry — o sufixo “.a” ou “.so” será determinado de acordo com o que o compilador encontrar ou como o compilador estiver configurado.

Note que por convenção (e necessidade) todas as bibliotecas começam com o prefixo lib, mas quando o g++ ou outro compilador é usado a opção -lnoprefix é usada, ou seja, como mostrado acima para invocar a biblioteca libtapestry.a você usa -ltapestry.

Fonte: http://www.cs.duke.edu/~ola/courses/programming/libraries.html