Pular para o conteúdo

O que são e o que você pode fazer com eles?

Tempo de leitura: 5 minutos

Principais conclusões

  • Makefiles são usados ​​pelo Make, que automatiza processos de construção por meio de makefiles para compilar código de forma eficiente.

  • Makefiles consistem em regras com alvos, dependências e ações.

  • Makefiles requerem recuo usando tabulações, não espaços, então preste atenção aos seus espaços em branco ao trabalhar com makefiles.

Se você instalou algum software a partir do código-fonte, provavelmente já usou o Make. Mas o que é esse programa e como funciona? Aprenda tudo sobre makefiles e como eles podem revolucionar seu processo de construção.

O que é compilação?

Makefiles e compilação estão inextricavelmente ligados. Embora não sejam apenas para compilação, o programa Make surgiu devido às frustrações que a compilação pode causar.

A compilação pega os arquivos de origem e os converte em outro formato. O exemplo clássico é um arquivo .c que é compilado em um arquivo objeto .o. Os programas C também passam por um processo de vinculação que converte arquivos .o em um executável final. Na verdade, existem quatro estágios distintos envolvidos na construção de um projeto C:

As etapas de compilação do programa começando na parte superior com o código-fonte e terminando na parte inferior com um arquivo executável.

A compilação foi popularizada no início dos anos 1970 com o desenvolvimento da linguagem C, mas linguagens mais recentes como Typescript, Rust e Sass também a utilizam. A alternativa é a interpretação, que utiliza um programa intermediário para executar o código, em vez de gerar um executável independente. As linguagens interpretadas incluem JavaScript, Python e Ruby.

Os programas compilados geralmente serão executados mais rapidamente – às vezes muito mais rápido – do que os interpretados. A compilação também verifica seu código em busca de certos tipos de erros que a interpretação só pode verificar em tempo de execução, portanto é mais fácil garantir que os programas compilados estejam corretos. Mas a compilação pode ser um processo lento, especialmente para projetos com centenas ou milhares de arquivos de origem.

O que os Makefiles fazem?

Makefiles são usados ​​pelo Make, um programa que ajuda a automatizar seu processo de construção, incluindo tarefas como compilação.

Quando você executa o comando make, ele procura um arquivo chamado Makefile ou makefile por padrão. Este arquivo deve conter instruções sobre como compilar – ou construir – cada arquivo em seu programa.

Makefiles são construídos em torno do conceito de uma “dependência” (ou “pré-requisito”) que faz verificações usando carimbos de data e hora do arquivo. Isso significa que o Make pode acelerar drasticamente a compilação: em vez de recompilar todo e qualquer arquivo fonte, o Make reconstrói apenas o mínimo necessário. De modo geral, se um arquivo fonte foi alterado, o Make o recompila, caso contrário, ele o deixa como está.

Como são os Makefiles?

A primeira coisa que você deve saber sobre makefiles é que os espaços em branco são significativos. Esta é amplamente considerada uma má decisão de design, mas estamos presos a ela, então tome cuidado!

Um makefile contém uma série de regras que descrevem como construir cada componente. O padrão geral de uma regra é assim:

target: dependencies
    actions

Aqui está, basicamente, o makefile mais simples, que compila um único arquivo fonte em um executável:

program: program.c
    gcc -o program program.c

A segunda linha deste makefile é recuada e o recuo deve ser um único caractere de tabulação. Esteja você copiando e colando ou digitando um makefile manualmente, tenha muito cuidado para manter um único caractere de tabulação no início das linhas recuadas. Se, por exemplo, você usar quatro espaços em vez de uma tabulação, verá um erro como “Makefile:2: *** faltando separador. Pare”.

Neste exemplo, o destino é o nome do executável final: programa. Um destino não precisa corresponder a um nome de arquivo, mas geralmente corresponde.

Há apenas uma dependência deste alvo – program.c – que Make usará para decidir o que fazer. Se o arquivo “programa” for mais recente que “program.c”, o Make não fará nada.

Escrevendo seu primeiro Makefile

Não há nada como a experiência prática e, felizmente, o Make é muito fácil de usar em sua forma mais simples.

Instalar Make

Em uma distribuição Linux que usa apt, como Ubuntu, Mint ou Debian, você pode instalar o Make assim:

sudo apt install make

No macOS, você pode instalar o Make via Xcode executando este comando:

xcode-select --install

Alternativamente, se você tiver o homebrew instalado, execute:

brew install make

Se você vir um erro como “make: comando não encontrado” ao tentar executá-lo, o programa make não está instalado em seu PATH. Você pode corrigir esse problema verificando se ele está instalado corretamente.

Escreva um programa de teste simples

Você pode ver o Make em ação testando o makefile acima com um programa C simples. Você só precisará do gcc e do make instalados para testar isso.

Crie um arquivo chamado “program.c” e preencha-o com o seguinte:

#include 

int main()
{
    printf("Hello, world.\n");
}

Neste ponto, teste se o seu programa está correto (e se você tem o gcc instalado) executando o seguinte:

gcc -o program program.c

Confirme se o gcc compila o programa com sucesso e remova-o:

rm program

Escreva o Makefile Básico

Agora crie o makefile de exemplo (como “Makefile” ou “makefile”) com o seguinte conteúdo:

program: program.c
    gcc -o program program.c

Execute Fazer

Em seu terminal, certifique-se de que seu diretório de trabalho contenha os arquivos Makefile e program.c e execute Make:

make
Comandos mostrando Make construindo um programa e executando-o.

Depois de confirmar que o Make compilou e compilou seu programa, teste seu comportamento executando-o novamente:

make
O programa make informando que está tudo atualizado.

Make informa que tudo está atualizado, então na verdade não faz nada agora. Este é um dos maiores benefícios do Make: ele só gastará tempo construindo componentes que precisam ser reconstruídos. Tente atualizar seu arquivo de origem e você verá a diferença:

touch program.c
make
Forçando o Make a reconstruir um arquivo usando o comando touch para atualizar seu horário de modificação.

O comando touch aqui apenas atualiza a hora modificada do arquivo para a hora atual. Esta é apenas uma maneira rápida de “enganar” Make fazendo-o pensar que o arquivo foi alterado.

O que mais pode ser feito?

Make é realmente limitado apenas por sua natureza baseada em arquivos. Qualquer arquivo pode fazer parte do seu processo de construção e atuar como destino ou dependência.

Isso significa que Make é apropriado para uma ampla gama de projetos. Qualquer coisa com etapas de construção previsíveis e repetíveis é adequada.

Por exemplo, pegue um gerador de site estático que gera páginas da web de outras fontes, geralmente incluindo arquivos de texto Markdown. Este makefile reconstruirá uma página da web específica:

index.html: index.md
    pandoc index.md index.html

Tocamos apenas na superfície do que o Make pode fazer aqui. Na realidade, os makefiles contêm padrões para definir regras para muitos arquivos diferentes, criando cadeias de dependências complexas.

Da próxima vez que você criar um software, veja se existe um makefile e tente explorar seu conteúdo. Esperançosamente, você pode entender alguns dos princípios básicos e reconhecer um pouco do que está acontecendo nos bastidores. Com o manual make do GNU em mãos, você pode começar a usar o Make em seus próprios projetos para evitar tempo de inatividade desnecessário.