# MakeFile
## Introdução

Ao escrever códigos em qualquer linguagem, a medida em que a quantidade de arquivos cresce, se torna cada vez mais improdutivo compilar os arquivos de forma manual. Tendo isto em vista, é possível utilizar o programa make para automatizar a compilação e recompilação dos arquivos de um determinado software e também para limpar e gerenciar os arquivos gerados pelo compilador de acordo com a necessidade do utilizador. Para isso, utiliza-se um arquivo chamado Makefile, que deve conter as instruções a serem interpretadas e executadas pelo make.
Alguns Sistemas Operacionais trazem programas similares ao make, tais como gmake, nmake, tmake, etc. O programa make pode variar de um sistema a outro pois não faz parte de nenhuma normalização. Este artigo aborda os passos e comandos necessários para a criação de um Makefile que possibilite gerar um executável de forma eficiente e sua utilização através do utilitário GNU make que é similiar ao make.

## Sintaxe de Criação do Makefile

Um simples Makefile consiste de regras a sintaxe de uma regra é:
A regra é só um nome para identificar um bloco de comandos. Ela geralmente recebe o nome do arquivo gerado pelo programa, como por exemplo os arquivos executáveis ou arquivos objetos. Ou também pode-se nomear a regra de acordo com a ação realizada pela mesma, como por exemplo a regra "clean".
Uma dependência é um arquivo utilizado como entrada para a execução dos comandos da regra. Também podem ser outras regras que serão chamadas antes da execução dos comandos. Se houver mais de uma dependência elas devem ser separadas com espaços.
Os comandos são comandos normais do shell (bash). Pode-se colocar vários comandos, porém devem estar identados com tabulações.

### Regras complementares

* all : É o nome das regras a serem executadas
* clean: Apaga os arquivos temporários, geralmente são os arquivos objetos gerados pelo compilador.
* mrproper: Apaga tudo o que deve ser modificado

### Definir variáveis

As variáveis no Makefile, assim como em qualquer outro sistema, servem para facilitar o uso do programa. Pois ao invés de trocarmos um conteúdo em várias linhas podemos através das variáveis trocar apenas o conteúdo da variável.
Uma variável é definida do seguinte modo:

### Variáveis Recomendadas

* CC para nome de compiladores de C ou C++.
** CC=gcc
* CFLAGS para definir as flags passadas ao compilador.
** CFLAGS=-W -Wall -ansi -pedantic
* EXEC para definir o nome do futuro programa executável.
** EXEC=teste
* SRC para definir os arquivos fontes, ou seja, os arquivos que serão compilados e gerarão seus respectivos arquivos objeto.
** SRC=teste.c main.c
* OBJ para definir os arquivos objetos gerados. Para cada arquivo.c será criado um arquivo objeto com o mesmo nome. Logo para definir sua variável OBJ deve-se olhar o nome de todos os arquivos ".c" e colocá-los na variável como ".o".
** OBJ=teste.o main.o Pode-se também definir sua variável OBJ através da variável SRC do seguinte modo:
** SRC = main.c teste.c OBJ= $(SRC:.c=.o) Entretanto, ao se crescer a quantidade de arquivos ".c" se torna massante escrever o nome de todos os arquivos na variável SRC, então para isto utilizamos o comando wildcard que possibilida a utilização de caracteres joker na definição de variáveis. Logo, a definição das variáveis OBJ e SRC ficam assim:SRC= $(wildcard *.c) OBJ= $(SRC:.c=.o)

### As regras de interferência

São regras genéricas chamadas por default.
* %.o: %.c - Ela significa fazer um arquivo objeto (".o") a partir de um arquivo fonte (".c")
* .PHONY - Esta regra é utilizada para evitar conflitos.
** Por exemplo: A regra "clean" é utilizada sem a dependência de nenhuma outra regra. Por conta disso, caso haja algum arquivo na mesma pasta com o nome "clean" o comando make clean não será executado, pois o mesmo seria considerado atualizado ou modificado. Para evitar este tipo de problema pode-se utilizar o .PHONY que fará a regra "clean" ser considerada um pré-requisito da regra .PHONY..PHONY: clean clean: rm -rf *.o

## Criando e utilizando um Makefile básico

* Neste exemplo, iremos supor a existência dos arquivos A.h, A.cpp e Main.cpp
* Podemos começar adicionando as variáveis que serão utilizadas:
* #Compilador CC = g++ #Flags CFLAGS = -W -Wall -pedantic -ansi EXEC = test #Conjunto de arquivos a serem compilados SRC = A.cpp Main.cpp #Conjunto de arquivos objetos a serem gerados OBJ = A.o Main.o
* O próximo passo é definir as regras necessárias:
* #Compilador CC = g++ #Flags CFLAGS = -W -Wall -pedantic -ansi EXEC = test #Conjunto de arquivos a serem compilados SRC = A.cpp Main.cpp #Conjunto de arquivos objetos a serem gerados OBJ = A.o Main.o #A regra all(default) será responsável por chamar a regra que gera o executável #final do programa all: $(MAKE) $(EXEC) #Regras nesse formato são chamadas por default e geram arquivos de mesmo nome #a partir de suas respectivas dependências %.o: %.cpp $(CC) -c $(CFLAGS) $< -o $@ #Essa regra é responsável por gerar o executável final, e possui como #dependências todos os arquivos de objetos do programa $(EXEC): $(OBJ) $(CC) $(CFLAGS) -o $@ $(OBJ) #Sempre que essa regra for executada, todos os arquivos gerados pelo makefile #serão apagados clean: @rm -rf *.o @rm -rf $(EXEC) #Regra responsável por executar o programa run: @$(EXEC)
* Caso os arquivos não estivessem na raíz do diretório do Makefile, seria necessário referenciar as pastas em que eles estão contidos
* Para testar, basta ir na pasta em que se encontram os arquivos a serem compilados e digitar no terminal os seguintes comandos:$make $make run
* Para limpar os arquivos gerados, basta digitar no terminal o comando:$make clean