-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
141 lines (110 loc) · 3.89 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# Makefile with:
# - support for recursive subdirectories
# - support for seperate test file in a seperate directory
# - support for some C files
#
# Note that this files makes a some assumtions about the recursive makefiles:
# they must have a "base" target which does not make the main() function, they
# must have the same definition of SRC_DIR, TEST_DIR, MAINFILE and OBJ_DIR.
#
# Currently only support building 1 level deep
###############################################################################
# CONFIGURATION
###############################################################################
# Folders
SRC_DIR = src
OBJ_DIR := build
TEST_DIR := tests
# Compiler
CC_CPP = g++
CC_C = gcc
# Other include directories with headers
INC :=
# Compiling flags
DEBUG_FLAGS := -Og
OPTIM_FLAGS := -O3
WARNING_FLAGS := -Wno-deprecated-declarations -Wall -Wextra -pedantic \
-Weffc++ -Wold-style-cast -Woverloaded-virtual
CPPFLAGS := -std=c++17 -fmax-errors=3 -MMD $(INC) $(OPTIM_FLAGS) $(WARNING_FLAGS)
CFLAGS := -Wall -Wextra -pedantic
CFLAGS += $(INC)
# Linking flags
LDFLAGS +=
# File which contains the main function
MAINFILE := main.cpp
# Name of output
OUTNAME := main.out
TEST_OUTNAME := test.out
# Subdirectories which needs to be built
SUBDIRS :=
###############################################################################
CPP_SOURCE := $(shell find $(SRC_DIR) -name '*.cpp' ! -name $(MAINFILE))
TEST_SOURCE := $(shell find $(TEST_DIR) -name '*.cpp')
C_SOURCE := $(shell find $(SRC_DIR) -name '*.c')
MAINOBJ := $(patsubst %.cpp,%.o, $(MAINFILE))
CPP_OBJS := $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(CPP_SOURCE))
C_OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(C_SOURCE))
TEST_OBJS := $(patsubst $(TEST_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(TEST_SOURCE))
ALL_OBJS := $(CPP_OBJS) $(C_OBJS) $(TEST_OBJS) $(OBJ_DIR)/$(MAINOBJ)
DEPS := $(patsubst %.o, %.d, $(ALL_OBJS))
# Add subdirectories
CPPFLAGS += $(foreach d, $(SUBDIRS), -I$(d)/$(SRC_DIR))
SUBDIR_OBJS = $(wildcard $(foreach d, $(SUBDIRS), $(d)/$(OBJ_DIR)/*.o))
# Main objetice - created with 'make' or 'make main'.
main: subdirs base $(OBJ_DIR)/$(MAINOBJ)
@ echo Linking main file
@ $(CC_CPP) -pthread $(CPPFLAGS) -o $(OUTNAME) \
$(CPP_OBJS) $(C_OBJS) $(OBJ_DIR)/$(MAINOBJ) $(SUBDIR_OBJS) $(LDFLAGS)
@ echo ""
# Test objetice
tests: subdirs base $(TEST_OBJS)
@ echo Linking test file
@ $(CC_CPP) -pthread $(CPPFLAGS) -I$(SRC_DIR) -o $(TEST_OUTNAME) \
$(CPP_OBJS) $(C_OBJS) $(TEST_OBJS) $(SUBDIR_OBJS) $(LDFLAGS)
@ echo ""
# Recursive make of subdirectories
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
@ rm -f $@/$(OBJ_DIR)/$(MAINOBJ)
@ rm -f $@/$(OBJ_DIR)/check.o
@ rm -f $@/$(OBJ_DIR)/tests.o
@ if [ ! -d "$@/$(SRC_DIR)" ]; then \
printf "\033[0;31mSubdirectory $@ missing or broken\n\033[0m"; fi
$(MAKE) base -C $@
# Compile everything except mainfile
base: $(OBJ_DIR) $(CPP_OBJS) $(C_OBJS) Makefile
# Compile C++ objects
$(CPP_OBJS) $(OBJ_DIR)/$(MAINOBJ): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
@ echo Compiling $<
@ $(CC_CPP) $(CPPFLAGS) -c $< -o $@
# Compile C objects
$(C_OBJS): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
@ echo Compiling $<
@ $(CC_C) $(CFLAGS) -c $< -o $@
# Test program objects
$(TEST_OBJS): $(OBJ_DIR)/%.o: $(TEST_DIR)/%.cpp
@ echo Compiling $<
@ $(CC_CPP) -I$(SRC_DIR) $(CPPFLAGS) -c $< -o $@
# Create build directory
$(OBJ_DIR):
@ mkdir -p $(OBJ_DIR)
# Run output file (and compile it if needed)
run: main
@ ./$(OUTNAME)
# Run test file (and compile it if needed)
check: tests
@ ./$(TEST_OUTNAME)
# Run but with a memory leak test
run-leaktest: main
@ valgrind --leak-check=full ./$(OUTNAME)
check-leaktest: tests
@ valgrind --leak-check=full ./$(TEST_OUTNAME)
# 'make clean' removes object files and memory dumps.
.PHONY: clean
clean:
@ \rm -rf $(foreach d, $(SUBDIRS) ., $(d)/$(OBJ_DIR)) *.gch core
# 'make zap' also removes the executable and backup files.
zap: clean
@ \rm -rf $(OUTNAME) $(OUTNAME) *~
-include $(DEPS)