Creating file Makefile

3

I need to write a Makefile file, I've been able to set up something by searching, but I've tried to make it better for what I need, and I'm not getting it. What I'm trying to do:

1 - Check all .c or .cpp files if they have their equivalents .o

2 - Not having .o, would then create from the .c or .cpp file name, rather by checking your headers .h or .hpp files

3 - I wanted to do this check not only in one directory, but in several, because my project is divided into folders, all files in only one folder would be quite disorganized, ie, do steps 1 and 2 in the directory current and subdirectories, in those subdirectories check if directory ..., summarizing in the entire directory and subdirectories of the project.

What I've achieved so far, but I'm getting this error while giving make:

"Makefile: 22: *** missing separator." (Up 2: Error due "$ (COMPILER) -o $ @ $ ^" is white space instead of TAB, the Makefile file, recognizes TAB only)

#Compilador
COMPILADOR=g++
#Fontes .c
FONTES=$(wildcard *.c|*.cpp) 
#Headers .h
HEADERS=$(wildcard *.h|*.hpp)

.PHONY: all

all: compilar

#Verifica se os fontes .c possuem seus equivalentes arquivo-objetos .o
#Possuindo, compila e cria o arquivo executavel
compilar: $(FONTES:.c|.cpp=.o)
    $(COMPILADOR) -o $@ $^

#Verifica se os arquivos .c e .cpp, ainda não entendi muito bem aqui
%.o: %.c|%.cpp $(HEADERS)
    $(COMPILADOR) -c $< -o $@

Tutorial I relied on:

link

  

Up 1:

I'm still trying; I was able to get the files into their folders, but I can not check the object-files of the OBJ folder, because even without a file, the one in the folder is compiling and not going to the linkage code as it should ("Should", of course, if I had written the right code).

#Compilador
COMPILADOR=g++
#Diretorio dos arquivos de programa
PROGRAM=./program
#Diretorio dos arquivos binarios
BIN=./bin
#Diretorio dos arquivos .h e .hpp
INCLUDE=./include
#Diretorio dos arquivos-objetos
OBJ=./obj
#Diretorio dos arquivos .c e .cpp
SRC=./src
#Diretorio dos arquivos de bibliotecas
LIB=./lib

#Para otimizar e mostrar mais avisos
FLAGS= -O3 -Wall
#Para encontrar as bibliotecas utilizadas
LIBS= -lm -L $(LIB)


#Fontes .c
FONTES=$(wildcard $(SRC)/*.cpp) $(wildcard $(SRC)/*\*.c)
#Headers .h
HEADERS=$(wildcard $(INCLUDE)/*.hpp) $(wildcard $(INCLUDE)/*.h)


.PHONY: all

all: linkar
#Verifica se os fontes .c possuem seus equivalentes arquivo-objetos .o
#Possuindo, compila e cria o arquivo executavel
#Porém não está verificando, acredito que meu erro é aqui: 
#"%.%=$(OBJ)/.o"
#Mas não consigo imaginar outra forma de fazer isso
linkar: $(FONTES:%.%=$(OBJ)/.o)
    OBJETOS=$(wildcard $(OBJ)/*.o)
    $(COMPILADOR) $(FLAGS) $(PROGRAM)/programPrincipal.cpp $(OBJETOS) -I $(INCLUDE) -o $(BIN)/arquivoExecutavel

#Aqui compila e gera os .o
%.o: $(SRC)/%.c $(HEADERS) 
    $(COMPILADOR) $(FLAGS) -c $< -I $(INCLUDE) -o $(OBJ)/$@

And a doubt (Up 2: Resolved):

1 - Do you need to put "-I $ (INCLUDE)" when compiling and linking, or only when compiling the object files?

Answer = Requires only preprocessing, where #include is replaced by the file code to which it refers. So it's necessary when I say "compile" using "g ++ -c", it's actually already pre-processing and compiling each file individually, so it's necessary, as well as linking, since I'm calling the .cpp file with the function "int main" and if it has organized into separate files, it will have its .hpp file, ie "-I $ (INCLUDE)" is required in the two situations in which I use g ++.

  

Up 2 :

I've been able to resolve it, just change "%.% = $ (OBJ) /. o", and further down the code where it re-enters the question that needs "or":

$(subst .c,.o,$(subst .cpp,.o,$(FONTES)))

However, do not do this, it is not recommended to compile .c code in c ++ compilers, errors can occur, of course if the code is very simple, it compiles quietly but is best avoided. If you really need to compile in both languages, create a target for each in the makefile with your compiler. What I decided to do, was compile in the makefile only the c ++, as for the codes in c, I preferred to create libraries and to mention them in the linkage.

Link to the answer to my question about "or" in the makefile that helped me: link

Video series on Makefile file that also helped me:

link

I will leave the code here in case anyone is in doubt about creating the makefile file: (Up 3: Code below not functional, I just left here to learn the error that occurred, the working code is just below Up 3) p>

########################################
###Script by PerguGames
###GitHub:https://github.com/PerduGames
########################################
#Arquivo Makefile 
#Arquivo para compilar executavel em c++, 
#buscando as dependencias em suas respectivas pastas
#O que acontece quando digito "make"?
#Busca dentro do diretorio atribuido na variavel "SRC" todos os arquivos .cpp
#Muda o sufixo e prefixo de todos os arquivos: "src/*.cpp" para "obj/*.o"
#Compila os arquivos .cpp e cria os arquivos .o no diretorio atribuido na variavel "OBJ"
#Linka e cria o executavel com o nome que você colocou em "coloqueAquiOnomeDoSeuExecutavel",
#buscando primeiro o arquivo principal .cpp no diretorio atribuido na variavel "PROGRAM"
#e buscando as devidas dependecias, bibliotecas e arquivos-objetos que foram criados
#O que acontece quando digito "make run"?
#Executa o programa "coloqueAquiOnomeDoSeuExecutavel",
#O que acontece quando digito "make cleanObjetos"?
#Exclui todos os arquivos .o no diretorio atribuido na variavel "OBJ"
#O que acontece quando digito "make clean"?
#Exclui todos os arquivos no diretorio atribuido na variavel "BIN" que seria seu
#executavel que deu o nome em "coloqueAquiOnomeDoSeuExecutavel"
#O que acontece quando digito "make tar"?
#Empacota todo o diretorio atual onde esta o arquivo makefile com o
#nome que voce substituir em "nomeDeSeuProjeto"
#Notas:
#Lembrem-se ao nomear o executavel em "coloqueAquiOnomeDoSeuExecutavel",
#precisa existir um arquivo .cpp com o mesmo nome no diretorio atribuido 
#na variavel "PROGRAM", para sastisfazer a dependencia do alvo,
#esse arquivo, seria seu arquivo com a funcao "int main()". 

#Compilador
COMPILADOR=g++
#Diretorio dos arquivos de programa
PROGRAM=./program
#Diretorio dos arquivos binarios
BIN=./bin
#Diretorio dos arquivos .h e .hpp
INCLUDE=./include
#Diretorio dos arquivos-objetos
OBJ=./obj
#Diretorio dos arquivos .c e .cpp
SRC=./src
#Diretorio dos arquivos de bibliotecas
LIB=./lib

#Para otimizar e mostrar mais avisos
FLAGS= -O3 -Wall
#Para encontrar as bibliotecas utilizadas(em "-lm", apenas um exemplo, caso seu compilador nao faca isso por voce)
LIBS= -lm -L $(LIB)

#Pega todos arquivos .cpp e muda os nomes para .o
#Fontes .cpp
FONTES=$(wildcard $(SRC)/*.cpp)
#Retirar prefixo e sufixo
OBJLIMPAR=$(notdir $(basename $(FONTES)))
#Adicionar novo prefixo e sufixo
OBJETOS=$(addprefix $(OBJ)/, $(addsuffix .o, $(OBJLIMPAR)))

.PHONY: all cleanObjetos clean tar

all: compilar executaveis

#Arquivos .o do projeto
compilar: $(OBJETOS)

#Executaveis do projeto
executaveis: $(BIN)/coloqueAquiOnomeDoSeuExecutavel
    echo $(OBJETOS)

#Compilar e criar os arquivos-objetos
$(OBJ)/%.o: $(SRC)/%.cpp $(INCLUDE)/%.hpp
    $(COMPILADOR) $(FLAGS) -c $< -I $(INCLUDE) -o $@

#Linkar e criar o executavel
$(BIN)/%: $(PROGRAM)/%.cpp
    $(COMPILADOR) $(FLAGS) $< $(OBJETOS) -I $(INCLUDE) $(LIBS) -o $@

#Executar programa
run:
    $(BIN)/coloqueAquiOnomeDoSeuExecutavel

#Limpar arquivos .o
cleanObjetos:
    rm -f $(OBJ)/*.o

#Limpar executaveis
clean:
    rm -f $(BIN)/%

#Empacotar projeto
tar:
    tar cvjf nomeDeSeuProjeto.tar.bz2 pwd

I have only two questions:

1 - The code was commented after "/ (asterisk)" in the code posted, I could not escape it with "\", is there any way to do this?

2 - It's okay to do this: "g ++ filePrincipal.cpp file1.o2 file -I include / -o fileAccessable", I can compile my main file where function "int main ()" is at the same time linkar the object files?

Answer = Not sure, you will get an error because you did not compile the Main.cpp file, perhaps not if your files are out of content (as was the case with my test directory), compile separately before file, and then link all object files and libraries to create the executable. Remember that by doing this, you will no longer need the "-I $ (INCLUDE)" in the linking part, since all files have already been preprocessed and compiled. Follow the code working in Up 3 below.

  

Up 3:

Issue resolved, working code answered below.

    
asked by anonymous 24.06.2017 / 09:01

1 answer

1

GitHub code link:

link

########################################
###Script by PerguGames
###GitHub:https://github.com/PerduGames
########################################
#Arquivo Makefile 
#Arquivo para compilar executavel em c++, 
#buscando as dependencias em suas respectivas pastas
#O que acontece quando digito "make"?
#Busca dentro do diretorio atribuido na variavel "SRC" todos os arquivos .cpp
#Muda o sufixo e prefixo de todos os arquivos: "src/*.cpp" para "obj/*.o"
#Compila os arquivos .cpp e cria os arquivos .o no diretorio atribuido na variavel "OBJ"
#Linka e cria o executavel com o nome que você colocou na variavel "NOME_EXECUTAVEL",
#buscando as bibliotecas e os arquivos-objetos que foram criados
#O que acontece quando digito "make run"?
#Executa o programa "NOME_EXECUTAVEL",
#O que acontece quando digito "make cleanObjetos"?
#Exclui todos os arquivos .o no diretorio atribuido na variavel "OBJ"
#O que acontece quando digito "make clean"?
#Exclui todos os arquivos no diretorio atribuido na variavel "BIN" que seria seu
#executavel que deu o nome em "NOME_EXECUTAVEL"
#O que acontece quando digito "make tar"?
#Empacota todo o diretorio atual onde esta o arquivo makefile com o
#nome que voce colocou na variavel "NOME_EXECUTAVEL"

#Compilador
COMPILADOR=g++
#Nome do seu executavel
NOME_EXECUTAVEL=nomeDoSeuExecutavel
#Diretorio dos arquivos binarios
BIN=./bin
#Diretorio dos arquivos .h e .hpp
INCLUDE=./include
#Diretorio dos arquivos-objetos
OBJ=./obj
#Diretorio dos arquivos .c e .cpp
SRC=./src
#Diretorio dos arquivos de bibliotecas
LIB=./lib

#Para otimizar e mostrar mais avisos
FLAGS= -O3 -Wall
#Para encontrar as bibliotecas utilizadas(em "-lm", apenas um exemplo, caso seu compilador nao faca isso por voce)
LIBS= -lm -L $(LIB)

#Pega todos arquivos .cpp e muda os nomes para .o
#Fontes .cpp
FONTES=$(wildcard $(SRC)/*.cpp)
#Retirar prefixo e sufixo
OBJLIMPAR=$(notdir $(basename $(FONTES)))
#Adicionar novo prefixo e sufixo
OBJETOS=$(addprefix $(OBJ)/, $(addsuffix .o, $(OBJLIMPAR)))

.PHONY: all cleanObjetos clean tar

all: compilar $(NOME_EXECUTAVEL)

#Arquivos .o do projeto
compilar: $(OBJETOS)

#Compilar e criar os arquivos-objetos
$(OBJ)/%.o: $(SRC)/%.cpp $(INCLUDE)/%.hpp
    $(COMPILADOR) $(FLAGS) -c $< -I $(INCLUDE) -o $@

#Linkar e criar o executavel
$(NOME_EXECUTAVEL): $(OBJETOS)
    $(COMPILADOR) $(FLAGS) $(OBJETOS) $(LIBS) -o $(BIN)/$@

#Executar programa
run:
    $(BIN)/$(NOME_EXECUTAVEL)

#Limpar arquivos .o
cleanObjetos:
    rm -f $(OBJ)/*.o

#Limpar executavel
clean:
    rm -f $(BIN)/$(NOME_EXECUTAVEL)

#Empacotar projeto
tar:
    tar cvjf $(NOME_EXECUTAVEL).tar.bz2 pwd
    
29.06.2017 / 01:47