GCC
Compile! Linque! Debug! E mais!
John Henrique Teixeira de Godoi
Mathias Felipe Lima Santos
Instituto de Ci^encias e Tecnologia
Universidade Federal de S~ao Paulo
S~ao Jose dos Campos { SP, Brasil
Novembro, 2011
Programa de Educac~ao em Software Livre - PESL
Avisos!
Esse material foi elaborado para o vdeo que deve ser entregue
na disciplina de multimdia.
Algumas traduc~oes podem n~ao ser eis mas se adequavam
melhor ao contexto.
Alem do conteudo desses slides tem a parte pratica que sera
exibida durante a apresentac~ao.
Algumas bibliotecas e congurac~ees podem ser necessarias
para a execuc~ao de alguns exemplos, como GNU Database
Management Library (GDBM).
A biblioteca GDBM armazena pares de
valores-chaves em um arquivo DBM, um tipo de
arquivos de dados que permite armazenar e
indexar por uma chave.
Indice
1
GCC { C/C++
GCC
Programando em C e C++
2
Compilar!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
3
Vincular!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
4
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Indice
1
GCC { C/C++
GCC
Programando em C e C++
2
Compilar!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
3
Vincular!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
4
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Indice
1
GCC { C/C++
GCC
Programando em C e C++
2
Compilar!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
3
Vincular!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
4
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Indice
1
GCC { C/C++
GCC
Programando em C e C++
2
Compilar!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
3
Vincular!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
4
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
GCC { C/C++
Compilar!
Vincular!
E mais!
GCC
Programando em C e C++
Uma breve historia do GCC
Criador do GNU C Compiler (GCC) e Richard Stallman,que
fundou o projeto GNU, em 1984, para criar um sistema
operacional, baseado em Unix, como software livre.
Precisava de um compilador C, e devido a falta de
compiladores livres naquela epoca, criou-se um do zero.
1
o
lancamento do GCC em 1987, sendo o primeiro compilador
otimizador ANSI C portatil lancado como software livre.
1992, foi adicionado a capacidade de compilar C++
2001, adicionado melhorias na otimizac~ao e no suporte ao
C++
Suporte para linguagens adicionais como:
Fortran, ADA, Java and Objective-C.
E a sigla GCC, agora, se refere a \GNU Compiler Collection".
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
GCC
Programando em C e C++
Principais funcionalidades do GCC
GCC e um compilador portavel que roda na maioria das
plataformas disponveis atualmente, e criar sadas para diferentes
tipos de processadores (PC, microcontrollers, DSPs e CPUs
64-bits). GCC permite compilar um programa para diferentes
plataformas, produzindo arquivos executaveis para diferentes
sistemas a partir de qualquer outro com GCC. GCC e escrito em C
com um forte foco na portabilidade, e pode se auto-compilar, para
que seja adaptado a novos sistemas facilmente.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
GCC
Programando em C e C++
Principais funcionalidades do GCC
GCC tem uma arquitetura modular, permitindo suporte para novas
linguagens e arquiteturas a serem adicionadas. Adicionando uma
nova linguagem ao GCC permite o uso dessa linguagem em
qualquer arquitetura. Finalmente, e mais importante, GCC e um
software livre, distribudo sob a GNU General Public License (GNU
GPL).
O que signica que voc^e tem a liberdade para usa-lo, altera-lo,
assim como outros software GNU.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
GCC
Programando em C e C++
Programando em C e C++
C e C++ s~ao linguagens que permitem acesso direto a
memoria do computado.
Usadas para escrever sistemas de baixo nvel, e aplicac~oes
onde alta-perfomance e controle dos recurso usados s~ao
crticos.
Exigem um cuidado com o acesso correto memoria, para
evitar corromper outras estruturas de dados.
Existem tecnicas, usando GCC por exemplo, que ajudam a
detectar provaveis erros durante a compilac~ao, mas que n~ao
eliminam o isco " de usar tais linguagens.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando um programa em C
Podemos compilar programas a partir de um unico arquivo, ou de
varios outros, e tambem podemos usar bibliotecas do sistema e
arquivos de cabecalho. Compilac~ao trata-se do processo de
converte um programa de um codigo fonte em texto, em uma
linguagem tal como C ou C++, em um codigo de maquina, uma
sequ^encia de 1's e 0's usados para controla a Unidade Central de
processamento (CPU) do computador. Esse codigo e armazendo
em um arquivo tambem conhecido como arquivo executavel, ou
binario.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando um programa simples em C
Usaremos o exemplo classico, Hello World, como exemplo de
programa em linguagem C.
//nome do arquivo: hello.c
# include<<stdio.h>>
int main(void)
f
printf(\Hello;world!nn
00
);
return 0;
g
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando um programa simples em C
Para compilar `hello.c': \$ gcc -Wall hello.c -o hello" O arquivo
de sada e denido usando o par^ametro `-o'. Se omitido, a sada e
escrita em um arquivo chamado `a.out'. O par^ametro `-Wall'ativa
os avisos para os erros mais comuns ainda na compilac~ao -
recomenda-se sempre use esse par^ametro! Para executar o
programa, digite o caminho do executavel assim: \$ ./hello" O
que carregara o arquivo executavel na memoria e fara a CPU
executar as instruc~oes contidas nele.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Encontrando erros em um programa simples
Exemplo, `printf'com formato de ponto utuante, `%f', usado para
imprimir um valor inteiro:
# include<<stdio.h>>
int main(void)
f
printf(\Twoplustwois%fnn
00
;4);
return 0;
g
Um erro que pode passar despercebido primeira vista, mas
detectado se o par^ametro `-Wall'estiver acionado.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Encontrando erros em um programa simples
Ao compilar o codigo acima, o gcc lanca um aviso com a seguinte
mensagem:
\$ gcc -Wall bad.c -o bad"
\bad.c: In function `main':"
\bad.c:6: warning: double format, dierent type arg(arg2)"
O que indica o uso incorreto de formato no `printf', na linha 6.
As mensagens produzidas pelo GCC sempre seguem o modelo -
arquivo:numerodalinha:mensagem.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Encontrando erros em um programa simples
O compilador e capaz de distinguir entre as mensagens de erro, o
que previne compilar um codigo com problemas, e de aviso que
indicam possveis problemas, n~ao causariam problemas na
compilac~ao. Nesse caso, o formato correto seria `%d'.
Sem o par^ametro `-Wall'o programa aparentemente compilar
normalmente, mas produz uma sada incorreta:
\$ gcc bad.c -o bad"
\$ ./bad"
\Two plus two is 2.585495(saida incorreta)"
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Encontrando erros em um programa simples
Numeros inteiros e pontos utuantes s~ao armazenados de forma
diferentes na memoria, e costumam ocupar quantidades de bytes
diferentes, causando sadas incorretas. Alem de gerar sadas
incorretas, func~oes que n~ao s~ao usadas corretamente podem causar
a falha do programa, e para prevenir possveis problemas e
aconselhavel vericar os avisos do compilador. Obs.: O par^ametro
`-Wall'e capaz de identicar os erros que comumente ocorrem em
C.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando a partir de varios arquivos
Programa divididos em varios arquivos:
codigo mais facil de editar e entender (codigosgrandes)
compilar separadamente cada arquivos
Exemplo, `Hello World'dividido nos arquivos `main.c', `hellofn.c'e
o cabecalho `hello.h'.
//main.c
# include \hello.h "
int main(void)f
hello(\world);
return 0;
g
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando a partir de varios arquivos
A chamada da func~ao printf e feita atraves de uma func~ao externa,
hello( ), denida em `hellofn.c'. O programa `main'tambem inclui
o cabecalho `hello.h'que contem a declarac~ao da func~ao hello( ).
A declarac~ao e usada para garantir que os tipos da func~ao
chamada combinam com a func~ao denida.
Como a func~ao main n~ao chama a func~ao `printf'diretamente, n~ao
ha necessidade incluir a biblioteca `stdio.h'no `main.c'.
//hello.h
void hello (const charname);
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando a partir de varios arquivos
//hellofn.c
# include<<stdio.h>>
# include \hello.h "
void hello(const charname)f
printf(\Hello;%s!nn\;name);
g
Observamos que existem duas formas usar a instruc~ao # include,
no caso de # include \FILE.h ", para indexar a biblioteca e feita
um procura pelo arquivo no diretorio atual, ent~ao busca-se nos
diretorios do sistema.
E para # include<<FILE.h>>a busca pelo arquivo e feita apenas
nos diretorios do sistema.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando a partir de varios arquivos
Para compilar:
\$ gcc -Wall main.c hellofn.c -o newhello"
Obs.: O arquivo cabecalho, `hello.h', n~ao foi includo na lista de
arquivos. A diretiva # include \hello.h " no codigo-fonte instrue o
compilador para inclu-lo automaticamente aonde e necessario.
Para executar:
\$ ./newhello"
\Hello, world!"
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando os arquivos separadamente
Ao realizar uma mudanca qualquer em uma func~ao separada: Num
unico arquivo:
o programa inteiro deve ser recompilado,
pode ser um processo lento Codigos em arquivos diferentes:
somente os arquivos que possuem mudancas precisam ser
recompilados. Os arquivos-fonte s~ao compilados separadamente e
ent~ao vinculados - um processo de duas fases.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando os arquivos separadamente
1
Na 1
a
etapa:
um arquivo e compilado sem criar um
executavel.O resultado e referenciado como um
arquivo objeto que tem a extens~ao `.o'quando
usando GCC.
2
Na 2
a
etapa:
O Lincador combina todos os arquivos objetos
para criar um unico executavel.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Compilando um programa em C
Encontrando erros em um programa simples
Compilando a partir de varios arquivos
Compilando os arquivos separadamente
Em um arquivo objeto temos o codigo de maquina sem refer^encias
para enderecos de memoria das func~oes (ou variaveis) em outros
arquivos, que cam indenidos
Isso permite que os codigos fontes sejam compilados sem uma
refer^encia direta entre esses. O lincados preenche os enderecos
restantes quando produz o executavel.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Criando arquivos objetos de codigo-fontes
O par^ametro `-c'e usado para compilar um codigo-fonte para um
arquivo objeto. Por exemplo, o seguinte comando ira compilar o
codigo-fonte `main.c'para um arquivo objeto:
\$ gcc -Wall -c main.c"
Isso produz um arquivo objeto `main.o'contem o codigo de
maquina para a func~ao main. Contem a ref^encia para func~ao
externa hello, mas o endereco de memoria e deixado indenido no
arquivo objeto nesse estagio (queserapreenchidopelolincador).
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Criando arquivos objetos de codigo-fontes
O comando que corresponde a compilar o codigo fonte da func~ao
hello em `hellofn.c'e:
\$ gcc -Wall -c hellofn.c"
Isso produz um arquivo objeto `hellofn.o'.
Perceba que n~ao existe necessidade de usar o par^ametro `-o'para
especicar o nome do arquivo de sada nesse caso. Quando
compilando com `-c'o compilador automaticamente cria um
arquivo objeto que o nome e o mesmo do codigo-fonte, com
`.o'diferente da extens~ao original.
N~ao ha necessidade de inserir o arquivo cabecalho `hello.h'na linha
de comando, pois ja e incluido automaticamenteo pelos comandos
# include no `main.c'e `hellofn.c'.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Criando executaveis a partir de arquivos objetos
O passo nal em criar um arquivo executavel e usar o gcc para
vincular os arquivos objetos e preencher os enderecos das func~oes
externas que faltam. Para vincular os arquivos objetos, eles s~ao
simplesmente listados na linha de comando:
\$ gcc main.o hellofn.o -o hello"
Esse e um dos poucos casos onde n~ao existe a necessidade do uso
do par^ametro de aviso `-Wall', ja que os codigos-fontes foram
separadamente compilados com sucesso para arquivos objetos.
Uma vez que os codigos fontes foram compilados, vincular e um
processo desambigo pode falhar ou n~ao, e so falhara se existirem
refer^encias que n~ao poderem ser resolvidas.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Criando executaveis a partir de arquivos objetos
Para realizar o passo de vinculac~ao o gcc usar o vinculador ld, que
e um programa separado. Em sistemas GNU e usado o GNU ld.
Outros sistemas podem usado o GNU linker com o GCC, ou
podem usar seus proprios vinculadores.
Ao rodar o vinculador, o gcc cria um arquivo executavel a partir
dos arquivos objetos.
O arquivos executavel pode ser rodado por:
\$ ./hello"
\Hello, world!"
Produzindo a mesma sada da vers~ao que utiliza um unico arquivo.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Ordem para vincular os arquivos objetos
Em sistemas derivados do Unix, o comportamento tradicional de
vinculadores e compilados e procurar por func~oes externas da
esquerda para a direita nos arquivos objetos especicados na linha
de comando. Isso signica que o arquivo obejto que contem a
denic~ao de uma func~ao deveria aparecer depois de alguns aruivos
que chamaram aquela func~ao.
Nesse caso, o arquivo `hellofn.o'contem hello que deveria ser
especicado depois de `main.o', ja que main chama hello:
\$ gcc main.o hellofn.o -o hello" (ordem correta)
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Ordem para vincular os arquivos objetos
Com alguns compiladores ou vinculadores a ordem inversa
produziria um erro,
\$ cc hellofn.o main.o -o hello(ordemincorreta)"
\main.o: In function `main':"
\main.o(:text+ 0xf): undened reference to `hello'"
por n~ao ha nenhum arquivo obejto contendo hello depois de
`main.o'.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Ordem para vincular os arquivos objetos
Mas atualmente compiladores e vinculadores ir~ao buscar em todos
arquivos objetos, mesmo fora de ordem, mas como nem todos
compildadores fazem isso e melhor seguir a ordem convencional
dos arquivos objetos da esquerda para a direita.
Assim vale a pena manter isso na mente caso voc^e encontre
problemas imprevistos com refer^encias indenidas, e todos os
arquivos objetos est~ao presentes na linha de comando.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Recompilando e revinculando
Para mostrar como os codigos-fontes podem ser compilados
independentemente nos iremos editar o programa main `main.c'e
modica-lo para mostrar uma saudac~ao para todos ao inves do
mundo:
# include \hello.h "
int main(void)
f
hello(\everyone); // mudado de \world"
return 0;
g
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Compilando os arquivos separadamente
O arquivo atualizado `main.c'pode agora ser recompilado com o
seguinte comando:
\$ gcc -Wall -c main.c"
Isso produzira um novo arquivo objeto `main.o'. N~ao ha
necessidade de criar um novo arquivo objeto para `hellofn.c', ja
que seu arquivo e dependentes, tais como arquivos cabecalhos, n~ao
sofreram alterac~oes.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Recompilando e revinculando
O novo arquivo objeto pode ser revinculado com a func~ao hello
para criar um novo executavel:
\$ gcc main.o hellofn.o -o hello"
O executavel resultante `hello'agora usa a nova func~ao main para
produzir a seguinte sada:
\$ ./hello"
\Hello, everyone!"
Note que somente o arquivo `main.c'foi recompilado e ent~ao
revinculado com os arquivos objetos existentes para a func~ao hello.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Vinculando com bibliotecas externas
Uma biblioteca e uma colec~ao de arquivos objetos precompilados
que podem ser vinculados em programas.
O uso mais comum de bibliotecas e para prover func~oes do
sistemas, tal como a func~ao de raiz quadrada sqrt encontrada na
na biblioteca do C \math".
Bibliotecas s~ao tipicamente arqmazenadas em arquivos especiais
com a extens~ao `.a', referenciadas como bibliotecas estaticas. Elas
s~ao criadas arquivos objetos com ferramentas separadas do gcc,
como o GNU archiver ar, e usado pelo vinculador para resolver
refer^encias a func~oes no tempo de compilac~ao.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Vinculando com bibliotecas externas
As bibliotecas padr~oes do sistema s~ao normalmente encontradas
nos diretorios `/usr/lib'e `/lib'. Por exemplo, a biblioteca math e
normalmente armazenada no arquivo `/usr/lib/libm.a'em sistemas
baseados no Unix.
O prototipo das correspondentes declarac~oes para as func~oes nessa
biblioteca pode ser encontrado no arquivo de cabecalho
`/usr/include/math.h'. A biblioteca padr~ao do proprio C e
arqmazenada em `/usr/lib/libc.a'e contem func~oes especicadas
no padr~ao ANSI/ISO C, tais como `printf'{ essa biblioteca e
vinculada por padr~ao para todos os programas em C.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Vinculando com bibliotecas externas
Exemplo de programa que chama uma func~ao externa sqrt na
biblioteca math `libm.a':
# include<<math.h>>
# include<<stdio.h>>
int main(void)f
double x = sqrt(2:0);
printf(\The square root of2:0is%fnn
00
;x);
return 0;
g
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Vinculando com bibliotecas externas
Ao tentar criar um executavel de codigo fonte sozinho o compilado
da como sada um erro no estagio de vinculac~ao:
\$ gcc -Wall calc.c -o calc"
\/tmp/ccbR6Ojm.o: In function `main':"
\/tmp/ccbR6Ojm.o(:text+ 0x19): undened reference to
`sqrt'"
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Vinculando com bibliotecas externas
O problema e que a refer^encia para a func~ao sqrt n~ao pode ser
resolvida sem a biblioteca externa math `libm.a'. A func~ao sqrt
n~ao e denida no programa ou na biblioteca padr~ao `libc.a', e o
compilador n~ao vincula o arquivo `libm.a'ao menos que seja
explicitamente selecionado. A proposito, o arquivo mencionado na
mensagem de erro `/tmp/ccbR60jm.o'e um arquivo objeto
temporario criado pelo compilador a partir do `calc.c', a m de
tentar realizar o processo de vinculac~ao.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Vinculando com bibliotecas externas
Para habilitar o compilador vincular a func~ao sqrt ao programa
main em `calc.c'nos precisamos fornecer a biblioteca `libm.a'. Uma
forma obvia de realizar isso e especicar explicitamente na linha de
comando:
\$ gcc -Wall calc.c /usr/lib/libm.a -o calc"
A biblioteca `libm.a'contem os arquivos objetos para todas a
func~oes matematicas, tais como sin, cos, exp, log e sqrt. O
vinculador procura por esse para achar o arquivo objeto contendo a
func~ao sqrt.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Vinculando com bibliotecas externas
Uma vez que o arquivo objeto para a func~ao sqrt e encontrado, o
programa main pode ser vinculado e produzir o executavel
completo:
\$ ./calc"
\The square root of 2.0 is 1.414214"
O arquivo executavel inclue o codigo de maquina para a func~ao
main e o codigo de maquina para a func~ao sqrt, copiado do
correspondente arquivo objeto na biblioteca `libm.a'.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Vinculando com bibliotecas externas
Para evitar ter que especicar longos caminhos na linha de
comando, o compilador disponibilizar uma opc~ao de atalho `-l'para
vincular bibliotecas. Por exemplo o seguinte comando,
\$ gcc -Wall calc.c -lm -o calc"
e equivalente ao original comando anterior usando o nome
completo da biblioteca `/usr/lib/libm.a'.
Em geral, o par^ametro `-lNAME `anexara arquivos objetos com o
arquivo da biblioteca `libNAME.a'nos diretorios padr~ees.
Adicionalmente diretorios podem ser especicados com par^ametros
na linha de comando ou variaveis de ambiente.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Ordem de vinculac~ao das bibliotecas
A ordem das bibliotecas na linha de comando segue a mesma
convec~ao dos arquivos objetos: eles s~ao buscado da esquerda para
a direita { uma biblioteca contendo a denic~ao de uma func~ao
deveria aparecer depois de qualquer arquivo fonte ou arquivos
objetos que a usem. Isso inclue biblioteca especicadas com o
par^ametro de atalho`-l', como vemos no comando a seguir:
\$ gcc -Wall calc.c -lm -o calc(correto)"
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Ordem de vinculac~ao das bibliotecas
Ao tentar compilar, colocando `-lm'antes do arquivo que a usa,
resultara no erro:
\$ cc -Wall -lm calc.c -o calc(incorreto)"
\main.o: In function `main':"
\main.o(:text+ 0xf): undened reference to `sqrt'because
there is no library or object le containing sqrt after `calc.c'."
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Codigo-fontes!arquivosobjetos!executaveis
Ordem para vincular os arquivos objetos
Recompilando e revinculando
Vinculando com bibliotecas externas
Ordem de vinculac~ao das bibliotecas
Ordem de vinculac~ao das bibliotecas
Quando diversas bibliotecas s~ao usadas, a mesma convec~ao deveria
ser seguida pelas proprias. Uma biblioteca que chama uma func~ao
externa denada em outra biblioteca apareceria antes da biblioteca
contendo a func~ao.
Por exemplo, um programa `data.c'usando a biblioteca GNU Linear
Programming `libglpk.a', que por sua vez usa a biblioteca math
`libm.a', deveria ser compilado como,
\$ gcc -Wall data.c -lglpk -lm"
ja que os arquivos objetos em `libglpk.a'usam func~ees denada em
`libm.a'.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Usando bibliotecas de arquivos cabecalhos
Ao usar uma biblioteca e essencial incluir arquivo cabecalhos
apropriados, em ordem ao declarar os argumentos de func~ees e os
valores de retorno com os tipos corretos. Sem declarac~ees, os
argumentos de uma func~ao podem ser passado com tipo errado,
causando resultados adulterados.
O proximo exemplo mostrar outro programa que faz uma func~ao
chamar a biblioteca math do C.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Usando bibliotecas de arquivos cabecalhos
Nesse caso, a func~ao pow e usada para calcular o cubo de 2.
# include<<stdio.h>>
int main(void)f
double x = pow(2:0;3:0);
printf(\Twocubedis%fnn
00
;x);
return 0;
g
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Usando bibliotecas de arquivos cabecalhos
Entretanto, o programa contem um erro { o comando # include
para `math.h'esta faltando, ent~ao o prototipo double pow
(doublex;doubley) dado n~ao sera encontrado pelo compilador.
Compilando o programa sem qualquer par^ametros para avisos
produzira um arquivo executavel que gerara resultados incorretos:
\$ gcc badpow.c -lm"
\$ ./a.out(resultado incorreto;deveria ser8)"
\Two cubed is 2.851120"
Os resultados s~ao adulterados porque os argumentos e o valor de
retorno da chamada pow s~ao passados com tipos incorretos.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Usando bibliotecas de arquivos cabecalhos
O que poderia ser detectado acionando o par^ametro `-Wall':
\$ gcc -Wall badpow.c -lm"
\badpow.c: In function `main':"
\badpow.c:6: warning: implicit declaration of function
`pow'(naoencontrouprototipodepow)
Prova de que o uso do par^ametro de aviso `-Wall'detecta diversos
problemas que poderiam ser ignorados.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Par^ametros de compilac~ao
Essas par^ametros controlam funcionalidades tais como busca de
caminhos usados para localizac~ao de bibliotecas e arquivos
includos, o uso adicional de avisos e diagnosticos, prepocessador
de macros e dialetos do C.
Um problema comum quando compilando um programa que usa
arquivos cabecalhos para bibliotecas e o erro:
FILE.h : No such le or directory (arquivo nao encontrado)
Isso ocorre se um arquivo de cabecalho n~ao esta presente nos
diretorios de arquivos padr~ees usados pelo gcc.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Par^ametros de compilac~ao
Um problema similar pode ocorre para bibliotecas:
/usr/bin/ld: cannot nd library(biblioteca nao encontrada)
Isso acontece se a biblioteca usada para vinculac~ao n~ao esta
presente nos diretorios padr~ees usados pelo gcc.
Por padr~ao, o gcc busca por arquivos de cabecalhos nos seguintes
diretorios:
/usr/local/include/
/usr/include/
e os nos seguintes diretorios para bibliotecas:
/usr/local/lib/
/usr/lib/
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Par^ametros de compilac~ao
A lista de de diretorios para cabecalhos e frequentemente
referenciada para caminho para inclus~ao, e a lista de diretorios
para bibliotecas como diretorio de busca ou caminho de vnculo.
Os diretotios nesses caminhos s~ao buscados em ordem, do primeiro
ao ultimo nas duas listas acima. Por exemplo, um arquivo de
cabecalho encontrado em`/usr/local/include'tem preced^encia em
relac~ao ao um arquivo com mesmo nome em`/usr/include'.
Similarmente, uma biblioteca encontrada em`/usr/local/lib'tem
preced^encia em relac~ao a outra com mesmo nome em`/usr/lib'.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Par^ametros de compilac~ao
Os caminhos padr~ees de busca podem tambem incluir adicionais
dependendo do sistema ou local especco dos diretorios, e os
diretorios na instalac~ao do GCC mesmo.
Por exemplo, em plataformas 64-bit `lib64'diretorios adicionais
podem ser buscado por padr~ao.
Quando bibliotecas adicinais s~ao instaladas em outros diretorios e
necessario extender os caminhos de busca, de forma que as
bibliotecas sejam achadas.
Os par^ametros do compilador `-I'e `-L'adicionam novos diretorios
ao incio do caminho de inclus~ao e busca de bibliotecas
respectivamente.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Par^ametros de compilac~ao
O programa `dbmain.c', que cria um arquivo DBM contendo uma
chave `testkey'com o valor `testvalue':
# include<<stdio.h>>
# include<<gdbm.h>>
int main(void)f
GDBMFILE dbf;
datum key = estkey ", 7 ; //key, length
datum value = estvalue ", 9 ; //value, length
printf(\Storingkeyvaluepair:::);
dbf = gdbmopen(\test
00
;0;GDBMNEWDB;0644;0);
gdbmstore(dbf;key;value;GDBMINSERT);
gdbmclose(dbf);
printf(\done:nn
00
);
return 0;g
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Par^ametros de compilac~ao
O programa usa um arquivo de cabecalho `gdbm.h'e uma biblioteca
`libgdbm.a'. Se a biblioteca foi instalada na localizac~ao padr~ao de
`/usr/local/lib', com o arquivo cabecalho em `/usr/local/include',
ent~ao o programa pode ser compilado com o seguinte comando:
\$ gcc -Wall dbmain.c -lgdbm"
Ambos diretorios s~ao parte dos caminhos de vnculos e inclus~ao
padr~ees.
Entretanto, se GDBM foi instalado em uma localizac~ao diferente,
tentar compilar o programa ira dar o seguinte erro:
\$ gcc -Wall dbmain.c -lgdbm"
\dbmain.c:1: gdbm.h: No such le or directory"
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Par^ametros de compilac~ao
Por exemplo, se a vers~ao 1.8.3 do pacote GDBM esta instalado no
diretorio `/opt/gdbm-1.8.3'a localizac~ao do cabecalho poderia ser,
/opt/gdbm-1.8.3/include/gdbm.h que n~ao e parte dos caminhos
de inclus~ao padr~ees. Adicionando os diretorio aproprioado ao
caminho de inclus~ao com o comando `-I'permite que o programa
seja compilado, mas n~ao vinculado:
\$ gcc -Wall -I/opt/gdbm-1.8.3/include dbmain.c -lgdbm"
\/usr/bin/ld: cannot nd -lgdbm"
\collect2: ld returned 1 exit status"
O diretorio contendo a biblioteca ainda esta faltando no caminho
de vnculo. Ele pode ser adicionado usando o seguinte par^ametros:
\-L/opt/gdbm-1.8.3/lib/"
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Par^ametros de compilac~ao
A seguinte linha de comando permite que o programa seja
compilado e vinculado:
\$ gcc -Wall -I/opt/gdbm-1.8.3/include
-L/opt/gdbm-1.8.3/lib dbmain.c -lgdbm"
Isso produz o executavel nal vinculado a biblioteca GCBM.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
Por padr~ao, o gcc compila programas usando o dialeto GNU da
linguagem C, referenciado como GNU C. Esse dialeto incorpora o
padr~ao ocial ANSI/ ISO para a linguagem C com diversas
extens~ees uteis do GNU, tais como func~ees aninhadas e vetores de
tamanho din^amico. A maioria dos programas ANSI/ ISO
compilar~ao sob o GNU C sem problemas.
Existem diversos par^ametros que controlam o dialeto do C usado
pelo gcc.
Os mais comumente usados s~ao `-ansi'e `-pedantic'.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
O especifcio dialeto para a linguagem C para cada padr~ao pode
tambem ser selecionado com o par^ametro `-std'.
Ocasionalmente um programa ANSI/ ISO valido pode ser
incompatvel com as extens~ees GNU C. Para lidar com essa
situac~ao, o par^ametros do compilador `-ansi'desabilita aquelas
extens~ees GNU que tiverem conito com o padr~ao ANSI/ ISO. Em
sistemas usando a biblioteca GNU C (glibc) pode-se tambem
desabilitar a biblioteca padr~ao do C. Isso permite que os programas
sejam escritos em ANSI/ ISO C sejam compilados sem efeitos
indesejaveis das extens~ees do GNU.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
Por exemplo, o programa ANSI/ ISO C que usa uma variavel
chamada asm:
# include<<stdio.h>>
int main(void)f
const char asm[]= \6502 ";
printf(\thestringasmis`%s
0
nn
00
;asm);
return 0;
g
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
A variavels asm e valida sob o padr~ao ANSI/ ISO, mas esse
programa n~ao sera compilado no GNU C porque asm e um palavra
chave para a extens~ao GNU C, o que permite usar instruc~ees
assembly em func~ees C. Consequentemente, n~ao podera ser usada
como nome de variavel sem um erro de compilac~ao:
\$ gcc -Wall ansi.c"
\ansi.c: In function `main':"
\ansi.c:6: parse error before `asm'"
\ansi.c:7: parse error before `asm'"
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
Em contraste, usando o par^ametro `-ansi'disabilita a palavra-chave
asm, e permite que o programa acima seja compilado
corretamente:
\$ gcc -Wall -ansi ansi.c"
\$ ./a.out"
\the string asm is `6502'"
Outras palavras-chaves n~ao padr~ees e macros denidaas pelas
extens~ees do GNU C s~ao asm, inline, typeof, unix e vax.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
O proximo exemplo mostra o efeito do par^ametro `-ansi'em
sistemas usando a biblioteca GNU C, tais como sistemas
GNU/Linux. O programa abaixo imprime o valor de pi, =
3.14159..., da denic~ao do prepocessador MPI no arquivo de
cabecalhos `math.h':
# include<<math.h>>
# include<<stdio.h>>
int main(void)f
printf(\thevalueofpiis%fnn
00
;MPI);
return 0;
g
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
A constante MPI n~ao e parte da biblioteca padr~ao ANSI/ ISO C.
Nesse caso, o programa n~ao complicara com o par^ametro `-ansi':
\$ gcc -Wall -ansi pi.c"
\pi.c: In function `main':"
\pi.c:7: `MPI'undeclared(rst use in this function)"
\pi.c:7:(Each undeclared identier is reported only once)"
\pi.c:7:for each function it appears in:
00
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
O programa pode ser compilado sem par^ametro `-ansi'. Nesse caso
ambas extens~ees de linguagem e biblioteca s~ao habilitadas por
padr~ao:
\$ gcc -Wall pi.c"
\$ ./a.out"
\the value of pi is 3.141593"
Tambem e possvel compilar o programa usando o ANSI/ ISO C,
habilitando somente as extens~ees da propria biblioteca GNU C.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
Isso pode ser alcancado pela especic~ao de macros especiais, tais
comoGNUSOURCE, que habilita extens~ees da biblioteca GNU C:
\$ gcc -Wall -ansi -DGNUSOURCE pi.c"
\$ ./a.out"
\the value of pi is 3.141593"
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Padr~oes da linguagem C
A biblioteca GNU C prov^e diversas dessas macros que permite
controlar o suporte para extens~ees POSIX (POSIXCSOURCE),
BSD (BSDSOURCE), SVID (SVIDSOURCE), XOPEN
(XOPENSOURCE) e GNU (GNUSOURCE).
O par^ametro `-D'e usado para a denic~ao de macros.
A macroGNUSOURCE habilita todas extens~ees, com as
extens~ees POSIX tendo preced^encia sobre as outras em casos em
que hajam conitos.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
Refer^encias
Traduzido e adaptado de \An Introduction to GCC: for the
GNU Compilers gcc and g++" - Brian Gough, Foreword by
Richard M. Stallman, 2004, Network Theory Limited, GNU
Free Documentation License, Version 1.2.
John Godoi, Mathias Santos GCC
GCC { C/C++
Compilar!
Vincular!
E mais!
Usando bibliotecas de arquivos cabecalhos
Par^ametros de compilac~ao
Padr~oes da linguagem C
Refer^encias
2
a
parte
You will see in www.pinguim.pro.br
John Godoi, Mathias Santos GCC