Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 62 additions & 37 deletions templates/cpp/Makefile
Original file line number Diff line number Diff line change
@@ -1,99 +1,124 @@
#
# 'make' build executable file 'main'
# 'make' builds executable file 'main'
# 'make clean' removes all .o and executable files
# 'make start' builds executable file 'main' and executes it
#

# define the Cpp compiler to use
CXX = g++

# define any compile-time flags
CXXFLAGS := -std=c++17 -Wall -Wextra -g
CXXFLAGS := -std=c++17 -Wall -Wextra -g

# define library paths in addition to /usr/lib
# if I wanted to include libraries not in /usr/lib I'd specify
# their path using -Lpath, something like:
LFLAGS =

# define output directory
OUTPUT := output
OUTPUT := output

# define build directory
BUILD := build

# define source directory
SRC := src
SRC := src

# define include directory
INCLUDE := include
INCLUDE := include

# define lib directory
LIB := lib
LIB := lib

# enable or disable parallel build (true/false)
PARALLEL_BUILD := true

ifeq ($(OS),Windows_NT)
MAIN := main.exe
SOURCEDIRS := $(SRC)
INCLUDEDIRS := $(INCLUDE)
LIBDIRS := $(LIB)
MAIN := main.exe
SOURCEDIRS := $(SRC)
INCLUDEDIRS := $(INCLUDE)
LIBDIRS := $(LIB)
FIXPATH = $(subst /,\,$1)
RM := del /q /f
MD := mkdir
RM := del /q /f
MD := mkdir
else
MAIN := main
SOURCEDIRS := $(shell find $(SRC) -type d)
INCLUDEDIRS := $(shell find $(INCLUDE) -type d)
LIBDIRS := $(shell find $(LIB) -type d)
MAIN := main
SOURCEDIRS := $(shell find $(SRC) -type d)
INCLUDEDIRS := $(shell find $(INCLUDE) -type d)
LIBDIRS := $(shell find $(LIB) -type d)
FIXPATH = $1
RM = rm -f
MD := mkdir -p
MD := mkdir -p
endif

# define any directories containing header files other than /usr/include
INCLUDES := $(patsubst %,-I%, $(INCLUDEDIRS:%/=%))
INCLUDES := $(patsubst %,-I%, $(INCLUDEDIRS:%/=%))

# define the C libs
LIBS := $(patsubst %,-L%, $(LIBDIRS:%/=%))
LIBS := $(patsubst %,-L%, $(LIBDIRS:%/=%))

# define the C source files
SOURCES := $(wildcard $(patsubst %,%/*.cpp, $(SOURCEDIRS)))
SOURCES := $(wildcard $(patsubst %,%/*.cpp, $(SOURCEDIRS)))

# define the C object files
OBJECTS := $(SOURCES:.cpp=.o)
# define the C object files (stored in build/)
OBJECTS := $(patsubst $(SRC)/%, $(BUILD)/$(SRC)/%, $(SOURCES:.cpp=.o))

# define the dependency output files
DEPS := $(OBJECTS:.o=.d)
# define the dependency output files (also in build/)
DEPS := $(OBJECTS:.o=.d)

#
# The following part of the makefile is generic; it can be used to
# build any executable just by changing the definitions above and by
# deleting dependencies appended to the file from 'make depend'
#

OUTPUTMAIN := $(call FIXPATH,$(OUTPUT)/$(MAIN))
OUTPUTMAIN := $(call FIXPATH,$(OUTPUT)/$(MAIN))

all: $(OUTPUT) $(MAIN)
all: $(BUILD) $(OUTPUT)
ifeq ($(PARALLEL_BUILD),true)
@$(MAKE) -j $(OUTPUTMAIN)
else
@$(MAKE) $(OUTPUTMAIN)
endif
@echo Executing 'all' complete!

$(BUILD):
$(MD) $(BUILD)

$(OUTPUT):
$(MD) $(OUTPUT)

$(MAIN): $(OBJECTS)
# Link all object files into the final executable
$(OUTPUTMAIN): $(OBJECTS)
$(CXX) $(CXXFLAGS) $(INCLUDES) -o $(OUTPUTMAIN) $(OBJECTS) $(LFLAGS) $(LIBS)

# include all .d files
-include $(DEPS)

# this is a suffix replacement rule for building .o's and .d's from .c's
# it uses automatic variables $<: the name of the prerequisite of
# the rule(a .c file) and $@: the name of the target of the rule (a .o file)
# -MMD generates dependency output files same name as the .o file
# (see the gnu make manual section about automatic variables)
.cpp.o:
$(CXX) $(CXXFLAGS) $(INCLUDES) -c -MMD $< -o $@
# This rule builds .o and .d files from .cpp sources
# It automatically creates the necessary subdirectories inside build/
$(BUILD)/$(SRC)/%.o: $(SRC)/%.cpp
@$(MD) $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) -c -MMD $< -o $@

.PHONY: clean
clean:
$(RM) $(OUTPUTMAIN)
$(RM) $(call FIXPATH,$(OBJECTS))
$(RM) $(call FIXPATH,$(DEPS))
$(RM) -r $(call FIXPATH,$(BUILD))
$(RM) -r $(call FIXPATH,$(OUTPUT))
@echo Cleanup complete!

run: all
./$(OUTPUTMAIN)
@echo Executing 'run: all' complete!

# ---------------------------------------------------------------------
# Start target: runs the built executable, building it first if needed
# ---------------------------------------------------------------------
.PHONY: start
start:
ifeq ($(wildcard $(OUTPUTMAIN)),)
@echo "Executable not found. Building first..."
@$(MAKE) all
endif
@echo "Starting program..."
./$(OUTPUTMAIN)