GNU Make é uma ferramenta que ajuda a gerar programas executáveis a partir do código fonte e também processar outros arquivos não-fonte do projeto. Make obtém a lógica de construir os executáveis e processar outros arquivos não-fonte de um arquivo chamado makefile ou um Makefile.
Por que fazer?
-
Make é a ferramenta de fato para a construção de programas executáveis a partir do código-fonte no mundo do código aberto.
-
O Make permite que os usuários finais criem programas executáveis sem saber detalhes técnicos de como criá-los.
-
Todos os detalhes de como construir executáveis e processar arquivos não-fonte estão listados no makefile - então o processo se torna repetível por todas as pessoas ou sistemas que tentam construir um projeto.
-
Se uma base de código for muito grande, é demorado e problemático construir um executável do zero quando a mudança no código-fonte é muito pequena. Make cuida disso. Ele rastreia quais arquivos são alterados e resolve a dependência de acordo para construir, reconstruir a parte específica do programa.
-
Make é agnóstico em relação à linguagem de programação. Não importa qual linguagem de programação ou qual dialeto você está usando. Makefile é um arquivo de texto de comandos de shell organizados estruturalmente com dependência e outra lógica para construir o programa e gerenciar outros arquivos não-fonte. Como é um monte de comandos shell, pode ser executado em qualquer lugar que o comando shell seja executado. O Windows não executa comandos do shell do Linux por padrão, mas você pode fazer isso com uma versão especializada para Windows.
-
Durante a construção de programas executáveis, muitos arquivos intermediários são criados que não precisam estar lá quando a construção for concluída. Faça a exclusão desses arquivos automaticamente. Ajuda a manter o ambiente limpo e economiza muito tempo valioso.
Instalando Make
Fazer sozinho não é suficiente para construir programas. Para construir programas a partir do código, você precisa ter compiladores e outras ferramentas instaladas em seu sistema. Então, precisamos do pacote completo de ferramentas de desenvolvimento para nosso propósito.
Para compilar fontes no Linux, existe um pacote chamado “build-essential” em sistemas baseados em Debian (e.g. Ubuntu, Linux Mint, etc) e “Ferramentas de Desenvolvimento” no Red Hat e CentOS.
Para instalar em sistemas baseados em Debian:
apt-get install build-essential
Para instalar no CentOS e no Red Hat, execute:
yum groupinstall "Ferramentas de Desenvolvimento"
Primeiros passos com Makefile
Vamos começar escrevendo um Olá Mundo programa com a linguagem de programação C.
A principal função do nosso programa C residirá dentro Hellomain.c. O conteúdo do arquivo deve ser semelhante ao seguinte:
#incluirint main () my_fun (); return 0;
Este código inclui o arquivo de cabeçalho hellofun.h que contém a declaração de uma função chamada hello_fun (). O conteúdo do inferno fofo.seu:
void my_fun ();
A definição de my_fun () mora dentro de Hellofun.c:
#incluir#incluir void my_fun () printf ("Olá, mundo!\ n "); return;
Este é um programa muito simples e poderíamos compilá-lo com o gcc com apenas uma linha de comando. Mas, os programas da vida real não são tão simples e tão pequenos quanto este. As coisas ficam complexas muito em breve. Abaixo, vou escrever o script makefile necessário para compilar este programa hello world. Vou explicar as diferentes partes dele nas seções subsequentes.
hellomain: hellomain.c diabinho.c gcc -o olá hellomain.c Hellomain.c -I.
Mantenha este código em um arquivo chamado makefile (sem qualquer extensão de arquivo). Coloque o arquivo no diretório onde os arquivos C estão. Aponte sua linha de comando neste diretório. Na linha de comando, escreva make e pressione Enter. Um arquivo executável chamado hello será gerado no diretório atual. Você pode verificar o resultado executando o executável com o seguinte comando.
./Olá
Saídas:
Olá Mundo!
Regras, metas e dependências
Um script makefile é uma coleção de regras. As regras instruem o Make como construir um destino ou saída da fonte ou de outros arquivos. A regra também especifica dependências do alvo. As regras de dependência devem ser executadas primeiro, dependendo se isso já foi processado olhando para os carimbos de data / hora. Em nosso exemplo makefile acima, temos uma regra com destino chamado Hellomain e suas dependências. O nome do destino é separado por dois pontos da lista de dependências. Os comandos do shell que serão executados estão listados na linha a seguir. Os comandos do shell devem começar com um caractere de tabulação.
Se você não especificar nenhum parâmetro com o comando make, o primeiro alvo é executado. Em nosso exemplo, não especificamos nenhum parâmetro e tínhamos Hellomain como o primeiro e único alvo.
Variáveis
Variáveis são uma ótima maneira de escrever valor uma vez e usá-las inúmeras vezes sem repetir o valor indefinidamente. Ajuda-nos a manter o nosso código DRY (Do Not Repeat Yourself). Se você precisar mudar algum valor em todo o script, você só precisa mudar isso em um lugar para refletir a mudança em todos os lugares se você estiver usando a variável.
Em nosso exemplo, usamos gcc como o compilador, mas podemos precisar mudar o compilador para outra coisa. Então, podemos manter o nome do compilador em uma variável. Além disso, podemos manter os sinalizadores do compilador em outra variável para reutilizar esse. Para definir um valor para uma variável, usamos o sinal de igual (=) e para ler essa variável usamos $ (variable_name).
CC = gcc CFLAGS = -I. hellomain: hellomain.c diabinho.c $ (CC) -o olá hellomain.c Hellomain.c $ (CFLAGS)
Limpando o ambiente
Muitas vezes, podemos precisar limpar nosso ambiente. Se quisermos que cada peça do nosso projeto seja reconstruída do zero, precisamos limpá-la. Em nosso exemplo simples, o único arquivo gerado é o Olá executável. Sem deletar manualmente, podemos deletar com make. Então, podemos criar uma regra para isso e nomear o destino como limpar.
CC = gcc CFLAGS = -I. hellomain: hellomain.c diabinho.c $ (CC) -o olá hellomain.c Hellomain.c $ (CFLAGS) clean: rm olá
O comando shell no destino limpoéapenas o antigo comando shell rm. Agora, na linha de comando, execute:
limpar
Olhe para o diretório atual para ver se o Olá arquivo executável foi embora.
Expandindo nosso exemplo para resolver mais problemas
No nosso exemplo simples de compilação hello world, temos um problema que ainda não resolvemos. Hellomain alvo olha para Hellomian.c e diabinho.c timestamps dos arquivos na próxima vez que você tentar recompilá-los com faço ou fazer Hellomain. Portanto, se você alterar qualquer um desses dois arquivos, eles serão recompilados. Mas, se você mudar diabinho.h então não vai recompilar. Isso é inesperado!
Novamente, pulamos um nível intermediário. Não geramos os arquivos objeto e geramos diretamente o executável. Mas, nos bastidores, os arquivos-objeto são criados em um diretório temporário e excluídos. Queremos gerar os arquivos objeto antes de construir o executável. Desta vez, estamos nomeando o alvo principal como tudo
all: hellomain.o diabinho.o gcc hellomain.o diabinho.o-oi olá hellomain.o: hellomain.c diabinho.h gcc -I. -c Hellomain.c diabinho.o: diabinho.c diabinho.h gcc -I. -c diabinho.c clean: rm -rf *.o rm olá
Execute o comando make novamente para ver se o seu programa foi compilado com sucesso ou não. Execute o executável hello para verificar o resultado. Observe o diretório atual e você verá que os arquivos de objetos são criados. Nós adicionamos mais uma linha ao alvo de limpeza para limpar arquivos de objetos. Este script makefile ajudará a recompilar o programa hello world mesmo se o diabinho.h arquivo é modificado.
Conclusão
Make é uma das ferramentas mais essenciais para usuários e programadores Linux. Se você é um usuário final, então o conhecimento do make irá ajudá-lo a consertar muitas coisas quebradas no seu mundo do Linux. Se você é um programador, então simplesmente não pode sair escrevendo o código e deixar seus usuários descobrirem como compilar esse código-fonte para executáveis. Você deve criar um script makefile para os usuários finais, para que eles não joguem algum jogo de adivinhação para compilar sua fonte para executáveis.
Referências
GNUMake Project Homepage
GNU Make Documentation