-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
189 lines (152 loc) · 5.41 KB
/
Makefile
File metadata and controls
189 lines (152 loc) · 5.41 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
SHELL = /bin/sh
# version of c++ utilities
CXX = clang++
LINK = clang++
DB = lldb
ifneq "$(target)" "release"
ifneq "$(target)" "debug"
override target = testing
endif # target != debug
endif # target != release
# compiler flags
CPPFLAGS = -std=c++11 -pthread -DHAVE_INLINE -DGTEST_USE_OWN_TR1_TUPLE
CXXFLAGS = -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-qual \
-Wcast-align -Wwrite-strings -fshort-enums -fno-common \
-stdlib=libc++ -march=native
LDFLAGS = -stdlib=libc++ -fuse-ld=gold
LDLIBS = -lc++abi -ltcmalloc -lgsl -lgslcblas -lm -lpthread
ifeq "$(target)" "release"
# add -DNO_ERROR_CHECKING to remove internal error checks
CXXFLAGS += -O3
endif # target == release
ifeq "$(target)" "testing"
CXXFLAGS += -O2 -fvectorize
endif # target == testing
ifeq "$(target)" "debug"
CXXFLAGS += -g -O0 -DDEBUG=1
endif # target == debug
targets = release testing debug
# object files to generate, should be named ${foo}.o where source file
# is ${foo}.c
_OBJ = graph log_msg matrix tensor utils
OBJ = $(patsubst %,$(target)/%.o,$(_OBJ))
ALL_OBJ = $(foreach foo,$(targets),$(patsubst %,$(foo)/%.o,$(_OBJ)))
# file containing main() (excluded from test binary, which defines its
# own main() )
_MAIN = main
MAIN = $(patsubst %,$(target)/%.o,$(_MAIN))
ALL_MAIN = $(foreach foo,$(targets),$(patsubst %,$(foo)/%.o,$(_MAIN)))
# test cases for code in ${foo}.cc should be named ${foo}$(TSUF).cc
# and placed in TDIR
TDIR = test
TSUF = _test
_TESTS = graph tensor utils
TESTS = $(patsubst %,$(target)/%$(TSUF).o,$(_TESTS))
ALL_TESTS = $(foreach foo,$(targets),$(patsubst %,$(foo)/%$(TSUF).o,$(_TESTS)))
MPRE = mock_
_MOCKS = matrix tensor
MOCKS = $(patsubst %,$(target)/$(MPRE)%.o,$(_MOCKS))
ALL_MOCKS = $(foreach foo,$(targets),$(patsubst %,$(foo)/$(MPRE)%.o,$(_MOCKS)))
# main and unit test binaries
_BIN = tensor
_TEST = tensor$(TSUF)
BIN = $(_BIN)_$(target).bin
TEST = $(_TEST)_$(target).bin
# library files that shouldn't normally need to be rebuilt
_LIBS = .a -all.o _main.a _main.o
_LIB_OBJS = $(foreach lib,$(_LIBS),gmock$(lib) gtest$(lib))
LIB_OBJS = $(foreach foo,$(targets),$(patsubst %,$(foo)/%,$(_LIB_OBJS)))
# dependency files
DEPS = $(patsubst %,%.d,$(_OBJ)) \
$(patsubst %,$(TDIR)/%$(TSUF).d,$(_TESTS)) \
$(patsubst %,$(TDIR)/$(MPRE)%.d,$(_MOCKS))
OBJECTS = $(ALL_OBJ) $(ALL_MAIN) $(ALL_TESTS) $(ALL_MOCKS)
GENERATED = $(OBJECTS) $(LIB_OBJS) $(DEPS)
# targets
.PHONY : all
all : $(BIN)
.PHONY : run
run : $(BIN)
./$<
.PHONY : test
test : $(TEST)
./$<
.PHONY : check
check : $(TEST)
./$<
$(BIN) : $(OBJ) $(MAIN)
$(LINK) $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(TEST) : $(OBJ) $(TESTS) $(MOCKS) $(target)/gmock_main.a
$(LINK) $(LDFLAGS) -o $@ $^ $(LDLIBS)
.PHONY : objs
objs : $(OBJ)
$(target)/%.o : %.cc %.d
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
$(target)/%$(TSUF).o : $(TDIR)/%$(TSUF).cc $(TDIR)/%$(TSUF).d
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
$(target)/$(MPRE)%.o : $(TDIR)/$(MPRE)%.cc $(TDIR)/$(MPRE)%.d
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
# include dependency information
include $(patsubst %,%.d,$(_OBJ)) $(patsubst %,%.d,$(_MAIN)) \
$(patsubst %,$(TDIR)/%$(TSUF).d,$(_TESTS)) \
$(patsubst %,$(TDIR)/$(MPRE)%.d,$(_MOCKS))
# generate dependency information
%.d : %.cc
@set -e; rm -f $@; \
$(CC) -MM -MP $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($(*F)\)\.o[ :]*,$(target)/\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
# debugging and cleaning targets
.PHONY : debug
debug : $(BIN)
$(DB) $<
.PHONY : debug_test
debug_test : $(TEST)
$(DB) $<
.PHONY : valgrind
valgrind : $(BIN)
valgrind --trace-children=yes --leak-check=full \
--show-reachable=yes ./$<
.PHONY : clean
clean :
-rm -f $(OBJECTS)
.PHONY : distclean
distclean :
-rm -f $(GENERATED)
# Building Google Test and Google Mock
# location for gtest files
GTEST_DIR = /usr/src/gtest
GTEST_HEADERS = /usr/include/gtest/*.h \
/usr/include/gtest/internal/*.h
GMOCK_DIR = /usr/src/gmock
GMOCK_HEADERS = /usr/include/gmock/*.h \
/usr/include/gmock/internal/*.h
# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_HEADERS)
GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS)
# For simplicity and to avoid depending on Google Test's
# implementation details, the dependencies specified below are
# conservative and not optimized. This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
$(target)/gtest-all.o : $(GTEST_SRCS_) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) \
-c -w -o $@ $(GTEST_DIR)/src/gtest-all.cc
$(target)/gtest_main.o : $(GTEST_SRCS_) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) \
-c -w -o $@ $(GTEST_DIR)/src/gtest_main.cc
$(target)/gmock-all.o : $(GTEST_HEADERS) $(GMOCK_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
-c -w -o $@ $(GMOCK_DIR)/src/gmock-all.cc
$(target)/gmock_main.o : $(GTEST_HEADERS) $(GMOCK_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
-c -w -o $@ $(GMOCK_DIR)/src/gmock_main.cc
$(target)/gtest.a : $(target)/gtest-all.o
$(AR) $(ARFLAGS) $@ $^
$(target)/gtest_main.a : $(target)/gtest-all.o $(target)/gtest_main.o
$(AR) $(ARFLAGS) $@ $^
$(target)/gmock.a : $(target)/gtest-all.o gmock-all.o
$(AR) $(ARFLAGS) $@ $^
$(target)/gmock_main.a : $(target)/gtest-all.o $(target)/gmock-all.o \
$(target)/gmock_main.o
$(AR) $(ARFLAGS) $@ $^