blob: 792482cf36bd8a9136e4b094bdcae75b8bd34edf [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001# GRPC global makefile
2# This currently builds C and C++ code.
3<%!
4 from copy import deepcopy
5 import re
6
7 def excluded(filename, exclude_res):
8 for r in exclude_res:
9 if r.match(filename):
10 return True
11 return False
12%>
13
14<%
15 altlibs = []
16 for lib in libs:
17 for alt in lib.get('alternates', []):
18 new = deepcopy(lib)
19 new.name = alt.name
20 new.alternates = []
21 exclude_res = [re.compile(str) for str in alt.get('exclude_res', [])]
22
23 src = [file for file in new.get('src', []) if not excluded(file, exclude_res)]
24 src.extend(alt.get('include_src', []))
25 new.src = src
26
27 headers = [file for file in new.get('headers', []) if not excluded(file, exclude_res)]
28 headers.extend(alt.get('include_headers', []))
29 new.headers = headers
30
31 public_headers = [file for file in new.get('public_headers', []) if not excluded(file, exclude_res)]
32 public_headers.extend(alt.get('include_public_headers', []))
33 new.public_headers = public_headers
34
35 for prop in alt.properties:
36 new[prop.name] = prop.value
37
38 altlibs.append(new)
39 libs.extend(altlibs)
40
41 protos_dict = {}
42 proto_re = re.compile('\.proto$')
43 for lib in libs:
44 for src in lib.src:
45 if proto_re.match(src):
46 protos_dict[src] = True
47 for tgt in targets:
48 for src in tgt.src:
49 if proto_re.match(src):
50 protos_dict[src] = True
51
52 protos = []
53 for k, v in protos_dict:
54 protos.append(k)
55%>
56
57# General settings.
58# You may want to change these depending on your system.
59
60prefix ?= /usr/local
61
62PROTOC = protoc
63CC = gcc
64CXX = g++
65LD = gcc
66LDXX = g++
67AR = ar
68STRIP = strip --strip-unneeded
69INSTALL = install -D
70RM = rm -f
71
72ifeq ($(DEBUG),)
73CPPFLAGS += -O2
74DEFINES += NDEBUG
75else
76CPPFLAGS += -O0
77DEFINES += _DEBUG DEBUG
78endif
79
80CFLAGS += -std=c89 -pedantic
81CXXFLAGS += -std=c++11
82CPPFLAGS += -g -fPIC -Wall -Werror -Wno-long-long
83LDFLAGS += -g -pthread -fPIC
84
85INCLUDES = . include gens
86LIBS = rt m z event event_pthreads pthread
87LIBSXX = protobuf
88LIBS_SECURE = ssl crypto dl
89
90ifneq ($(wildcard /usr/src/gtest/src/gtest-all.cc),)
91GTEST_LIB = /usr/src/gtest/src/gtest-all.cc -I/usr/src/gtest
92else
93GTEST_LIB = -lgtest
94endif
95
96ifeq ($(V),1)
97E = @:
98Q =
99else
100E = @echo
101Q = @
102endif
103
104VERSION = ${settings.version.major}.${settings.version.minor}.${settings.version.micro}.${settings.version.build}
105
106CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
107CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
108
109LDFLAGS += $(ARCH_FLAGS)
110LDLIBS += $(addprefix -l, $(LIBS))
111LDLIBSXX += $(addprefix -l, $(LIBSXX))
112LDLIBS_SECURE += $(addprefix -l, $(LIBS_SECURE))
113
114.SECONDARY = %.pb.h %.pb.cc
115
116all: static shared\
117% for tgt in targets:
118% if tgt.build == 'all':
119 bins/${tgt.name}\
120% endif
121% endfor
122
nnoble29e1d292014-12-01 10:27:40 -0800123static: static_c static_cxx
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800124
nnoble0c475f02014-12-05 15:37:39 -0800125static_c: make_dirs dep_c\
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800126% for lib in libs:
nnoble29e1d292014-12-01 10:27:40 -0800127% if lib.build == 'all' and not lib.get('c++', False):
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800128 libs/lib${lib.name}.a\
129% endif
130% endfor
131
132
nnoble0c475f02014-12-05 15:37:39 -0800133static_cxx: make_dirs dep_cxx\
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800134% for lib in libs:
nnoble29e1d292014-12-01 10:27:40 -0800135% if lib.build == 'all' and lib.get('c++', False):
136 libs/lib${lib.name}.a\
137% endif
138% endfor
139
140
141shared: shared_c shared_cxx
142
nnoble0c475f02014-12-05 15:37:39 -0800143shared_c: make_dirs dep_c\
nnoble29e1d292014-12-01 10:27:40 -0800144% for lib in libs:
145% if lib.build == 'all' and not lib.get('c++', False):
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800146 libs/lib${lib.name}.so.$(VERSION)\
147% endif
148% endfor
149
150
nnoble0c475f02014-12-05 15:37:39 -0800151shared_cxx: make_dirs dep_cxx\
nnoble29e1d292014-12-01 10:27:40 -0800152% for lib in libs:
153% if lib.build == 'all' and lib.get('c++', False):
154 libs/lib${lib.name}.so.$(VERSION)\
155% endif
156% endfor
157
158
159privatelibs: privatelibs_c privatelibs_cxx
160
nnoble0c475f02014-12-05 15:37:39 -0800161privatelibs_c: make_dirs dep_c\
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800162% for lib in libs:
163% if lib.build == 'private':
164 libs/lib${lib.name}.a\
165% endif
166% endfor
167
168
nnoble0c475f02014-12-05 15:37:39 -0800169privatelibs_cxx: make_dirs dep_cxx\
nnoble29e1d292014-12-01 10:27:40 -0800170% for lib in libs:
171% if lib.build == 'private':
172 libs/lib${lib.name}.a\
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800173% endif
174% endfor
175
176
nnoble29e1d292014-12-01 10:27:40 -0800177buildtests: buildtests_c buildtests_cxx
178
179buildtests_c: privatelibs_c\
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800180% for tgt in targets:
181% if tgt.build == 'test' and not tgt.get('c++', False):
182 bins/${tgt.name}\
183% endif
184% endfor
185
186
nnoble29e1d292014-12-01 10:27:40 -0800187buildtests_cxx: privatelibs_cxx\
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800188% for tgt in targets:
nnoble29e1d292014-12-01 10:27:40 -0800189% if tgt.build == 'test' and tgt.get('c++', False):
190 bins/${tgt.name}\
191% endif
192% endfor
193
194
195tests: tests_c tests_cxx
196
197tests_c: buildtests_c
198% for tgt in targets:
199% if tgt.build == 'test' and tgt.get('run', True) and not tgt.get('c++', False):
200 $(E) "[RUN] Testing ${tgt.name}"
201 $(Q) ./bins/${tgt.name} || ( echo test ${tgt.name} failed ; exit 1 )
202% endif
203% endfor
204
205
206tests_cxx: buildtests_cxx
207% for tgt in targets:
208% if tgt.build == 'test' and tgt.get('run', True) and tgt.get('c++', False):
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800209 $(E) "[RUN] Testing ${tgt.name}"
210 $(Q) ./bins/${tgt.name} || ( echo test ${tgt.name} failed ; exit 1 )
211% endif
212% endfor
213
214
215tools: privatelibs\
216% for tgt in targets:
217% if tgt.build == 'tool':
218 bins/${tgt.name}\
219% endif
220% endfor
221
222
223buildbenchmarks: privatelibs\
224% for tgt in targets:
225% if tgt.build == 'benchmark':
226 bins/${tgt.name}\
227% endif
228% endfor
229
230
231benchmarks: buildbenchmarks
232
233make_dirs:
234 $(Q) mkdir -p libs
235 $(Q) mkdir -p bins
236 $(Q) mkdir -p gens
237
238strip: strip-static strip-shared
239
240strip-static: static
241% for lib in libs:
242% if lib.build == "all":
243 $(E) "[STRIP] Stripping lib${lib.name}.a"
244 $(Q) $(STRIP) libs/lib${lib.name}.a
245% endif
246% endfor
247
248strip-shared: shared
249% for lib in libs:
250% if lib.build == "all":
251 $(E) "[STRIP] Stripping lib${lib.name}.so"
252 $(Q) $(STRIP) libs/lib${lib.name}.so.$(VERSION)
253% endif
254% endfor
255
256gens/%.pb.cc : %.proto
257 $(E) "[PROTOC] Generating protobuf CC file from $<"
258 $(Q) mkdir -p `dirname $@`
259 $(Q) $(PROTOC) --cpp_out=gens $<
260
261deps/%.dep : %.c
262 $(E) "[DEP] Generating dependencies for $<"
263 $(Q) mkdir -p `dirname $@`
264 $(Q) $(CC) $(CFLAGS) $(CPPFLAGS_NO_ARCH) -MG -M $< > $@
265
266deps/%.dep : gens/%.pb.cc
267 $(E) "[DEP] Generating dependencies for $<"
268 $(Q) mkdir -p `dirname $@`
269 $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS_NO_ARCH) -MG -M $< > $@
270
271deps/%.dep : %.cc
272 $(E) "[DEP] Generating dependencies for $<"
273 $(Q) mkdir -p `dirname $@`
274 $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS_NO_ARCH) -MG -M $< > $@
275
276objs/%.o : %.c
277 $(E) "[C] Compiling $<"
278 $(Q) mkdir -p `dirname $@`
279 $(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
280
281objs/%.o : gens/%.pb.cc
282 $(E) "[CXX] Compiling $<"
283 $(Q) mkdir -p `dirname $@`
284 $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
285
286objs/%.o : %.cc
287 $(E) "[CXX] Compiling $<"
288 $(Q) mkdir -p `dirname $@`
289 $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
290
nnoble0c475f02014-12-05 15:37:39 -0800291dep: dep_c dep_cxx
292
293dep_c:\
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800294% for lib in libs:
nnoble0c475f02014-12-05 15:37:39 -0800295% if not lib.get('c++', False):
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800296 deps_lib${lib.name}\
nnoble0c475f02014-12-05 15:37:39 -0800297% endif
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800298% endfor
299% for tgt in targets:
nnoble0c475f02014-12-05 15:37:39 -0800300% if not tgt.get('c++', False):
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800301 deps_${tgt.name}\
nnoble0c475f02014-12-05 15:37:39 -0800302% endif
303% endfor
304
305
306dep_cxx:\
307% for lib in libs:
308% if lib.get('c++', False):
309 deps_lib${lib.name}\
310% endif
311% endfor
312% for tgt in targets:
313% if tgt.get('c++', False):
314 deps_${tgt.name}\
315% endif
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800316% endfor
317
318
319install: install-headers install-static install-shared
320
321install-headers:
322 $(E) "[INSTALL] Installing public headers"
323 $(Q) $(foreach h, $(PUBLIC_HEADERS), $(INSTALL) $(h) $(prefix)/$(h) && ) exit 0 || exit 1
324
325install-static: static strip-static
326% for lib in libs:
327% if lib.build == "all":
328 $(E) "[INSTALL] Installing lib${lib.name}.a"
329 $(Q) $(INSTALL) libs/lib${lib.name}.a $(prefix)/lib/lib${lib.name}.a
330% endif
331% endfor
332
333install-shared: shared strip-shared
334% for lib in libs:
335% if lib.build == "all":
336 $(E) "[INSTALL] Installing lib${lib.name}.so"
337 $(Q) $(INSTALL) libs/lib${lib.name}.so.$(VERSION) $(prefix)/lib/lib${lib.name}.so.$(VERSION)
338% endif
339% endfor
340
341clean:\
342% for lib in libs:
343 clean_lib${lib.name}\
344% endfor
345% for tgt in targets:
346 clean_${tgt.name}\
347% endfor
348
349 $(Q) $(RM) -r deps objs libs bins gens
350
351
352# The various libraries
353
354% for lib in libs:
355${makelib(lib)}
356% endfor
357
358
359# All of the test targets
360
361% for tgt in targets:
362${maketarget(tgt)}
363% endfor
364
365<%def name="makelib(lib)">
366LIB${lib.name.upper()}_SRC = \\
367
368% for src in lib.src:
369 ${src} \\
370
371% endfor
372
373% if "public_headers" in lib:
374PUBLIC_HEADERS += \\
375
376% for hdr in lib.public_headers:
377 ${hdr} \\
378
379% endfor
380% endif
381
382LIB${lib.name.upper()}_OBJS = $(addprefix objs/, $(addsuffix .o, $(basename $(LIB${lib.name.upper()}_SRC))))
383LIB${lib.name.upper()}_DEPS = $(addprefix deps/, $(addsuffix .dep, $(basename $(LIB${lib.name.upper()}_SRC))))
384
385libs/lib${lib.name}.a: $(LIB${lib.name.upper()}_OBJS)
386 $(E) "[AR] Creating $@"
387 $(Q) $(AR) rcs libs/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS)
388
389% if lib.build == "all":
390libs/lib${lib.name}.so.$(VERSION): $(LIB${lib.name.upper()}_OBJS)
391 $(E) "[LD] Linking $@"
392% if lib.get('c++', False):
393 $(Q) $(LDXX) $(LDFLAGS) -shared -Wl,-soname,lib${lib.name}.so.${settings.version.major} \
394% else:
395 $(Q) $(LD) $(LDFLAGS) -shared -Wl,-soname,lib${lib.name}.so.${settings.version.major} \
396% endif
397-o libs/lib${lib.name}.so.$(VERSION) $(LIB${lib.name.upper()}_OBJS) $(LDLIBS)\
398% if lib.secure:
399 $(LDLIBS_SECURE)
400% endif
401% endif
402
403
404deps_lib${lib.name}: $(LIB${lib.name.upper()}_DEPS)
405
406ifneq ($(MAKECMDGOALS),clean)
407-include $(LIB${lib.name.upper()}_DEPS)
408endif
409
410clean_lib${lib.name}:
411 $(E) "[CLEAN] Cleaning lib${lib.name} files"
412 $(Q) $(RM) $(LIB${lib.name.upper()}_OBJS)
413 $(Q) $(RM) $(LIB${lib.name.upper()}_DEPS)
414 $(Q) $(RM) libs/lib${lib.name}.a
415 $(Q) $(RM) libs/lib${lib.name}.so.$(VERSION)
416</%def>
417
418<%def name="maketarget(tgt)">
419${tgt.name.upper()}_SRC = \\
420
421% for src in tgt.src:
422 ${src} \\
423
424% endfor
425
426${tgt.name.upper()}_OBJS = $(addprefix objs/, $(addsuffix .o, $(basename $(${tgt.name.upper()}_SRC))))
427${tgt.name.upper()}_DEPS = $(addprefix deps/, $(addsuffix .dep, $(basename $(${tgt.name.upper()}_SRC))))
428
429bins/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
430% for dep in tgt.deps:
431 libs/lib${dep}.a\
432% endfor
433
434 $(E) "[LD] Linking $@"
435% if tgt.get("c++", False):
436 $(Q) $(LDXX) $(LDFLAGS) $(${tgt.name.upper()}_OBJS) $(GTEST_LIB) -Llibs\
437% else:
438 $(Q) $(LD) $(LDFLAGS) $(${tgt.name.upper()}_OBJS) -Llibs\
439% endif
440% for dep in tgt.deps:
441 -l${dep}\
442% endfor
443% if tgt.get("c++", False):
444 $(LDLIBSXX)\
445% endif
446 $(LDLIBS)\
447% if tgt.get('secure', True):
448 $(LDLIBS_SECURE)\
449% endif
450 -o bins/${tgt.name}
451
452deps_${tgt.name}: $(${tgt.name.upper()}_DEPS)
453
454ifneq ($(MAKECMDGOALS),clean)
455-include $(${tgt.name.upper()}_DEPS)
456endif
457
458clean_${tgt.name}:
459 $(E) "[CLEAN] Cleaning ${tgt.name} files"
460 $(Q) $(RM) $(${tgt.name.upper()}_OBJS)
461 $(Q) $(RM) $(${tgt.name.upper()}_DEPS)
462 $(Q) $(RM) bins/${tgt.name}
463</%def>
464
465.PHONY: all strip tools buildtests tests make_dirs install clean\
466% for lib in libs:
467 deps_lib${lib.name} clean_lib${lib.name}\
468% endfor
469% for tgt in targets:
470 deps_${tgt.name} clean_${tgt.name}\
471% endfor
472