new makefile
[xonotic/gmqcc.git] / Makefile
1 # Compilation options:
2 # * LTO       - Link time optimization       [default=0]
3 # * ASAN      - Address sanitizer            [default=0]
4 # * UBSAN     - Undefined behavior sanitizer [default=0]
5 # * DEBUG     - Debug build                  [default=0]
6 # * UNUSED    - Remove unused references     [default=1]
7 # * SRCDIR    - Out of tree builds           [default=./]
8 LTO ?= 0
9 ASAN ?= 0
10 UBSAN ?= 0
11 DEBUG ?= 0
12 UNUSED ?= 1
13 SRCDIR ?= ./
14
15 # Determine if we're building for Windows or not so we can set the right file
16 # extensions for the binaries and exclude the testsuite because it doesn't build
17 # for that platform.
18 ifeq ($(OS),Windows_NT)
19         GMQCC := gmqcc.exe
20         QCVM := qcvm.exe
21 else
22         GMQCC := gmqcc
23         QCVM := qcvm
24         TESTSUITE := testsuite
25 endif
26
27 # C++ compiler
28 CXX ?= clang++
29
30 # Build artifact directories
31 OBJDIR := .build/objs
32 DEPDIR := .build/deps
33
34 # Collect all the source files for GMQCC.
35 GSRCS := ast.cpp
36 GSRCS += code.cpp
37 GSRCS += conout.cpp
38 GSRCS += fold.cpp
39 GSRCS += ftepp.cpp
40 GSRCS += intrin.cpp
41 GSRCS += ir.cpp
42 GSRCS += lexer.cpp
43 GSRCS += main.cpp
44 GSRCS += opts.cpp
45 GSRCS += parser.cpp
46 GSRCS += stat.cpp
47 GSRCS += utf8.cpp
48 GSRCS += util.cpp
49
50 # Collect all the source files for QCVM.
51 QSRCS := exec.cpp
52 QSRCS += stat.cpp
53 QSRCS += util.cpp
54
55 # Collect all the source files for TESTSUITE.
56 TSRCS := conout.cpp
57 TSRCS += opts.cpp
58 TSRCS += stat.cpp
59 TSRCS += test.cpp
60 TSRCS += util.cpp
61
62 #
63 # Compilation flags
64 #
65 CXXFLAGS := -Wall
66 CXXFLAGS += -Wextra
67 CXXFLAGS += -Wno-parentheses
68 CXXFLAGS += -Wno-class-memaccess
69 CXXFLAGS += -Wno-implicit-fallthrough
70 CXXFLAGS += -std=c++11
71
72 # Disable some unneeded features.
73 CXXFLAGS += -fno-exceptions
74 CXXFLAGS += -fno-rtti
75 CXXFLAGS += -fno-asynchronous-unwind-tables
76
77 # Give each function and data it's own section so the linker can remove unused
78 # references to each, producing smaller, tighter binaries.
79 ifeq ($(UNUSED),1)
80         CXXFLAGS += -ffunction-sections
81         CXXFLAGS += -fdata-sections
82 endif
83
84 # Enable link-time optimizations if requested.
85 ifeq ($(LTO),1)
86         CXXFLAGS += -flto
87 endif
88
89 ifeq ($(DEBUG),1)
90         # Ensure there is a frame-pointer in debug builds.
91         CXXFLAGS += -fno-omit-frame-pointer
92
93         # Disable all optimizations in debug builds.
94         CXXFLAGS += -O0
95
96         # Enable debug symbols.
97         CXXFLAGS += -g
98 else
99         # Disable all the stack protection features in release builds.
100         CXXFLAGS += -fno-stack-protector
101         CXXFLAGS += -fno-stack-check
102
103         # Disable frame pointer in release builds when AddressSanitizer isn't present.
104         ifeq ($(ASAN),1)
105                 CXXFLAGS += -fno-omit-frame-pointer
106         else
107                 CXXFLAGS += -fomit-frame-pointer
108         endif
109
110         # Highest optimization flag in release builds.
111         CXXFLAGS += -O3
112 endif
113
114 # Sanitizer selection
115 ifeq ($(ASAN),1)
116         CXXFLAGS += -fsanitize=address
117 endif
118 ifeq ($(UBSAN),1)
119         CXXFLAGS += -fsanitize=undefined
120 endif
121
122 #
123 # Dependency flags
124 #
125 DEPFLAGS := -MMD
126 DEPFLAGS += -MP
127
128 #
129 # Linker flags
130 #
131 LDFLAGS :=
132
133 # Remove unreferenced sections
134 ifeq ($(UNUSED),1)
135         LDFLAGS += -Wl,--gc-sections
136 endif
137
138 # Enable link-time optimizations if request.
139 ifeq ($(LTO),1)
140         LDFLAGS += -flto
141 endif
142
143 # Sanitizer selection
144 ifeq ($(ASAN),1)
145         LDFLAGS += -fsanitize=address
146 endif
147 ifeq ($(UBSAN),1)
148         LDFLAGS += -fsanitize=undefined
149 endif
150
151 # Strip the binaries when not a debug build
152 ifneq (,$(findstring, -g,$(CXXFLAGS)))
153         STRIP := true
154 else
155         STRIP := strip
156 endif
157
158 all: $(GMQCC) $(QCVM) $(TESTSUITE)
159
160 # Build artifact directories.
161 $(DEPDIR):
162         @mkdir -p $(DEPDIR)
163 $(OBJDIR):
164         @mkdir -p $(OBJDIR)
165
166 $(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d | $(OBJDIR) $(DEPDIR)
167         $(CXX) -MT $@ $(DEPFLAGS) -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -c -o $@ $<
168         @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
169
170 $(GMQCC): $(filter %.o,$(GSRCS:%.cpp=$(OBJDIR)/%.o))
171         $(CXX) $^ $(LDFLAGS) -o $@
172         $(STRIP) $@
173
174 $(QCVM): $(filter %.o,$(QSRCS:%.cpp=$(OBJDIR)/%.o))
175         $(CXX) $^ $(LDFLAGS) -o $@
176         $(STRIP) $@
177
178 $(TESTSUITE): $(filter %.o,$(TSRCS:%.cpp=$(OBJDIR)/%.o))
179         $(CXX) $^ $(LDFLAGS) -o $@
180         $(STRIP) $@
181
182 # Determine if the tests should be run.
183 RUNTESTS := true
184 ifdef TESTSUITE
185         RUNTESTS := ./$(TESTSUITE)
186 endif
187
188 test: $(QCVM) $(TESTSUITE)
189         @$(RUNTESTS)
190
191 clean:
192         rm -rf $(DEPDIR) $(OBJDIR)
193
194 .PHONY: test clean $(DEPDIR) $(OBJDIR)
195
196 # Dependencies
197 $(filter %.d,$(GSRCS:%.cpp=$(DEPDIR)/%.d)):
198 include $(wildcard $@)
199
200 $(filter %.d,$(QSRCS:%.cpp=$(DEPDIR)/%.d)):
201 include $(wildcard $@)
202
203 $(filter %.d,$(TSRCS:%.cpp=$(DEPDIR)/%.d)):
204 include $(wildcard $@)