-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
248 lines (208 loc) · 6.82 KB
/
Makefile
File metadata and controls
248 lines (208 loc) · 6.82 KB
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
######################################################################
# Makefile for Machine Learning Compilers
# Author: lgrumbach, lobitz
######################################################################
# TOOLS
CXX = g++
LD = g++
CPP_VERSION = c++20
# LIBS
LIBS =
LIB_NAME = libmlc
# DIRECTORIES
SRC_DIR = src
TEST_DIR = tests
UNIT_TESTS_DIR = $(TEST_DIR)/unit
INT_TESTS_DIR = $(TEST_DIR)/integration
BIN_DIR_ROOT = build
KERNELS_DIR = $(BIN_DIR_ROOT)/kernels
LIB_DIR = lib
INC_DIR = include
SUB_DIR = $(SRC_DIR)/submissions
# COMPILER FLAGS
CXXFLAGS = -std=$(CPP_VERSION)
CXXFLAGS += -O2
CXXFLAGS += -g
CXXFLAGS += -Wall
CXXFLAGS += -Wextra
CXXFLAGS += -Wpedantic
# Suppress warnings from Catch2 and standard library regex
CXXFLAGS += -Wno-maybe-uninitialized
CXXFLAGS += -Wno-unknown-warning-option
# LINKER FLAGS
LDFLAGS =
# SANITIZER FLAGS
SAN_CXX_FLAGS = -g
SAN_CXX_FLAGS += -fsanitize=float-divide-by-zero
SAN_CXX_FLAGS += -fsanitize=bounds
SAN_CXX_FLAGS += -fsanitize=address
SAN_CXX_FLAGS += -fsanitize=undefined
SAN_CXX_FLAGS += -fno-omit-frame-pointer
SAN_LD_FLAGS = -g
SAN_LD_FLAGS += -fsanitize=address
SAN_LD_FLAGS += -fsanitize=undefined
# TARGET OS
ifeq ($(OS),Windows_NT)
OS = windows
else
UNAME := $(shell uname -s)
ifneq (,$(findstring _NT,$(UNAME)))
OS = windows
else ifeq ($(UNAME),Darwin)
OS = macOS
else ifeq ($(UNAME),Linux)
OS = linux
else
$(error OS not supported by this Makefile)
endif
endif
ARCH := $(shell uname -m)
# Check which compiler is used on macos
ifeq ($(OS),macOS)
ifneq (,$(findstring Apple clang,$(shell $(CXX) --version)))
$(warning Apple clang does not support OpenMP. Switching to LLVM)
LLVM_LOCATION = $(shell brew --prefix llvm)
CXX = $(LLVM_LOCATION)/bin/clang++
LD = $(LLVM_LOCATION)/bin/clang++
endif
endif
# SET AR ON MAC THAT IS NOT INSTALLED BY HOMEBREW
AR := ar
ifeq ($(OS),macOS)
AR := $(shell xcrun --find ar)
endif
# OS-SPECIFIC DIRECTORIES
BIN_DIR := $(BIN_DIR_ROOT)/$(OS)
ifeq ($(OS),windows)
# Windows 32-bit
ifeq ($(win32),1)
BIN_DIR := $(BIN_DIR)32
# Windows 64-bit
else
BIN_DIR := $(BIN_DIR)64
endif
else ifeq ($(OS),macOS)
BIN_DIR := $(BIN_DIR)-$(ARCH)
endif
# Threads
LDFLAGS += -lpthread
ifneq ($(OS),macOS)
CXXFLAGS += -pthread
endif
# OPENMP
ifeq ($(OS),macOS)
CXXFLAGS += -Xpreprocessor
LDFLAGS += -Xpreprocessor
LIBOMP_LOCATION = $(shell brew --prefix libomp)
CXXFLAGS += -I$(LIBOMP_LOCATION)/include
LDFLAGS += -L$(LIBOMP_LOCATION)/lib
LDFLAGS += -lomp
LDFLAGS += -Wl,-rpath,$(LIBOMP_LOCATION)/lib
endif
CXXFLAGS += -fopenmp
LDFLAGS += -fopenmp
# INCLUDES
# INCFLAGS = -I$(LIB_DIR)
INCFLAGS = -I$(INC_DIR)
INCFLAGS += -I$(TEST_DIR)
INCFLAGS += -I/usr/local/include
ifeq ($(OS),macOS)
ifeq ($(ARCH),arm64)
INCFLAGS += -I/opt/homebrew/include
else ifeq ($(ARCH),x86_64)
INCFLAGS += -I/usr/local/include
endif
endif
# Windows and Linux might need additional includes
# But for now, we assume the standard locations are sufficient
# LINKER LIBRARIES
ifeq ($(OS),macOS)
ifeq ($(ARCH),arm64)
LDFLAGS += -L/opt/homebrew/lib
else ifeq ($(ARCH),x86_64)
LDFLAGS += -L/usr/local/lib
endif
endif
# GATHER ALL SOURCES
ifeq ($(OS),macOS)
SRC = $(shell find $(SRC_DIR) -name "*.cpp" ! -name "*.bench.cpp")
UNIT_TEST_SRC = $(shell find $(UNIT_TESTS_DIR) -name "*.cpp")
# INT_TEST_SRC = $(shell find $(INT_TESTS_DIR) -name "*.cpp")
BENCH_SRC = $(shell find $(SRC_DIR) -name "*.bench.cpp")
SUBMISSIONS = $(shell find $(SUB_DIR) -type f)
else ifeq ($(OS),linux)
SRC = $(shell find $(SRC_DIR) -name "*.cpp" ! -name "*.bench.cpp")
UNIT_TEST_SRC = $(shell find $(UNIT_TESTS_DIR) -name "*.cpp")
# INT_TEST_SRC = $(shell find $(INT_TESTS_DIR) -name "*.cpp")
BENCH_SRC = $(shell find $(SRC_DIR) -name "*.bench.cpp")
SUBMISSIONS = $(shell find $(SUB_DIR) -type f)
else ifeq ($(OS),windows)
find_files = $(foreach n,$1,$(shell C:\\\msys64\\\usr\\\bin\\\find.exe -L $2 -name "$n"))
SRC = $(call find_files,*.cpp,$(SRC_DIR))
UNIT_TEST_SRC = $(call find_files,*.cpp,$(UNIT_TESTS_DIR))
# INT_TEST_SRC = $(call find_files,*.cpp,$(INT_TESTS_DIR))
BENCH_SRC = $(call find_files,*.bench.cpp,$(SRC_DIR))
SUBMISSIONS = $(call find_files,*,$(SUB_DIR))
endif
# MAIN FILES FOR ENTRY POINTS
TESTS_MAIN_SRC = $(TEST_DIR)/tests.cpp
BENCH_MAIN_SRC = $(SRC_DIR)/benchmarks.cpp
# COMMON SOURCES (EXCEPT MAIN FILES)
COMMON_SRC = $(filter-out $(SUBMISSIONS) $(BENCH_MAIN_SRC) $(BENCH_SRC), $(SRC))
# DEP
COMMON_DEP = $(COMMON_SRC:%.cpp=$(BIN_DIR)/%.d)
TESTS_MAIN_DEP = $(TESTS_MAIN_SRC:%.cpp=$(BIN_DIR)/%.d)
UNIT_TEST_DEP = $(UNIT_TEST_SRC:%.cpp=$(BIN_DIR)/%.d)
INT_TEST_DEP = $(INT_TEST_SRC:%.cpp=$(BIN_DIR)/%.d)
BENCH_MAIN_DEP = $(BENCH_MAIN_SRC:%.cpp=$(BIN_DIR)/%.d)
BENCH_DEP = $(BENCH_SRC:%.cpp=$(BIN_DIR)/%.d)
-include $(COMMON_DEP)
-include $(TESTS_MAIN_DEP)
-include $(UNIT_TEST_DEP)
-include $(INT_TEST_DEP)
-include $(BENCH_MAIN_DEP)
-include $(BENCH_DEP)
# Convert sources to object files
COMMON_OBJ = $(COMMON_SRC:%.cpp=$(BIN_DIR)/%.o)
TESTS_MAIN_OBJ = $(TESTS_MAIN_SRC:%.cpp=$(BIN_DIR)/%.o)
UNIT_TEST_OBJ = $(UNIT_TEST_SRC:%.cpp=$(BIN_DIR)/%.o)
INT_TEST_OBJ = $(INT_TEST_SRC:%.cpp=$(BIN_DIR)/%.o)
BENCH_MAIN_OBJ = $(BENCH_MAIN_SRC:%.cpp=$(BIN_DIR)/%.o)
BENCH_OBJ = $(BENCH_SRC:%.cpp=$(BIN_DIR)/%.o)
# TARGETS
default: static-library unit-tests
$(BIN_DIR):
mkdir -p $@
createdirs: $(BIN_DIR)
$(BIN_DIR)/%.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) -o $@ -MMD -c $< $(CXXFLAGS) $(INCFLAGS)
static-library: $(LIB_DIR)/$(LIB_NAME).a
shared-library: $(LIB_DIR)/$(LIB_NAME).so
$(LIB_DIR):
mkdir -p $@
$(LIB_DIR)/$(LIB_NAME).a: $(COMMON_OBJ) | $(LIB_DIR)
$(AR) rcs $@ $^
$(LIB_DIR)/$(LIB_NAME).so: $(COMMON_OBJ) | $(LIB_DIR)
$(CXX) -shared -o $@ $^ $(LDFLAGS)
benchmarks: createdirs $(COMMON_OBJ) $(BENCH_MAIN_OBJ) $(BENCH_OBJ)
$(LD) -o $(BIN_DIR)/benchmarks $(COMMON_OBJ) $(BENCH_MAIN_OBJ) $(BENCH_OBJ) $(LDFLAGS) $(LIBS)
unit-tests: createdirs $(COMMON_OBJ) $(TESTS_MAIN_OBJ) $(UNIT_TEST_OBJ)
$(LD) -o $(BIN_DIR)/$(TEST_DIR)/unit-tests $(COMMON_OBJ) $(TESTS_MAIN_OBJ) $(UNIT_TEST_OBJ) $(LDFLAGS) $(LIBS)
int-tests: createdirs $(COMMON_OBJ) $(TESTS_MAIN_OBJ) $(INT_TEST_OBJ)
$(LD) -o $(BIN_DIR)/$(TEST_DIR)/int-tests $(COMMON_OBJ) $(TESTS_MAIN_OBJ) $(INT_TEST_OBJ) $(LDFLAGS) $(LIBS)
tests: unit-tests int-tests
unit-tests-san: CXXFLAGS := $(SAN_CXX_FLAGS) $(CXXFLAGS)
unit-tests-san: LDFLAGS := $(SAN_LD_FLAGS) $(LDFLAGS)
unit-tests-san: createdirs $(COMMON_OBJ) $(TESTS_MAIN_OBJ) $(UNIT_TEST_OBJ)
$(LD) -o $(BIN_DIR)/$(TEST_DIR)/unit-tests-san $(COMMON_OBJ) $(TESTS_MAIN_OBJ) $(UNIT_TEST_OBJ) $(LDFLAGS) $(LIBS)
int-tests-san: CXXFLAGS := $(SAN_CXX_FLAGS) $(CXXFLAGS)
int-tests-san: LDFLAGS := $(SAN_LD_FLAGS) $(LDFLAGS)
int-tests-san: createdirs $(COMMON_OBJ) $(TESTS_MAIN_OBJ) $(INT_TEST_OBJ)
$(LD) -o $(BIN_DIR)/$(TEST_DIR)/int-tests-san $(COMMON_OBJ) $(TESTS_MAIN_OBJ) $(INT_TEST_OBJ) $(LDFLAGS) $(LIBS)
tests-san: unit-tests-san int-tests-san
.PHONY: clean
clean:
rm -rf $(LIB_DIR)
rm -rf $(BIN_DIR)
rm -rf $(KERNELS_DIR)