1

I have read other questions asking similar things, alas I am still confused.

This is my current Makefile:

CC = g++

EXEFILE = template

IFLAGS= -I/usr/include/freetype2 -I../Camera
LFLAGS= -L/usr/lib/nvidia-375 -L/usr/local/lib -L/usr/include/GL -L/usr/local/include/freetype2 -L/usr/local/lib/
LIBS = -lglfw -lGL -lGLU -lOpenGL -lGLEW -pthread -lfreetype

SRC=*.cpp
DEPS=*.h

$(EXEFILE): 
    $(CC) -std=c++11 -o $(EXEFILE) -Wall -Wno-comment $(SRC) $(IFLAGS) $(LFLAGS) $(LIBS)

all: run clean

run: $(EXEFILE)
    ./$(EXEFILE)
clean:
    rm $(EXEFILE)

Right now all of my .h files and .cpp files are on the working directory, and everything compiles and runs just fine. My issue is that I have already a large number of files, and it is getting quite messy. I want to create multiple directories (and maybe even directories inside these directories) to organize my files. But as soon as I move a header file and it's corresponding cpp file(s) to a directory inside of the current directory the compiler doesn't know how to link them anymore.

How do I tell my make file to compile and link everything under the current root?

Alternatively, is there a ELI5 guide to makefile syntax?

peterh
  • 11,875
  • 18
  • 85
  • 108
Makogan
  • 8,208
  • 7
  • 44
  • 112
  • Possible duplicate of [Sources from subdirectories in Makefile](http://stackoverflow.com/questions/4036191/sources-from-subdirectories-in-makefile) – flyx Apr 05 '17 at 08:22
  • You'd find your build process works much better if you replace `$(EXEFILE):` with `$(EXEFILE): $(SRC)` - no need to delete the executable to rebuild it. Although really you want `$(OBJ)` in that last stage cos you don't want to have to recompile every source file each time too. – Chris Turner Apr 05 '17 at 08:40
  • For easier compilation - check out Cmake. – SHG Apr 05 '17 at 08:43

2 Answers2

0

The quickest way to solve your problem is to add SRC and DEPS the files contains in all your sub-directories, something like:

 SRC=*.cpp src/*.cpp
 DEPS=*.h inc/*.h

Now you may consider writing a rule to first compile every file in a separate directory:

# Group compilation option
CXXFLAGS := -std=c++11 -Wall -Wno-comment $(IFLAGS)

# A directory to store object files (.o)
ODIR := ./objects

# Read this ugly line from the end:
#  - grep all the .cpp files in SRC with wildcard
#  - add the prefix $(ODIR) to all the file names with addprefix
#  - replace .cpp in .o with patsubst
OBJS := $(patsubst %.cpp,%.o,$(addprefix $(ODIR)/,$(wildcard $(SRC)/*.cpp)))

# Compile all the files in object files
# $@ refers to the rule name, here $(ODIR)/the_current_file.o
# $< refers to first prerequisite, here $(SRC)/the_current_file.cpp
$(ODIR)/%.o:$(SRC)/%.cpp $(DEPS)/%.h
    $(CXX) $(CXXFLAGS) -c -o $@ $<

# Finally link everything in the executable
# $^ refers to ALL the prerequisites
$(EXEFILE): $(OBJS)
    $(CXX) $(CXXFLAGS) -o $@  $^ $(LFLAGS) $(LIBS)
gaFF
  • 747
  • 3
  • 11
0

I found a solution, that, to my tastes seems elegant, or at least easy to trace using the wildcard operator. Here is my current makefile:

    EXEFILE := $(shell basename $(CURDIR))


DIRECTORIES = $(filter-out ./ ./.%, $(shell find ./ -maxdepth 10 -type d))
IFLAGS= -I/usr/include/freetype2
LOCAL_I_DIRS =$(addprefix -I./, $(DIRECTORIES))
LFLAGS= -L/usr/lib/nvidia-375 -L/usr/local/lib -L/usr/include/GL -L/usr/local/include/freetype2 -L/usr/local/lib/
LIBS = -lglfw -lGL -lGLU -lOpenGL -lGLEW -pthread -lfreetype

SRC := $(wildcard *.cpp) $(wildcard **/*.cpp)

$(EXEFILE): $(EXEFILE).cpp
    g++ -std=c++11 -o $(EXEFILE) -Wall -Wno-comment $(SRC) $(IFLAGS) $(LOCAL_I_DIRS) $(LFLAGS) $(LIBS) 

all: run clean

run: $(EXEFILE)
    ./$(EXEFILE)

clean:
    rm $(EXEFILE)

print-%: ; @echo $* = $($*)

So I get all directories up to depth 10. I then take out the current root (./) and any hidden directory (./.) leaving me with standard subdirectories stored under "DIRECTORIES", I then add -I to every directory to make it an include directory and store them in LOCAL_I_DIRS So I can now create as many subdirectories as needed (up to 10 levels) and the compiler will be happy.

Makogan
  • 8,208
  • 7
  • 44
  • 112