Samuel Dias Neto - sdiasneto@yahoo.com.br
O que é o utilitário make
Arquivos make padrão
O conceito de alvos
Executando o Makefile
Alvos frequentemente utilizados pela comunidade
Dependências
Utilizando macros
Utilizando regras de inferência
O utilitário make é uma poderosa ferramenta usada para compilar grandes projetos. Em vez de você mesmo compilar e linkar todos os arquivos, o make pode fazer isto para você com a vantagem de compilar somente o que for necessário. Isto é muito útil no caso de pequenas modificações em um grande projeto. Você pode introduzir os comandos de compilação num arquivo make , assim não há necessidade de decorar as opções de comando que você utilizou para compilar um projeto.
Veremos aqui a utilização básica do utilitário make . Para aprofundar-se dê uma olhada na page do GNU. Na seção de documentação você encontrará um manual completo do make , só que em inglês.
Ao ser invocado, o comando make procura no diretório atual por um dos três arquivos abaixo na seguinte sequência:
Ao construir seu arquivo make é recomendado o uso do nome Makefile porque:
O comando make trabalha com o conceito de alvos. Nosso Makefile deve ter pelo menos um alvo. Crie um Makefile vazio e execute o comando make e você terá uma sessão parecida com esta:
[nerd@aranha teste]$ ls Makefile [nerd@aranha teste]$ make make: *** No targets. Stop. [nerd@aranha teste]$
Observe que o comando foi encerrado dizendo que não haviam alvos. Agora vamos editar o Makefile e introduzir alvos:
# Estudando o comando make
alvo1:
@echo "Exibindo o alvo 1"
alvo2:
@echo "Exibindo o alvo 2"
alvo3:
@echo "Exibindo o alvo 3"
As linhas iniciadas com # são linhas de comentários. Um nome de alvo deve sempre iniciar no começo da linha e ser seguido por dois pontos.
Para excutar o Makefile invocando um alvo basta entrar com o comando make seguido do nome do alvo na linha de comando. Observe:
[nerd@aranha teste]$ make alvo2 Exibindo o alvo 2 [nerd@aranha teste]$ make alvo3 Exibindo o alvo 3 [nerd@aranha teste]$ make Exibindo o alvo 1 [nerd@aranha teste]$
Veja que quando foi invocado sem alvo, o comando make assumiu o primeiro alvo do arquivo como o alvo padrão.
Você pode também invocar vários alvos no mesmo comando:
[nerd@aranha teste]$ make alvo2 alvo3 alvo1 Exibindo o alvo 2 Exibindo o alvo 3 Exibindo o alvo 1 [nerd@aranha teste]$
Alvos frequentemente utilizados pela comunidade
Existem alguns nomes de alvo que são frequentemente utilizados por todos os programadores. Abaixo segue alguns deles:
Dependências O comando make também tem um conceito de dependência. Quando um alvo A depende de um alvo B, o alvo B será executado primeiro. Para o uso dos alvos frequentemente utilizados que estão descritos acima esteja ciente que:
Vamos introduzir dependências no nosso exemplo de estudo:
# Estudando o comando make
alvo1:
@echo "Exibindo o alvo 1"
alvo2: alvo1 alvo3
@echo "Exibindo o alvo 2"
alvo3: alvo2
@echo "Exibindo o alvo 3"
Agora vamos executar o Makefile invocando alvo2 e ver como funcionam as dependências:
[nerd@aranha teste]$ make alvo2 Exibindo o alvo 1 Exibindo o alvo 3 Exibindo o alvo 2 [nerd@aranha teste]$
Vemos que as dependências devem vir após o nome do alvo e devem estar separadas por um espaço. A primeira dependência também deve estar separada dos dois pontos por um espaço.
Macros O arquivo make também pode utilizar-se de macros para aumentar sua funcionalidade. Observe como abaixo:
# Estudando o comando make
# definindo uma macro
ARQUIVO = teste.c
#usando um nome de alvo frequentemente utilizado para
#definir todo o projeto
all: alvo1 alvo2 alvo3
alvo1:
@echo "compilando "$(ARQUIVO)
alvo2:
@echo "linkando "$(ARQUIVO)
alvo3:
@echo "removendo "$(ARQUIVO)
Nesta implementação do nosso arquivo de estudo introduzimos um nome de alvo normalmente utilizado ( all ) para definir todo o projeto. Veja como seria a execução deste Makefile:
[nerd@aranha teste]$ make compilando teste.c linkando teste.c removendo teste.c [nerd@aranha teste]$
Como mostrado no novo código do nosso Makefile de estudo, onde quisermos que o nome da macro seja substituído devemos colocar a expressão:
$(NOME_DA_MACRO)
Você ainda pode alterar o valor da macro quando invocando o Makefile. Observe a sessão abaixo:
[nerd@aranha teste]$ make compilando teste.c linkando teste.c removendo teste.c [nerd@aranha teste]$ make ARQUIVO=main.c compilando main.c linkando main.c removendo main.c [nerd@aranha teste]$
Veja que usamos o mesmo Makefile para processar outro arquivo através da definição de outro valor para a macro ARQUIVO na linha de comando.
Regras de inferência As regras de inferência são outro grande recurso do comando make . Para utilizá-las o make reconhece os seguintes tipos de arquivos dentre outros:
Abaixo segue um exemplo da definição de uma regra de inferência:
CC = gcc STD = _GNU_SOURCE .c.o: $(CC) -c -Wall $(CFLAGS) -D$(STD) $< -o $@
Vamos dissecar o trecho de código acima:
CC = gcc STD = _GNU_SOURCEutilizam macros para definir o compilador e o padrão de compilação. Observe que estas macros serão substituídas na linha de ação do alvo .c.o montando, assim, o comando correto para a compilação do arquivo.
$(CC) -c -Wall $(CFLAGS) -D$(STD) $< -o $@O comando deve iniciar com um caractere de tabulação. Para que o comando não seja exibido na saída padrão preceda-o com o caracter @ . Veja que este comando usa amplamente macros. As macros CC e STD já foram vistas acima.
$* o arquivo alvo sem o sufixo
$@ o arquivo alvo
$< o arquivo dependente. No caso do alvo ser um arquivo objeto( .o ),
o dependente será um arquivo fonte em linguagem C ( .c )
Para um melhor entendimento da utilização de regras de inferência vamos a um exemplo:
Crie o arquivo fonte sam.c com o código abaixo:
#include <stdio.h>
int main()
{
printf("testando 1,2,3\n");
return(0);
}
Agora crie o Makefile com o seguinte código:
# Exemplo da utilização de regras de inferência
CC = gcc
.c.o:
$(CC) -c $< -o $ $@
sam.o:
Observe que o Makefile tem o alvo sam.o . Utilizando as definições da regra de inferência o make procura o arquivo sam.c . Se não encontrar, exibirá uma mensagem de erro, provavelmente parecida com:
[nerd@aranha teste]$ make make: Nothing to be done for `sam.o'. [nerd@aranha teste]$
Caso encontre, o alvo será criado:
[nerd@aranha teste]$ ls Makefile sam.c [nerd@aranha teste]$ make gcc -c sam.c -o sam.o [nerd@aranha teste]$ ls Makefile sam.c sam.o [nerd@aranha teste]$
Observe os valores substituídos para as macros $< e $@ .
Aqui encerramos nossa pequena tour pelo comando make , lembrando que vimos apenas o "básico do básico" desta poderosa ferramenta.
Qualquer bizú a mais não esquece de me enviar.
E como dizia o meu querido professor de física Guido, lá no CMR, toda vez que terminava a aula:
" ..... estudem!" (aí jogava o giz na canaleta do quadro negro e saia da sala).