2
\$\begingroup\$

Ok this is the first makefile I've ever written. I it works and that's about it. Things that I was wondering if if I can specify where the object files go. It looks really bad with all the .o files cluttering the working folder. I was thinking a src folder and maybe a obj folder? Is there a better naming convention for Compiler_flags and c_compiler_flags? Also is there other ways of optimizing the makefile? Thanks all help is extremely appreciated.

OBJS = close.o init.o main.o texture.o load_media.o
CC = g++
COMPILER_FLAGS = -w
C_COMPILER_FLAGS = -c -w
LINKER_FLAGS = -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf
OBJ_NAME = run
all : exe
debug : COMPILER_FLAGS += -g
debug : C_COMPILER_FLAGS += -g
debug : exe
exe : $(OBJS)
 $(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OBJ_NAME)
close.o : isolation.h close.cpp
 $(CC) $(C_COMPILER_FLAGS) $(LINKER_FLAGS) close.cpp
init.o : isolation.h init.cpp
 $(CC) $(C_COMPILER_FLAGS) $(LINKER_FLAGS) init.cpp
main.o : isolation.h main.cpp
 $(CC) $(C_COMPILER_FLAGS) $(LINKER_FLAGS) main.cpp
texture.o : isolation.h texture.h texture.cpp
 $(CC) $(C_COMPILER_FLAGS) $(LINKER_FLAGS) texture.cpp
load_media.o : isolation.h load_media.cpp
 $(CC) $(C_COMPILER_FLAGS) $(LINKER_FLAGS) load_media.cpp
clean:
 \rm *.o *~ run
asked Aug 1, 2016 at 2:03
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$
  • There is no need to pass linker flags to the compile stage. You only them when you link the final executable.

  • Traditionally (aligned with make defaults) the flags variables are CFLAGS for C compiler, CXXFLAGS for C++ compiler, and LDFAGS for the link stage specifics. It is not recommended however to have -c as a part of CFLAGS: the CFLAGS can be reused for non-compile action (e.g. dependency generation as described below).

  • exe is a phony target (and better be specified as such); a file named exe is never created, so it is never up to date, and the makefile forces linking even if nothing has been changed. I recommend to change the link recipe to

    $(OBJ_NAME): $(OBJS)
     ....
    
  • Stem rules let you DRY:

    %.o: %.cpp
     $(CC) $(CXXFLAGS) $<
    
  • For a separate build directory you may look at VPATH; I prefer to to point it explicitly in the stem rule:

    $(BUILD)/%.o: %.cpp
     $(CC) -o $@ $(CXXFLAGS) $<
    

    As a side note, I'd go one step further, and separate debug and release builds.

  • Dependency generation. The stem rules above do not specify #include dependencies. With gcc it is easy to automate. -M family of flags:

    $(BUILD)/%.d: %.cpp
     $(CC) -o $@ -MM -MT $(CXXFLAGS) $<
    

    create a makefile fragment which you'd include in your makefile.

    Since the dep and obj file names mirror the source file names (only the extension differs) it is recommended to generate them using the patsubst function.

  • Never use -w. Warnings are your friends. I highly recommend passing at least -Wall -Wextra.

  • Putting it (almost) all together,

    SRC = close.cpp init.cpp main.cpp texture.cpp load_media.cpp
    OBJ = $(patsubst %.cpp,$(BUILD)/%.o,$(SRC))
    DEP = $(patsubst %.cpp,$(BUILD)/%.o,%(SRC))
    TARGET = run
    $(BUILD)/%.o: %.cpp
     $(CXX) -c -o $@ $(CXXFLAGS) $<
    $(BUILD)/%.d: %.cpp
     $(CXX) -MM -MT -o $@ $(CXXFLAGS) $<
    -include $(DEP)
    $(BUILD)/$(TARGET): $(OBJ)
     $(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) $(OBJ)
    
answered Aug 1, 2016 at 17:50
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.