Articles

O que é um Makefile e como ele funciona?

Posted by admin

Se você quiser executar ou atualizar uma tarefa quando certos arquivos são atualizados, o utilitário make pode ser útil. make utilitário requer um arquivo, Makefile (ou makefile, que define o conjunto de tarefas a serem executadas. Você pode ter usado make para compilar um programa a partir do código fonte. A maioria dos projetos de código aberto usam makepara compilar um executável binário final, que pode então ser instalado usando make install.,

neste artigo, vamos explorar make e Makefile usando básico e avançado de exemplos. Antes de iniciar, certifique-se de que make está instalado no seu sistema.

exemplos básicos

vamos começar por imprimir o clássico “Olá Mundo” no terminal. Criar um diretório vazio myproject que contém um arquivo Makefile com este conteúdo:

say_hello:
echo "Hello World"

Agora, execute o arquivo digitando make dentro do diretório myproject., A saída será:

$ make
echo "Hello World"
Hello World

No exemplo acima, say_hello comporta-se como um nome de função, como em qualquer linguagem de programação. Isto chama-se o alvo. Os pré-requisitos ou dependências seguem o alvo. Por uma questão de simplicidade, não definimos quaisquer pré-requisitos neste exemplo. O comando echo "Hello World" é chamado de receita. A receita usa pré-requisitos para fazer um alvo. O alvo, pré-requisitos e receitas juntos fazem uma regra.,

Para resumir, abaixo está a sintaxe de uma regra típica:

target: prerequisites
<TAB> recipe

Como um exemplo, um alvo pode ser um arquivo binário que depende de pré-requisitos (arquivos de origem). Por outro lado, um pré-requisito também pode ser um alvo que depende de outras dependências:

não é necessário que o alvo seja um arquivo; pode ser apenas um nome para a receita, como no nosso exemplo. Chamamos-lhes “alvos falsos”.,”

voltando ao exemplo acima, quando make foi executado, a todo o comando echo "Hello World" foi exibido, seguido pelo real da saída do comando. Muitas vezes não queremos isso. Para suprimir ecoando o comando real, precisamos iniciar echo com @:

say_hello:
@echo "Hello World"

Agora, tente executar o make novamente., O resultado deve apresentar apenas isso:

$ make
Hello World

Vamos adicionar mais alguns falsos alvos: generate e clean Makefile:

Se a gente tentar executar o make após a mudança, só o destino say_hello será executada. Isso porque apenas o primeiro alvo no makefile é o alvo padrão. Muitas vezes chamado de objetivo padrão, esta é a razão pela qual você vai ver all como o primeiro alvo na maioria dos projetos., É da responsabilidade de all chamar outros alvos. Podemos anular este comportamento usando um alvo falso especial chamado .DEFAULT_GOAL.

Vamos incluir isso no início do nosso makefile:

.DEFAULT_GOAL := generate

Isto irá executar o alvo generate como padrão:

$ make
Creating empty text files...
touch file-{1..10}.txt

Como o nome sugere, o falso destino .DEFAULT_GOAL pode executado somente um alvo por vez. É por isso que a maioria dos makefiles incluem all como um alvo que pode chamar tantos alvos quanto necessário.,

Vamos incluir o falso destino all e remover .DEFAULT_GOAL:

Antes de executar o make, vamos incluir o outro especiais falso destino, .PHONY, onde definimos todos os alvos que não são arquivos. make irá executar a sua receita independentemente de existir um ficheiro com esse nome ou qual é a sua última hora de modificação., Aqui é a completa makefile:

make deve chamar say_hello e generate:

$ make
Hello World
Creating empty text files...
touch file-{1..10}.txt

é uma boa prática para não chamar clean no all ou colocá-lo como o primeiro alvo., clean deve ser chamado manualmente quando a limpeza é necessária como primeiro argumento para make:

$ make clean
Cleaning up...
rm *.txt

Agora que você tem uma idéia de como uma base makefile funciona e como escrever um simples makefile, vamos olhar para alguns exemplos mais avançados.

exemplos avançados

variáveis

no exemplo acima, a maioria dos valores-alvo e pré-requisitos são hard-coded, mas em projetos reais, estes são substituídos por variáveis e padrões.,

A maneira mais simples de definir uma variável em um makefile é usar o operador =., Por exemplo, para atribuir o comando gcc para uma variável CC:

CC = gcc

Este é também chamada recursiva expandida variável, e é usada em uma regra como mostrado abaixo:

hello: hello.c
${CC} hello.c -o hello

Como você pode ter adivinhado, a receita se expande conforme abaixo quando ele é passado para o terminal:

gcc hello.c -o hello

Os ${CC} e $(CC) são referências válidas para chamar gcc. Mas se alguém tentar reatribuir uma variável a si mesmo, causará um loop infinito., Vamos verificar isso:

CC = gcc
CC = ${CC}
all:
@echo ${CC}

Com make irá resultar em:

$ make
Makefile:8: *** Recursive variable 'CC' references itself (eventually). Stop.

Para evitar este cenário, podemos usar o := operador (isso também é chamado simplesmente expandido variável). Não devemos ter problemas em executar o makefile abaixo:

CC := gcc
CC := ${CC}
all:
@echo ${CC}

padrões e funções

o makefile seguinte pode compilar todos os programas C usando variáveis, padrões e funções., Vamos explorá-lo linha por linha:

abaixo está a reescrita do makefile acima, assumindo que ele é colocado no diretório com um único arquivo foo.c:

Leave A Comment