Newer
Older
# GRPC global makefile
# This currently builds C and C++ code.
<%!
from copy import deepcopy
import re
proto_re = re.compile('(.*)\.proto')
def excluded(filename, exclude_res):
for r in exclude_res:
if r.match(filename):
return True
return False
def proto_to_cc(filename):
m = proto_re.match(filename)
if not m:
return filename
return 'gens/' + m.group(1) + '.pb.cc'
%>
<%
altlibs = []
for lib in libs:
for alt in lib.get('alternates', []):
new = deepcopy(lib)
new.name = alt.name
new.alternates = []
exclude_res = [re.compile(str) for str in alt.get('exclude_res', [])]
src = [file for file in new.get('src', []) if not excluded(file, exclude_res)]
src.extend(alt.get('include_src', []))
new.src = src
headers = [file for file in new.get('headers', []) if not excluded(file, exclude_res)]
headers.extend(alt.get('include_headers', []))
new.headers = headers
public_headers = [file for file in new.get('public_headers', []) if not excluded(file, exclude_res)]
public_headers.extend(alt.get('include_public_headers', []))
new.public_headers = public_headers
for prop in alt.properties:
new[prop.name] = prop.value
altlibs.append(new)
libs.extend(altlibs)
m = proto_re.match(src)
if m:
protos.add(m.group(1))
m = proto_re.match(src)
if m:
protos.add(m.group(1))
%>
# General settings.
# You may want to change these depending on your system.
prefix ?= /usr/local
PROTOC = protoc
CC = gcc
CXX = g++
LD = gcc
LDXX = g++
AR = ar
STRIP = strip --strip-unneeded
INSTALL = install -D
RM = rm -f
HOST_CC = $(CC)
HOST_CXX = $(CXX)
HOST_LD = $(LD)
HOST_LDXX = $(LDXX)
ifeq ($(DEBUG),)
CPPFLAGS += -O2
DEFINES += NDEBUG
else
CPPFLAGS += -O0
DEFINES += _DEBUG DEBUG
endif
CFLAGS += -std=c89 -pedantic
CXXFLAGS += -std=c++11
CPPFLAGS += -g -fPIC -Wall -Werror -Wno-long-long
LDFLAGS += -g -pthread -fPIC
INCLUDES = . include gens
LIBS = rt m z event event_pthreads pthread
LIBSXX = protobuf
LIBS_SECURE = ssl crypto dl
LIBS_PROTOC = protoc protobuf
ifneq ($(wildcard /usr/src/gtest/src/gtest-all.cc),)
GTEST_LIB = /usr/src/gtest/src/gtest-all.cc -I/usr/src/gtest
else
GTEST_LIB = -lgtest
endif
ifeq ($(V),1)
E = @:
Q =
else
E = @echo
Q = @
endif
VERSION = ${settings.version.major}.${settings.version.minor}.${settings.version.micro}.${settings.version.build}
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
LDFLAGS += $(ARCH_FLAGS)
LDLIBS += $(addprefix -l, $(LIBS))
LDLIBSXX += $(addprefix -l, $(LIBSXX))
LDLIBS_SECURE += $(addprefix -l, $(LIBS_SECURE))
HOST_LDLIBS_PROTOC += $(addprefix -l, $(LIBS_PROTOC))
HOST_CPPFLAGS = $(CPPFLAGS)
HOST_CFLAGS = $(CFLAGS)
HOST_CXXFLAGS = $(CXXFLAGS)
HOST_LDFLAGS = $(LDFLAGS)
HOST_LDLIBS = $(LDLIBS)
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
# These are automatically computed variables.
# There shouldn't be any need to change anything from now on.
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
ifeq ($(SYSTEM),)
SYSTEM = $(HOST_SYSTEM)
endif
ifeq ($(wildcard .git),)
IS_GIT_FOLDER = false
else
IS_GIT_FOLDER = true
endif
EVENT2_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/event2.c -levent $(LDFLAGS)
OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/openssl-alpn.c -levent $(LDFLAGS) $(LDLIBS_SECURE)
ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/event2.c -levent $(LDFLAGS)
HAS_SYSTEM_EVENT2 = $(shell $(EVENT2_CHECK_CMD) >& /dev/null && echo true || echo false)
HAS_SYSTEM_OPENSSL_ALPN = $(shell $(OPENSSL_ALPN_CHECK_CMD) >& /dev/null && echo true || echo false)
HAS_SYSTEM_ZLIB = $(shell $(ZLIB_CHECK_CMD) >& /dev/null && echo true || echo false)
ifeq ($(wildcard third_party/libevent/include/event2/event.h),)
HAS_EMBEDDED_EVENT2 = false
else
HAS_EMBEDDED_EVENT2 = true
endif
ifeq ($(wildcard third_party/openssl/ssl/ssl.h),)
HAS_EMBEDDED_OPENSSL_ALPN = false
else
HAS_EMBEDDED_OPENSSL_ALPN = true
endif
ifeq ($(wildcard third_party/zlib/zlib.h),)
HAS_EMBEDDED_ZLIB = false
else
HAS_EMBEDDED_ZLIB = true
endif
ifneq ($(SYSTEM),MINGW32)
ifeq ($(HAS_SYSTEM_EVENT2),false)
DEP_MISSING += libevent
endif
endif
ifeq ($(HAS_SYSTEM_ZLIB),false)
ifeq ($(HAS_EMBEDDED_ZLIB),true)
ZLIB_DEP = third_party/zlib/libz.a
CPPFLAGS += -Ithird_party/zlib
LDFLAGS += -Lthird_party/zlib
else
DEP_MISSING += zlib
endif
endif
ifeq ($(HAS_SYSTEM_OPENSSL_ALPN),false)
ifeq ($(HAS_EMBEDDED_OPENSSL_ALPN),true)
OPENSSL_DEP = third_party/openssl/libssl.a
CPPFLAGS += -Ithird_party/openssl/include
LDFLAGS += -Lthird_party/openssl
else
NO_SECURE = true
endif
endif
ifneq ($(DEP_MISSING),)
NO_DEPS = true
endif
ifneq ($(MAKECMDGOALS),clean)
NO_DEPS = true
endif
all: static shared\
% for tgt in targets:
% if tgt.build == 'all':
bins/${tgt.name}\
% endif
% endfor
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
dep_error:
@echo "You shouldn't see this message - all of your dependencies are correct."
else
all: dep_error git_update stop
dep_error:
@echo
@echo "DEPENDENCY ERROR"
@echo
@echo "You are missing system dependencies that are essential to build grpc,"
@echo "and the third_party directory doesn't have them:"
@echo
@echo " $(DEP_MISSING)"
@echo
@echo "Installing the development packages for your system will solve"
@echo "this issue. Please consult INSTALL to get more information."
@echo
@echo "If you need information about why these tests failed, run:"
@echo
@echo " make run_dep_checks"
@echo
endif
git_update:
ifeq ($(IS_GIT_FOLDER),true)
@echo "Additionally, since you are in a git clone, you can download the"
@echo "missing dependencies in third_party by running the following command:"
@echo
@echo " git submodule --init update"
@echo
endif
openssl_dep_error: openssl_dep_message git_update stop
openssl_dep_message:
@echo
@echo "DEPENDENCY ERROR"
@echo
@echo "The target you are trying to run requires OpenSSL with ALPN support."
@echo "Your system doesn't have it, and neither does the third_party directory."
@echo
@echo "Please consult INSTALL to get more information."
@echo
@echo "If you need information about why these tests failed, run:"
@echo
@echo " make run_dep_checks"
@echo
stop:
@false
run_dep_checks:
$(EVENT2_CHECK_CMD) || true
$(OPENSSL_ALPN_CHECK_CMD) || true
$(ZLIB_CHECK_CMD) || true
third_party/zlib/libz.a:
(cd third_party/zlib ; CFLAGS="-fPIC -fvisibility=hidden" ./configure --static)
$(MAKE) -C third_party/zlib
third_party/openssl/libssl.a:
(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden" ./config)
$(MAKE) -C third_party/openssl build_crypto build_ssl
static: static_c static_cxx
% if lib.build == 'all' and not lib.get('c++', False):
% if lib.build == 'all' and lib.get('c++', False):
libs/lib${lib.name}.a\
% endif
% endfor
shared: shared_c shared_cxx
% for lib in libs:
% if lib.build == 'all' and not lib.get('c++', False):
libs/lib${lib.name}.so.$(VERSION)\
% endif
% endfor
% for lib in libs:
% if lib.build == 'all' and lib.get('c++', False):
libs/lib${lib.name}.so.$(VERSION)\
% endif
% endfor
privatelibs: privatelibs_c privatelibs_cxx
% for lib in libs:
% if lib.build == 'private':
libs/lib${lib.name}.a\
% endif
% endfor
% for lib in libs:
% if lib.build == 'private':
libs/lib${lib.name}.a\
% endif
% endfor
buildtests: buildtests_c buildtests_cxx
buildtests_c: bin_dep_c privatelibs_c\
% if tgt.build == 'test' and not tgt.get('c++', False):
buildtests_cxx: bin_dep_cxx privatelibs_cxx\
% if tgt.build == 'test' and tgt.get('c++', False):
% for tgt in targets:
% if tgt.build == 'test' and tgt.get('run', True) and not tgt.get('c++', False):
$(E) "[RUN] Testing ${tgt.name}"
$(Q) ./bins/${tgt.name} || ( echo test ${tgt.name} failed ; exit 1 )
% endif
% endfor
% if tgt.build == 'test' and tgt.get('run', True) and tgt.get('c++', False):
$(E) "[RUN] Testing ${tgt.name}"
$(Q) ./bins/${tgt.name} || ( echo test ${tgt.name} failed ; exit 1 )
% endif
% endfor
tools: privatelibs\
% for tgt in targets:
% if tgt.build == 'tool':
bins/${tgt.name}\
% endif
% endfor
protoc_plugins:\
% for tgt in targets:
% if tgt.build == 'protoc':
bins/${tgt.name}\
% endif
% endfor
buildbenchmarks: privatelibs\
% for tgt in targets:
% if tgt.build == 'benchmark':
bins/${tgt.name}\
% endif
% endfor
benchmarks: buildbenchmarks
strip: strip-static strip-shared
strip-static_c: static_c
% for lib in libs:
% if not lib.get("c++", False):
% if lib.build == "all":
$(E) "[STRIP] Stripping lib${lib.name}.a"
$(Q) $(STRIP) libs/lib${lib.name}.a
% endif
% endif
% endfor
strip-static_cxx: static_cxx
% if lib.build == "all":
$(E) "[STRIP] Stripping lib${lib.name}.a"
$(Q) $(STRIP) libs/lib${lib.name}.a
% endif
% endif
% endfor
strip-shared_c: shared_c
% for lib in libs:
% if not lib.get("c++", False):
% if lib.build == "all":
$(E) "[STRIP] Stripping lib${lib.name}.so"
$(Q) $(STRIP) libs/lib${lib.name}.so.$(VERSION)
% endif
% endif
% if lib.build == "all":
$(E) "[STRIP] Stripping lib${lib.name}.so"
$(Q) $(STRIP) libs/lib${lib.name}.so.$(VERSION)
% endif
% for p in protos:
deps/gens/${p}.pb.dep:
$(Q) mkdir -p `dirname $@`
$(Q) touch $@
gens/${p}.pb.cc: ${p}.proto protoc_plugins
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --cpp_out=gens --grpc_out=gens --plugin=protoc-gen-grpc=bins/cpp_plugin $<
% endfor
deps/%.dep : %.c
$(E) "[DEP] Generating dependencies for $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS_NO_ARCH) -MG -M $< > $@
deps/%.dep : %.cc
$(E) "[DEP] Generating dependencies for $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS_NO_ARCH) -MG -M $< > $@
objs/%.o : %.c
$(E) "[C] Compiling $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
objs/%.o : gens/%.pb.cc
$(E) "[CXX] Compiling $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
objs/src/compiler/%.o : src/compiler/%.cc
$(E) "[HOSTCXX] Compiling $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_CPPFLAGS) -c -o $@ $<
objs/%.o : %.cc
$(E) "[CXX] Compiling $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
dep: dep_c dep_cxx
dep_c:\
% if not lib.get('c++', False):
% endif
% if not tgt.get('c++', False):
% endif
% endfor
dep_cxx:\
% for lib in libs:
% if lib.get('c++', False):
deps_lib${lib.name}\
% endif
% endfor
% for tgt in targets:
% if tgt.get('c++', False):
deps_${tgt.name}\
% endif
install: install_c install_cxx
install_c: install-headers_c install-static_c install-shared_c
install_cxx: install-headers_cxx install-static_cxx install-shared_cxx
install-headers: install-headers_c install-headers_cxx
install-headers_c:
$(E) "[INSTALL] Installing public C headers"
$(Q) $(foreach h, $(PUBLIC_HEADERS_C), $(INSTALL) $(h) $(prefix)/$(h) && ) exit 0 || exit 1
install-headers_cxx:
$(E) "[INSTALL] Installing public C++ headers"
$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) $(h) $(prefix)/$(h) && ) exit 0 || exit 1
install-static: install-static_c install-static_cxx
install-static_c: static_c strip-static_c
% if lib.build == "all":
$(E) "[INSTALL] Installing lib${lib.name}.a"
$(Q) $(INSTALL) libs/lib${lib.name}.a $(prefix)/lib/lib${lib.name}.a
% endif
% endif
% endfor
install-static_cxx: static_cxx strip-static_cxx
% for lib in libs:
% if lib.get("c++", False):
% if lib.build == "all":
$(E) "[INSTALL] Installing lib${lib.name}.a"
$(Q) $(INSTALL) libs/lib${lib.name}.a $(prefix)/lib/lib${lib.name}.a
% endif
% endif
% endfor
install-shared_c: shared_c strip-shared_c
% for lib in libs:
% if not lib.get("c++", False):
% if lib.build == "all":
$(E) "[INSTALL] Installing lib${lib.name}.so"
$(Q) $(INSTALL) libs/lib${lib.name}.so.$(VERSION) $(prefix)/lib/lib${lib.name}.so.$(VERSION)
% endif
% endif
install-shared_cxx: shared_cxx strip-shared_cxx
% if lib.build == "all":
$(E) "[INSTALL] Installing lib${lib.name}.so"
$(Q) $(INSTALL) libs/lib${lib.name}.so.$(VERSION) $(prefix)/lib/lib${lib.name}.so.$(VERSION)
% endif
% endfor
clean:\
% for lib in libs:
clean_lib${lib.name}\
% endfor
% for tgt in targets:
clean_${tgt.name}\
% endfor
$(Q) $(RM) -r deps objs libs bins gens
# The various libraries
% for lib in libs:
${makelib(lib)}
% endfor
# All of the test targets, and protoc plugins
% for tgt in targets:
${maketarget(tgt)}
% endfor
<%def name="makelib(lib)">
LIB${lib.name.upper()}_SRC = \\
% for src in lib.src:
% if lib.get("c++", False):
PUBLIC_HEADERS_CXX += \\
% else:
PUBLIC_HEADERS_C += \\
% endif
% for hdr in lib.public_headers:
${hdr} \\
% endfor
% endif
LIB${lib.name.upper()}_OBJS = $(addprefix objs/, $(addsuffix .o, $(basename $(LIB${lib.name.upper()}_SRC))))
LIB${lib.name.upper()}_DEPS = $(addprefix deps/, $(addsuffix .dep, $(basename $(LIB${lib.name.upper()}_SRC))))
% if lib.get('secure', True):
LIB${lib.name.upper()}_OBJS += $(OPENSSL_DEP)
ifeq ($(NO_SECURE),true)
libs/lib${lib.name}.a: openssl_dep_error
else
% endif
libs/lib${lib.name}.a: $(LIB${lib.name.upper()}_OBJS)
$(E) "[AR] Creating $@"
$(Q) $(AR) rcs libs/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS)
% if lib.build == "all":
libs/lib${lib.name}.so.$(VERSION): $(LIB${lib.name.upper()}_OBJS)
$(E) "[LD] Linking $@"
% if lib.get('c++', False):
$(Q) $(LDXX) $(LDFLAGS) -shared -Wl,-soname,lib${lib.name}.so.${settings.version.major} \
% else:
$(Q) $(LD) $(LDFLAGS) -shared -Wl,-soname,lib${lib.name}.so.${settings.version.major} \
% endif
-o libs/lib${lib.name}.so.$(VERSION) $(LIB${lib.name.upper()}_OBJS) $(LDLIBS)\
% if lib.get('secure', True):
$(LDLIBS_SECURE)\
% if lib.get('secure', True):
endif
% endif
deps_lib${lib.name}: $(LIB${lib.name.upper()}_DEPS)
% if lib.get('secure', True):
ifneq ($(NO_SECURE),true)
% endif
ifneq ($(NO_DEPS),true)
% if lib.get('secure', True):
endif
% endif
clean_lib${lib.name}:
$(E) "[CLEAN] Cleaning lib${lib.name} files"
$(Q) $(RM) $(LIB${lib.name.upper()}_OBJS)
$(Q) $(RM) $(LIB${lib.name.upper()}_DEPS)
$(Q) $(RM) libs/lib${lib.name}.a
$(Q) $(RM) libs/lib${lib.name}.so.$(VERSION)
</%def>
<%def name="maketarget(tgt)">
${tgt.name.upper()}_SRC = \\
% for src in tgt.src:
% endfor
${tgt.name.upper()}_OBJS = $(addprefix objs/, $(addsuffix .o, $(basename $(${tgt.name.upper()}_SRC))))
${tgt.name.upper()}_DEPS = $(addprefix deps/, $(addsuffix .dep, $(basename $(${tgt.name.upper()}_SRC))))
% if tgt.get('secure', True):
ifeq ($(NO_SECURE),true)
bins/${tgt.name}: openssl_dep_error
else
% endif
bins/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
% for dep in tgt.deps:
libs/lib${dep}.a\
% endfor
% if tgt.get("c++", False):
% if tgt.build == 'protoc':
$(E) "[HOSTLD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(${tgt.name.upper()}_OBJS)\
% else:
$(Q) $(LDXX) $(LDFLAGS) $(${tgt.name.upper()}_OBJS)\
% if tgt.build == 'test':
$(GTEST_LIB)\
% endif
-Llibs\
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(${tgt.name.upper()}_OBJS) -Llibs\
% endif
% for dep in tgt.deps:
-l${dep}\
% endfor
% if tgt.get("c++", False):
% if tgt.build == 'protoc':
$(HOST_LDLIBSXX)\
% else:
% endif
% if tgt.build == 'protoc':
$(HOST_LDLIBS)\
% else:
% endif
% if tgt.build == 'protoc':
$(HOST_LDLIBS_PROTOC)\
% elif tgt.get('secure', True):
$(LDLIBS_SECURE)\
% if tgt.get('secure', True):
endif
% endif
% if tgt.get('secure', True):
ifneq ($(NO_SECURE),true)
% endif
ifneq ($(NO_DEPS),true)
% if tgt.get('secure', True):
endif
% endif
clean_${tgt.name}:
$(E) "[CLEAN] Cleaning ${tgt.name} files"
$(Q) $(RM) $(${tgt.name.upper()}_OBJS)
$(Q) $(RM) $(${tgt.name.upper()}_DEPS)
$(Q) $(RM) bins/${tgt.name}
</%def>
dep_error openssl_dep_error openssl_dep_message git_update stop \
buildtests buildtests_c buildtests_cxx \
test test_c test_cxx \
install install_c install_cxx \
install-headers install-headers_c install-headers_cxx \
install-shared install-shared_c install-shared_cxx \
install-static install-static_c install-static_cxx \
strip strip-shared strip-static \
strip_c strip-shared_c strip-static_c \
strip_cxx strip-shared_cxx strip-static_cxx \
clean\
% for lib in libs:
deps_lib${lib.name} clean_lib${lib.name}\
% endfor
% for tgt in targets:
deps_${tgt.name} clean_${tgt.name}\
% endfor