Make e Makefile

Resultado de imagem para GNU Make

Make é um utilitário que agiliza a compilação de programas, onde através de um arquivo de configuração (normalmente chamado Makefile), ele encontrara diretivas e regras para executar a compilação.

Sintaxe

O arquivo de configuração (Makefile) tem que ser escrito com uma sintaxe própria, o seu template pode ser definida como:

regra: dependências 
          comando1          
          comando2         
          comando3

regra: É o nome da regra que você quer criar.

dependências: São os pré-requisitos para o programa ser gerado, essas dependências devem ser satisfeitas antes que os comandos daquela determinada regra sejam executados.

comando: É a ordem dos comandos a serem executadas depois que as dependências tiverem sido satisfeitas.

Exemplo

hello.c

#include <stdio.h>
#include <stdlib.h>
int main (){
    printf("Hello World!\n");
    return 0;
}

Para executar:

 
$ gcc hello.c -o hello
$./hello

Makefile

Podemos escrever essa mesma ordem de comandos no arquivo Makefile, que ficaria assim:

hello: hello.c
	gcc hello.c -o hello
        ./hello

Para executar o arquivo, digite o seguinte comando:


$ make
# ou executar
$ make hello

Os dois comandos acima vão executar a mesma coisa, se você digitar só “make” ele irá por padrão rodar somente a primeira regra escrita no Makefile.

Variáveis

No Makefile é possível ter variáveis, você pode escrevê-las da seguinte maneira:


CC := gcc
hello: hello.c
	$(CC) hello.c -o hello
        ./hello

Sua sintaxe é NOME_DA_VARIAVEL := VALOR_DA_VARIAVEL, e para usar nos comandos é só colocar $(NOME_DA_VARIAVEL).

Variáveis Automáticas

Assim como o argv e argc da main do C que serve para pegarmos os parâmetros passados pelo terminal, no make podemos pegar o nome da regra e suas dependências que estão em variáveis, as chamadas variáveis automáticas. Exemplo, o nome da regra é hello e o nome da saída do gcc também é hello, podemos usar então a variável $@ que nesse caso tem o valor de hello guardada dentro dela.

O arquivo Makefile ficará assim:


CC := gcc
hello: hello.c
	$(CC) hello.c -o $@
        ./hello

E a variável $^ indica uma lista das dependências daquela regra, no nosso caso o valor de $^ é hello.c, logo podemos mudar um pouco o nosso arquivo.


CC := gcc
hello: hello.c
	$(CC) $^ -o $@
        ./$@

Se você executar mais de um vez o arquivo make e não fez nenhuma alteração no arquivo hello.c, vai aparecer uma mensagem dizendo que esta tudo em ordem e nada foi modificado no arquivo e por isso não precisa compilar. Acaso você queira compilar mesmo assim é só apagar o arquivo executável ./hello, usando o comando rm no terminal:

$ rm ./hello

Ou criando uma regra com esse comando no Makefile:


CC := gcc
hello: hello.c
	$(CC) $^ -o $@
        ./$@
clean: hello
        rm $^

Dependências

Bom por fim a ultima coisa que você tem que saber é a ordem de dependências. Por exemplo eu quero que antes da regra de compilar eu quero que apareça no terminal uma mensagem, e depois da regra de compilação eu também quero que outra mensagem apareça, então o arquivo Makefile devera ser o seguinte.


CC := gcc

inicio: msg1 hello msg2

msg1: 
        @echo "Iniciando Compilação"

msg2:
        @echo "Finalizando Compilação"

hello: hello.c
	$(CC) $^ -o $@
        ./$@
clean: hello
        rm $^

Agora se você digitar make no terminal a regra inicial será inicio pois agora ela é a primeira. Nos pré-requisitos temos 3 parâmetros (que são os nomes das regras), que deveram ser executados na ordem, primeiro msg1, depois hello, e por fim msg2. Note que nas msg1 e msg2 eu utilizei @ antes do comando, fiz isso para que evite que esses comandos apareçam no terminal, e só oque vai aparecer é a saída de tal comando, o @ poderia ser empregado tanto na regra do hello: como no clean:

Referencias:

[ 1 ] – https://blog.pantuza.com/tutoriais/como-funciona-o-makefile

[ 2 ] – https://blog.pantuza.com/tutoriais/como-funciona-o-makefile

[ 3 ] – https://www.gnu.org/software/make/manual/make.html

[ 4 ] – http://orion.lcg.ufrj.br/compgraf1/downloads/MakefileTut.pdf

[ 5 ] – https://www.mat.uc.pt/~pedro/lectivos/ProgramacaoOrientadaObjectos/tutorialMakefilesPT.pdf