| # GRPC global makefile |
| # This currently builds C and C++ code. |
| <%! |
| from copy import deepcopy |
| import re |
| |
| def excluded(filename, exclude_res): |
| for r in exclude_res: |
| if r.match(filename): |
| return True |
| return False |
| %> |
| |
| <% |
| 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) |
| |
| protos_dict = {} |
| proto_re = re.compile('\.proto$') |
| for lib in libs: |
| for src in lib.src: |
| if proto_re.match(src): |
| protos_dict[src] = True |
| for tgt in targets: |
| for src in tgt.src: |
| if proto_re.match(src): |
| protos_dict[src] = True |
| |
| protos = [] |
| for k, v in protos_dict: |
| protos.append(k) |
| %> |
| |
| # 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 |
| |
| 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 |
| |
| 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 |
| GTEST_LIB += -lgflags |
| 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)) |
| |
| .SECONDARY = %.pb.h %.pb.cc |
| |
| all: static shared\ |
| % for tgt in targets: |
| % if tgt.build == 'all': |
| bins/${tgt.name}\ |
| % endif |
| % endfor |
| |
| static: static_c static_cxx |
| |
| static_c: dep_c\ |
| % for lib in libs: |
| % if lib.build == 'all' and not lib.get('c++', False): |
| libs/lib${lib.name}.a\ |
| % endif |
| % endfor |
| |
| |
| static_cxx: dep_cxx\ |
| % for lib in libs: |
| % if lib.build == 'all' and lib.get('c++', False): |
| libs/lib${lib.name}.a\ |
| % endif |
| % endfor |
| |
| |
| shared: shared_c shared_cxx |
| |
| shared_c: dep_c\ |
| % for lib in libs: |
| % if lib.build == 'all' and not lib.get('c++', False): |
| libs/lib${lib.name}.so.$(VERSION)\ |
| % endif |
| % endfor |
| |
| |
| shared_cxx: dep_cxx\ |
| % 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 |
| |
| privatelibs_c: dep_c\ |
| % for lib in libs: |
| % if lib.build == 'private': |
| libs/lib${lib.name}.a\ |
| % endif |
| % endfor |
| |
| |
| privatelibs_cxx: dep_cxx\ |
| % for lib in libs: |
| % if lib.build == 'private': |
| libs/lib${lib.name}.a\ |
| % endif |
| % endfor |
| |
| |
| buildtests: buildtests_c buildtests_cxx |
| |
| buildtests_c: privatelibs_c\ |
| % for tgt in targets: |
| % if tgt.build == 'test' and not tgt.get('c++', False): |
| bins/${tgt.name}\ |
| % endif |
| % endfor |
| |
| |
| buildtests_cxx: privatelibs_cxx\ |
| % for tgt in targets: |
| % if tgt.build == 'test' and tgt.get('c++', False): |
| bins/${tgt.name}\ |
| % endif |
| % endfor |
| |
| |
| test: test_c test_cxx |
| |
| test_c: buildtests_c |
| % 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 |
| |
| |
| test_cxx: buildtests_cxx |
| % for tgt in targets: |
| % 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 |
| % for lib in libs: |
| % if 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-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 |
| % endfor |
| |
| strip-shared_cxx: shared_cxx |
| % for lib in libs: |
| % if 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 |
| % endfor |
| |
| gens/%.pb.cc : %.proto |
| $(E) "[PROTOC] Generating protobuf CC file from $<" |
| $(Q) mkdir -p `dirname $@` |
| $(Q) $(PROTOC) --cpp_out=gens $< |
| |
| deps/%.dep : %.c |
| $(E) "[DEP] Generating dependencies for $<" |
| $(Q) mkdir -p `dirname $@` |
| $(Q) $(CC) $(CFLAGS) $(CPPFLAGS_NO_ARCH) -MG -M $< > $@ |
| |
| deps/%.dep : gens/%.pb.cc |
| $(E) "[DEP] Generating dependencies for $<" |
| $(Q) mkdir -p `dirname $@` |
| $(Q) $(CXX) $(CXXFLAGS) $(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/%.o : %.cc |
| $(E) "[CXX] Compiling $<" |
| $(Q) mkdir -p `dirname $@` |
| $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< |
| |
| dep: dep_c dep_cxx |
| |
| dep_c:\ |
| % for lib in libs: |
| % if not lib.get('c++', False): |
| deps_lib${lib.name}\ |
| % endif |
| % endfor |
| % for tgt in targets: |
| % if not tgt.get('c++', False): |
| deps_${tgt.name}\ |
| % 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 |
| % endfor |
| |
| |
| 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 |
| % for lib in libs: |
| % if not 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-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 |
| % endfor |
| |
| install-shared_cxx: shared_cxx strip-shared_cxx |
| % for lib in libs: |
| % if 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 |
| % 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 |
| |
| % for tgt in targets: |
| ${maketarget(tgt)} |
| % endfor |
| |
| <%def name="makelib(lib)"> |
| LIB${lib.name.upper()}_SRC = \\ |
| |
| % for src in lib.src: |
| ${src} \\ |
| |
| % endfor |
| |
| % if "public_headers" in lib: |
| % 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)))) |
| |
| libs/lib${lib.name}.a: $(LIB${lib.name.upper()}_OBJS) |
| $(E) "[AR] Creating $@" |
| $(Q) mkdir -p `dirname $@` |
| $(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 $@" |
| $(Q) mkdir -p `dirname $@` |
| % 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.secure: |
| $(LDLIBS_SECURE) |
| % endif |
| % endif |
| |
| |
| deps_lib${lib.name}: $(LIB${lib.name.upper()}_DEPS) |
| |
| ifneq ($(MAKECMDGOALS),clean) |
| -include $(LIB${lib.name.upper()}_DEPS) |
| 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: |
| ${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)))) |
| |
| bins/${tgt.name}: $(${tgt.name.upper()}_OBJS)\ |
| % for dep in tgt.deps: |
| libs/lib${dep}.a\ |
| % endfor |
| |
| $(E) "[LD] Linking $@" |
| $(Q) mkdir -p `dirname $@` |
| % if tgt.get("c++", False): |
| $(Q) $(LDXX) $(LDFLAGS) $(${tgt.name.upper()}_OBJS) $(GTEST_LIB) -Llibs\ |
| % else: |
| $(Q) $(LD) $(LDFLAGS) $(${tgt.name.upper()}_OBJS) -Llibs\ |
| % endif |
| % for dep in tgt.deps: |
| -l${dep}\ |
| % endfor |
| % if tgt.get("c++", False): |
| $(LDLIBSXX)\ |
| % endif |
| $(LDLIBS)\ |
| % if tgt.get('secure', True): |
| $(LDLIBS_SECURE)\ |
| % endif |
| -o bins/${tgt.name} |
| |
| deps_${tgt.name}: $(${tgt.name.upper()}_DEPS) |
| |
| ifneq ($(MAKECMDGOALS),clean) |
| -include $(${tgt.name.upper()}_DEPS) |
| 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> |
| |
| .PHONY: all strip tools \ |
| 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 |
| |