MakeFile

Fonte: Wikiversidade

Introdução[editar | editar código-fonte]

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.

Instalação[editar | editar código-fonte]

Debian e derivados[editar | editar código-fonte]

$ sudo apt-get install make

Fedora[editar | editar código-fonte]

$ yum install make

Sintaxe de Criação do Makefile[editar | editar código-fonte]

Um simples Makefile consiste de regras a sintaxe de uma regra é:

regra: dependências
<TAB> comando1...
<TAB> comando2...

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[editar | editar código-fonte]

  • 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[editar | editar código-fonte]

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:

NOMEVARIAVEL=CONTEUDO
Para utilizá-la utilizamos o $()
Neste caso ficaria $(NOMEVARIAVEL)

Variáveis Recomendadas[editar | editar código-fonte]

  • 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)
      

Variáveis internas[editar | editar código-fonte]

 $@    Nome da regra. 
 $<    Nome da primeira dependência 
 $^     Lista de dependências
 $?     Lista de dependências mais recentes que a regra.
 $*     Nome do arquivo sem sufixo

As regras de interferência[editar | editar código-fonte]

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[editar | editar código-fonte]

  • 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
    

Referências[editar | editar código-fonte]

https://www.gnu.org/software/make/manual/make.html#Reference

https://pt.wikibooks.org/wiki/Programar_em_C/Makefiles#As_regras_de_interfer.C3.AAncia