4
\$\begingroup\$

This is my first hand crafted makefile in quite a while. I thought it might be useful for anyone who wants to review the Knights Tour - Improved Refactored Recursive Breadth First Search.

I believe there is a lot of room for improvement on this makefile.

The C++ source code as well as the makefile can be found on github.

RM := rm -rf

OBJ_DIR := obj

BIN_DIR := bin

SRC_DIR := # src/

DIRS := $(OBJ_DIR) $(BIN_DIR)

EXECUTABLES := KnightMovesRefactored

# All Target
all: $(DIRS) $(EXECUTABLES)

# Add inputs and outputs from these tool invocations to the build variables 
OBJS += $(OBJ_DIR)/KMBoardLocation.o $(OBJ_DIR)/KMMove.o $(OBJ_DIR)/KMMoveFilters.o \
$(OBJ_DIR)/KMOutputData.o $(OBJ_DIR)/KMPath.o $(OBJ_DIR)/KnightMoves.o \
$(OBJ_DIR)/KnightMovesImplementation.o 

obj/%.o: $(SRC_DIR)%.cpp
    @echo 'Building file: $<'
    @echo 'Invoking: GCC C++ Compiler'
    g++ -std=c++0x -D__cplusplus=201103L -O3 -Wall -c -o "$@" "$<" # Production
#   g++ -std=c++0x -D__cplusplus=201103L -O0 -g3 -Wall -c -o "$@" "$<" # Debug
    @echo 'Finished building: $<'
    @echo ' '

obj/KMBoardLocation.o: $(SRC_DIR)KMBoardLocation.cpp $(SRC_DIR)KnightMoves.h \
 $(SRC_DIR)KMMethodLimitations.h $(SRC_DIR)KMBaseData.h \
 $(SRC_DIR)KMBoardLocation.h $(SRC_DIR)KMBoardDimensionConstants.h

obj/KMMove.o: $(SRC_DIR)KMMove.cpp $(SRC_DIR)KMMove.h $(SRC_DIR)KMBoardLocation.h \
 $(SRC_DIR)KMBoardDimensionConstants.h

obj/KMMoveFilters.o: $(SRC_DIR)KMMoveFilters.cpp \
 $(SRC_DIR)KMBoardDimensionConstants.h $(SRC_DIR)KMMoveFilters.h \
 $(SRC_DIR)KnightMoves.h $(SRC_DIR)KMMethodLimitations.h $(SRC_DIR)KMBaseData.h \
 $(SRC_DIR)KMMove.h $(SRC_DIR)KMBoardLocation.h

obj/KMOutputData.o: $(SRC_DIR)KMOutputData.cpp $(SRC_DIR)KMOutputData.h \
 $(SRC_DIR)KMPath.h $(SRC_DIR)KMBoardLocation.h $(SRC_DIR)KMMove.h \
 $(SRC_DIR)KnightMoves.h $(SRC_DIR)KMMethodLimitations.h $(SRC_DIR)KMBaseData.h

obj/KMPath.o: $(SRC_DIR)KMPath.cpp $(SRC_DIR)KMPath.h $(SRC_DIR)KMBoardLocation.h \
 $(SRC_DIR)KMMove.h $(SRC_DIR)KnightMoves.h $(SRC_DIR)KMMethodLimitations.h \
 $(SRC_DIR)KMBaseData.h $(SRC_DIR)KMBoardDimensionConstants.h

obj/KnightMoves.o: $(SRC_DIR)KnightMoves.cpp $(SRC_DIR)KnightMoves.h \
 $(SRC_DIR)KMMethodLimitations.h $(SRC_DIR)KMBaseData.h \
 $(SRC_DIR)KnightMovesImplementation.h $(SRC_DIR)KMPath.h \
 $(SRC_DIR)KMBoardLocation.h $(SRC_DIR)KMMove.h $(SRC_DIR)KMOutputData.h \
 $(SRC_DIR)KMMoveFilters.h $(SRC_DIR)KMBoardDimensionConstants.h

obj/KnightMovesImplementation.o: $(SRC_DIR)KnightMovesImplementation.cpp \
 $(SRC_DIR)KnightMoves.h $(SRC_DIR)KMMethodLimitations.h $(SRC_DIR)KMBaseData.h \
 $(SRC_DIR)KnightMovesImplementation.h $(SRC_DIR)KMPath.h \
 $(SRC_DIR)KMMethodLimitations.h $(SRC_DIR)KMBaseData.h \
 $(SRC_DIR)KnightMovesImplementation.h $(SRC_DIR)KMPath.h \
 $(SRC_DIR)KMBoardLocation.h $(SRC_DIR)KMMove.h $(SRC_DIR)KMOutputData.h \
 $(SRC_DIR)KMMoveFilters.h $(SRC_DIR)KMBoardDimensionConstants.h

obj/KnightMovesImplementation.o: $(SRC_DIR)KnightMovesImplementation.cpp \
 $(SRC_DIR)KnightMoves.h $(SRC_DIR)KMMethodLimitations.h $(SRC_DIR)KMBaseData.h \
 $(SRC_DIR)KnightMovesImplementation.h $(SRC_DIR)KMPath.h \
 $(SRC_DIR)KMBoardLocation.h $(SRC_DIR)KMMove.h $(SRC_DIR)KMOutputData.h \
 $(SRC_DIR)KMMoveFilters.h $(SRC_DIR)KMBoardDimensionConstants.h

$(SRC_DIR)KnightMoves.h:

$(SRC_DIR)KMMethodLimitations.h:

$(SRC_DIR)KMBaseData.h:

$(SRC_DIR)KnightMovesImplementation.h:

$(SRC_DIR)KMPath.h:

$(SRC_DIR)KMBoardLocation.h:

$(SRC_DIR)KMMove.h:

$(SRC_DIR)KMOutputData.h:

$(SRC_DIR)KMMoveFilters.h:

$(SRC_DIR)KMBoardDimensionConstants.h:

# Add inputs and outputs from these tool invocations to the build variables 

# Tool invocations
KnightMovesRefactored: $(OBJS)
    @echo 'Building target: $@'
    @echo 'Invoking: GCC C++ Linker'
    g++  -o "$(BIN_DIR)/KnightMovesRefactored" $(OBJS)
    ln -s bin/KnightMovesRefactored .
    @echo 'Finished building target: $@'
    @echo ' '

# Other Targets
clean:
    -$(RM) $(DIRS) $(EXECUTABLES)
    -@echo ' '

MKDIR_P := mkdir -p

${OBJ_DIR}:
    ${MKDIR_P} ${OBJ_DIR}

${BIN_DIR}:
    ${MKDIR_P} ${BIN_DIR}

.PHONY: all clean $(DIRS)
.SECONDARY:
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Is there a reason you aren't using a build systems such as CMake? \$\endgroup\$
    – syb0rg
    Jun 27, 2016 at 12:16
  • \$\begingroup\$ @syb0rg In this case I may be too Old School. I've been using eclipse CDT to develop my programs on Linux. It generates it's own makefile from the project. I've used CMake before for other projects where I use vim to write the code. For small projects I really don't want to search to multiple files in multiple directories to see what's going on in the make which is what I have to do with makefiles generated by both CDT and CMake. \$\endgroup\$
    – pacmaninbw
    Jun 27, 2016 at 13:07
  • 1
    \$\begingroup\$ @dfhwze I noticed you asked a question, so I was going to start chatting. I didn't know about your suspension. I'll wait till you aren't suspended anymore. \$\endgroup\$
    – pacmaninbw
    Sep 7, 2019 at 19:23

1 Answer 1

2
\$\begingroup\$

I am too lazy to use just make and write Makefiles by hand. I would use some build system like:

What I would definitely not do by hand is keeping header dependencies for compilation units in Makefile. If for some reason you don't want to use any build system you might at least utilize g++ to generate this.

Check g++ -M and/or this questions:

Are you sure you need this list of empty targets?

$(SRC_DIR)KnightMoves.h:

$(SRC_DIR)KMMethodLimitations.h:

...
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.