Bibliotecas estáticas c/c++

Este é um tópico muito batido, tão velho quanto a linguagem C, mas que muita gente procura. Já que existem milhares de livros de c/c++ parecidos que podem fazer diferença para cada leitor, resolvi escrevi este artigo. Em resumo será mostrado como fazer um programa em c++ com funções e como fazê-lo da mesma forma com uma biblioteca.

[ Hits: 39.281 ]

Por: Fábio A. B. em 03/06/2007


Gerando o executável



Depois de tudo que fizemos, agora a brincadeira é de gerar o executável.

Vá na linha de comando e digite:

$ g++ /home/programas/soma_principal.o -I/home/programas -L/home/programas libsoma_function.a -o soma_biblioteca

Pronto, agora você terá um programa que faz uso de uma biblioteca ".a", que está fora do programa principal e que possui a função suma_function, que por sua vez é "linkada" no programa principal quando você declara no início deste programa principal o header "soma_head.h".

Lembrando que nas linhas acima:
  • g++ : chamou o compilador;
  • /home/programas/soma_principal.o : é caminho onde se encontra o programa principal compilado;
  • -I/home/programas: é caminho da pasta onde se encontram os headers .h;
  • -L/home/programas: é caminho da pasta onde se encontram os as bibliotecas .a;
  • libsoma_function.a: é o nome da biblioteca usada;
  • -o soma_biblioteca: indica o nome do executável de saída.

É isso aí.

DETALHES: Se tivéssemos muitos arquivos funções compilados ".o", poderíamos juntá-los numa única biblioteca assim:

$ ar rc libtodas_functions.a function1.o function2.o function3.o function4.o ....

Não esquecer de reindexá-las com:

$ runlib libtodas_functions.a

Então faríamos um "head_todos.h" com o protótipo de todas as funções da biblioteca "libtodas_functions".

Agora então colocaríamos no nosso programa principal o header "head_todos.h" e poderíamos usar as "funções.o" nele contidas.

DETALHE: No programa principal não crie variáveis com o mesmo nome das funções.

Pronto, já sabemos usar um pouco de bibliotecas estáticas no GCC.

Como última dica, em vez de ficarmos chamando o gcc e explicando pra ele onde que está libsoma_fuction.a, os headers e etc, poderíamos gerar um script que faria isso automaticamente. Quanto a gerar scripts, há vários artigos na comunidade.

Como exercício:

1) Crie uma função que multiplica os dois números dados (multiplica_fuction.cpp);

2) Compile-a para obter o "multiplica_fuction.o";

3) Crie a biblioteca libtodas_function.a com o comando:

$ ar rc libtodas_fuction.a soma_function.o multiplica_function.o

4) Faça a reindexação com:

$ ranlib libtodas_function.a

5) Arrume seu arquivo principal colocando o header head_todos.h;

6) Compile seu programa principal;

7) Chame a função "multiplica" dentro do programa principal;

8) Crie o executável.

Espero contribuir.
FAB

Página anterior    

Páginas do artigo
   1. Funções
   2. Gerando bibliotecas estáticas
   3. Retomando o programa principal
   4. Gerando o executável
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Funcionamento da memória

O ? Alternativo em C/C++

Introdução à linguagem C - Parte II

Introdução à ponteiros em C

Operadores com a linguagem C

  
Comentários
[1] Comentário enviado por linuxalexsandro em 03/06/2007 - 11:30h

Gostei muito do artigo. Ele é bastante útil para estudantes iniciantes das linguagens c/cpp que desejam conhecer mais sobre o compilador gcc. Parabéns FAB

[2] Comentário enviado por sombriks em 03/06/2007 - 17:00h

Olá,

sombriks@comander:~/variados$ g++ -Wall pograma.cc -o pograma
In file included from /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/backward/iostream.h:31,
from pograma.cc:3:
/usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
sombriks@comander:~/variados$

todavia a execução é perfeita. Aparentemente no C++ o .h no final do arquivo foi depreciado.

Em C/C++ não basta apenas saber a linguagem; tem-se que aprender também os pormenores do compilador! Como estou estudando isso há umas 48 horas (direto, hahahaha) não resisti e decidi comentar.

Um Livro (pdf, mas deve existir como papel tb!) que eu recomendo se vc quiser uma rápida referência de C/C++ e um excelente tutorial de gcc é o do Brian Gough; dêem uma boa gloogada.

[3] Comentário enviado por V_Style em 03/06/2007 - 18:25h

Ola sombriks,

Então, o que significa efetivamente esse lance do se colocar o .h ou nao se colocar o .h no header?
Valeu
FAB

[4] Comentário enviado por feraf em 03/06/2007 - 19:48h

Para tornar o código portável, deve-se utilizar o iostream sem o .h. Isso se deve ao fato de que a iostream é uma namespace, ou seja, um aglomerado de classes. Na hora de invocar os métodos da iostream, deve-se chamá-los com std::cin e std::cout para entrada e saída padrão respectivamente. Opcionalmente pode-se importar o namespace std com 'using namespace std' e depois usar cin e cout diretamente.

[5] Comentário enviado por osirix em 25/02/2009 - 18:41h

Otimoooooooooooooo!!!
muito bom seu artigo ..
muito facil de entender .. !!
poxa dou nota 10000000000000000 pra ele .. ^^

vlw


[6] Comentário enviado por staltux em 23/04/2009 - 01:54h

cara legal...mas eu tenho uma pergunta...eu fiz isso que você mostrou e funcionou...
depois eu fiz novamente mas no code::blocks...sabe, criei um projeto e coloquei os arquivos nele...entao eu mandei compilar e executar e funcionou perfeitamente tambem...agora eu te pergunto:

Como o Code::Blocks sabe que o arquivo soma_function.cpp é a implementação do soma_header.h se em nenhum desses arquivos existe algo os relacionando...e eu tambem nao fiz nenhuma modificação nos scriptis de compilação do code...
é magica? magia negra? como ele adivinha isso?

[7] Comentário enviado por sombriks em 23/04/2009 - 09:18h

@alexfernandognr, essa é fácil.

ao compilar cada um dos N fontes individualmente o compilador vai apenas averiguar se todos os protótipos de função existem (i.e. não vai atrás da implementação ainda)

"g++ -c" não faz o executável, apenas o que é chamado de "código objeto".

No exemplo dado se vc der "g++ -c soma_function.cpp ; g++ -c g++ -c soma_principal.cpp" ambos vão gerar seus respectivos ".o" sem maiores dificuldades. Você somente teria problemas se os protótipos de função (declarados neste caso como manda a boa prática, no header) fossem usados de forma errada, o que implica em erro de compilação.

A mágica aqui é a etapa de linkagem ou linkedição.

"g++ soma_function.o soma_principal.o -o soma" faz a linkagem, é aqui o truque: o linker não precisa mais conhecer o código, apenas assegurar que cada chamada tem uma implementação em algum lugar no meio de todos os códigos objeto. dessa forma o problema é quebrado em pedaços menores e fica mais simples de resolver, ;)

em resumo, lembre-se que há duas etapas bem distintas: compilação e linkedição. A primeira cuida de achar os protótipos, mas é na segunda que juntamos as implementações.

[8] Comentário enviado por staltux em 23/04/2009 - 16:20h

entendido...
existe algum paramentro que possa ser colocado dentro do arquivo que implementa, para especificar de qual header se trata?
pois acho que teria problema se mais de um arquivo cpp implementa-se a mesma função...
tipo dois cpps implementando a mesma função com apenas um header...

[9] Comentário enviado por sombriks em 23/04/2009 - 19:55h

tem não, mas se você tiver no meio do seu mar de arquivos fontes dois que implementem o mesmo protótipo o linker irá falhar ao tentar juntar essas duas.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts