Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
387 lines
14 KiB
387 lines
14 KiB
# |
|
# This Makefile builds the upb library as well as associated tests, tools, and |
|
# language extensions. |
|
# |
|
# It does not use autoconf/automake/libtool in order to stay lightweight and |
|
# avoid the need for running ./configure. |
|
# |
|
# Summary of compiler flags you may want to use: |
|
# |
|
# * -DNDEBUG: makes binary smaller and faster by removing sanity checks. |
|
# * -O3: optimize for maximum speed |
|
# * -fomit-frame-pointer: makes code smaller and faster by freeing up a reg. |
|
# |
|
# Threading: |
|
# * -DUPB_USE_PTHREADS: configures upb to use pthreads r/w lock. |
|
# * -DUPB_THREAD_UNSAFE: remove all thread-safety. |
|
# * -pthread: required on GCC to enable pthreads (but what does it do?) |
|
# |
|
# Other: |
|
# * -DUPB_UNALIGNED_READS_OK: makes code smaller, but not standard compliant |
|
|
|
.PHONY: all lib clean tests test benchmarks benchmark descriptorgen |
|
.PHONY: clean_leave_profile |
|
|
|
# Default rule: just build libupb. |
|
all: lib |
|
|
|
# User-specified CFLAGS. |
|
USER_CFLAGS=$(strip $(shell test -f perf-cppflags && cat perf-cppflags)) |
|
|
|
# If the user doesn't specify an -O setting, we default to -O3, except |
|
# for upb_def which gets -Os. |
|
ifeq (, $(findstring -O, $(USER_CFLAGS))) |
|
USER_CFLAGS += -O3 |
|
DEF_OPT = -Os |
|
endif |
|
|
|
# Basic compiler/flag setup. |
|
CC=gcc |
|
CXX=g++ |
|
CFLAGS=-std=c99 |
|
INCLUDE=-Isrc -Itests -I. |
|
CPPFLAGS=$(INCLUDE) -Wall -Wextra $(USER_CFLAGS) |
|
LDLIBS=-lpthread src/libupb.a |
|
|
|
# Build with "make Q=" to see all commands that are being executed. |
|
Q=@ |
|
|
|
ifeq ($(Q), @) |
|
E=@echo |
|
else |
|
E=@: |
|
endif |
|
|
|
# Dependency generating. ####################################################### |
|
|
|
-include deps |
|
# Unfortuantely we can't easily generate deps for benchmarks or tests because |
|
# of the scheme we use that compiles the same source file multiple times with |
|
# different -D options, which can include different header files. |
|
deps: gen-deps.sh Makefile $(CORE) $(STREAM) |
|
$(Q) CPPFLAGS="$(CPPFLAGS)" ./gen-deps.sh $(CORE) $(STREAM) |
|
$(E) Regenerating dependencies for src/... |
|
|
|
$(ALLSRC): perf-cppflags |
|
|
|
|
|
# Source files. ############################################################### |
|
|
|
# Every source file used in upb should appear here. |
|
|
|
# The core library. |
|
CORE= \ |
|
src/upb.c \ |
|
src/upb_stream.c \ |
|
src/upb_table.c \ |
|
src/upb_string.c \ |
|
src/upb_def.c \ |
|
src/upb_msg.c \ |
|
|
|
# Common encoders/decoders -- you're almost certain to want these. |
|
STREAM= \ |
|
src/upb_decoder.c \ |
|
src/upb_stdio.c \ |
|
src/upb_textprinter.c \ |
|
src/upb_strstream.c \ |
|
src/upb_glue.c \ |
|
|
|
ASMCORE= \ |
|
src/upb_decoder_x64.asm |
|
|
|
# Parts of core that are yet to be converted. |
|
OTHERSRC=src/upb_encoder.c |
|
|
|
BENCHMARKS_SRC= \ |
|
benchmarks/main.c \ |
|
benchmarks/parsestream.upb_table.c \ |
|
benchmarks/parsetostruct.upb_table.c |
|
|
|
TESTS_SRC= \ |
|
tests/test_decoder.c \ |
|
tests/test_def.c \ |
|
tests/test_string.c \ |
|
tests/tests.c \ |
|
tests/tests_varint.c \ |
|
tests/test_vs_proto2.cc |
|
|
|
#tests/test_stream.c \ |
|
|
|
ALLSRC=$(CORE) $(STREAM) $(BENCHMARKS_SRC) $(TESTS_SRC) |
|
|
|
|
|
# Rules. ####################################################################### |
|
|
|
clean_leave_profile: |
|
rm -rf $(LIBUPB) $(LIBUPB_PIC) |
|
rm -rf $(call rwildcard,,*.o) $(call rwildcard,,*.lo) $(call rwildcard,,*.dSYM) |
|
rm -rf benchmark/google_messages.proto.pb benchmark/google_messages.pb.* benchmarks/b.* benchmarks/*.pb* |
|
rm -rf $(TESTS) tests/t.* |
|
rm -rf src/descriptor.pb |
|
rm -rf src/upbc deps |
|
rm -rf lang_ext/lua/upb.so |
|
cd lang_ext/python && python setup.py clean --all |
|
|
|
clean: clean_leave_profile |
|
rm -rf $(call rwildcard,,*.gcno) $(call rwildcard,,*.gcda) |
|
|
|
# Core library (libupb.a). |
|
SRC=$(CORE) $(STREAM) |
|
LIBUPB=src/libupb.a |
|
LIBUPB_PIC=src/libupb_pic.a |
|
lib: $(LIBUPB) |
|
|
|
|
|
OBJ=$(patsubst %.c,%.o,$(SRC)) |
|
PICOBJ=$(patsubst %.c,%.lo,$(SRC)) |
|
|
|
ifneq (, $(findstring DUSE_X64_FASTPATH, $(USER_CFLAGS))) |
|
OBJ += src/upb_decoder_x64.o |
|
PICOBJ += src/upb_decoder_x64.o |
|
endif |
|
$(LIBUPB): $(OBJ) |
|
$(E) AR $(LIBUPB) |
|
$(Q) ar rcs $(LIBUPB) $(OBJ) |
|
$(LIBUPB_PIC): $(PICOBJ) |
|
$(E) AR $(LIBUPB_PIC) |
|
$(Q) ar rcs $(LIBUPB_PIC) $(PICOBJ) |
|
|
|
%.o : %.c |
|
$(E) CC $< |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< |
|
|
|
%.lo : %.c |
|
$(E) 'CC -fPIC' $< |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -fPIC |
|
|
|
# Override the optimization level for upb_def.o, because it is not in the |
|
# critical path but gets very large when -O3 is used. |
|
src/upb_def.o: src/upb_def.c |
|
$(E) CC $< |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) $(DEF_OPT) -c -o $@ $< |
|
|
|
src/upb_def.lo: src/upb_def.c |
|
$(E) 'CC -fPIC' $< |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) $(DEF_OPT) -c -o $@ $< -fPIC |
|
|
|
src/upb_decoder_x64.o: src/upb_decoder_x64.asm |
|
$(E) NASM $< |
|
$(Q) nasm -Ox src/upb_decoder_x64.asm -o src/upb_decoder_x64.o -f macho64 |
|
|
|
src/upb_decoder_x64.lo: src/upb_decoder_x64.asm |
|
$(E) NASM $< |
|
$(Q) nasm -Ox src/upb_decoder_x64.asm -o src/upb_decoder_x64.lo -f macho64 |
|
|
|
# Function to expand a wildcard pattern recursively. |
|
rwildcard=$(strip $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)$(filter $(subst *,%,$2),$d))) |
|
|
|
|
|
|
|
# Regenerating the auto-generated files in src/. |
|
src/descriptor.pb: src/descriptor.proto |
|
@# TODO: replace with upbc |
|
protoc src/descriptor.proto -osrc/descriptor.pb |
|
|
|
descriptorgen: src/descriptor.pb src/upbc |
|
@# Regenerate descriptor_const.h |
|
./src/upbc -o src/descriptor src/descriptor.pb |
|
|
|
src/upbc: src/upbc.c $(LIBUPB) |
|
|
|
# Language extensions. |
|
python: $(LIBUPB_PIC) |
|
cd lang_ext/python && python setup.py build |
|
|
|
# Tests. ####################################################################### |
|
|
|
tests/test.proto.pb: tests/test.proto |
|
@# TODO: replace with upbc |
|
protoc tests/test.proto -otests/test.proto.pb |
|
|
|
SIMPLE_TESTS= \ |
|
tests/test_string \ |
|
tests/test_def \ |
|
tests/test_varint \ |
|
tests/tests |
|
# tests/test_decoder \ |
|
tests/test_stream \ |
|
|
|
SIMPLE_CXX_TESTS= \ |
|
tests/test_table |
|
|
|
VARIADIC_TESTS= \ |
|
tests/t.test_vs_proto2.googlemessage1 \ |
|
tests/t.test_vs_proto2.googlemessage2 \ |
|
|
|
TESTS=$(SIMPLE_TESTS) $(SIMPLE_CXX_TESTS) $(VARIADIC_TESTS) |
|
|
|
|
|
tests: $(TESTS) |
|
$(TESTS): $(LIBUPB) |
|
tests/tests: tests/test.proto.pb |
|
|
|
$(SIMPLE_TESTS): % : %.c |
|
$(E) CC $< |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $< $(LIBUPB) |
|
|
|
VALGRIND=valgrind --leak-check=full --error-exitcode=1 |
|
test: tests |
|
@echo Running all tests under valgrind. |
|
@set -e # Abort on error. |
|
@for test in $(TESTS); do \ |
|
if [ -x ./$$test ] ; then \ |
|
echo !!! $(VALGRIND) ./$$test; \ |
|
$(VALGRIND) ./$$test || exit 1; \ |
|
fi \ |
|
done; \ |
|
echo "All tests passed!" |
|
|
|
tests/t.test_vs_proto2.googlemessage1 \ |
|
tests/t.test_vs_proto2.googlemessage2: \ |
|
tests/test_vs_proto2.cc $(LIBUPB) benchmarks/google_messages.proto.pb \ |
|
benchmarks/google_messages.pb.cc |
|
$(E) CXX $< '(benchmarks::SpeedMessage1)' |
|
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o tests/t.test_vs_proto2.googlemessage1 $< \ |
|
-DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ |
|
-DMESSAGE_DESCRIPTOR_FILE=\"../benchmarks/google_messages.proto.pb\" \ |
|
-DMESSAGE_FILE=\"../benchmarks/google_message1.dat\" \ |
|
-DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ |
|
-DMESSAGE_HFILE=\"../benchmarks/google_messages.pb.h\" \ |
|
benchmarks/google_messages.pb.cc -lprotobuf -lpthread $(LIBUPB) |
|
$(E) CXX $< '(benchmarks::SpeedMessage2)' |
|
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o tests/t.test_vs_proto2.googlemessage2 $< \ |
|
-DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ |
|
-DMESSAGE_DESCRIPTOR_FILE=\"../benchmarks/google_messages.proto.pb\" \ |
|
-DMESSAGE_FILE=\"../benchmarks/google_message2.dat\" \ |
|
-DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ |
|
-DMESSAGE_HFILE=\"../benchmarks/google_messages.pb.h\" \ |
|
benchmarks/google_messages.pb.cc -lprotobuf -lpthread $(LIBUPB) |
|
tests/test_table: tests/test_table.cc |
|
@# Includes <hash_set> which is a deprecated header. |
|
$(E) CXX $< |
|
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated -o $@ $< $(LIBUPB) |
|
|
|
tests/tests: src/libupb.a |
|
|
|
|
|
# Benchmarks. ################################################################## |
|
|
|
# Benchmarks |
|
UPB_BENCHMARKS=benchmarks/b.parsestream_googlemessage1.upb_table \ |
|
benchmarks/b.parsestream_googlemessage2.upb_table \ |
|
benchmarks/b.parsetostruct_googlemessage1.upb_table_byref \ |
|
benchmarks/b.parsetostruct_googlemessage2.upb_table_byref |
|
|
|
BENCHMARKS=$(UPB_BENCHMARKS) \ |
|
benchmarks/b.parsetostruct_googlemessage1.proto2_table \ |
|
benchmarks/b.parsetostruct_googlemessage2.proto2_table \ |
|
benchmarks/b.parsetostruct_googlemessage1.proto2_compiled \ |
|
benchmarks/b.parsetostruct_googlemessage2.proto2_compiled |
|
upb_benchmarks: $(UPB_BENCHMARKS) |
|
benchmarks: $(BENCHMARKS) |
|
benchmark: |
|
@rm -f benchmarks/results |
|
@rm -rf benchmarks/*.dSYM |
|
@for test in benchmarks/b.* ; do ./$$test ; done |
|
|
|
benchmarks/google_messages.proto.pb: benchmarks/google_messages.proto |
|
@# TODO: replace with upbc. |
|
protoc benchmarks/google_messages.proto -obenchmarks/google_messages.proto.pb |
|
|
|
benchmarks/google_messages.pb.cc: benchmarks/google_messages.proto |
|
protoc benchmarks/google_messages.proto --cpp_out=. |
|
|
|
benchmarks/b.parsetostruct_googlemessage1.upb_table_byval \ |
|
benchmarks/b.parsetostruct_googlemessage1.upb_table_byref \ |
|
benchmarks/b.parsetostruct_googlemessage2.upb_table_byval \ |
|
benchmarks/b.parsetostruct_googlemessage2.upb_table_byref: \ |
|
benchmarks/parsetostruct.upb_table.c $(LIBUPB) benchmarks/google_messages.proto.pb |
|
$(E) 'CC benchmarks/parsetostruct.upb_table.c (benchmarks.SpeedMessage1, byval)' |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage1.upb_table_byval $< \ |
|
-DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ |
|
-DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ |
|
-DMESSAGE_FILE=\"google_message1.dat\" \ |
|
-DBYREF=false $(LIBUPB) |
|
$(E) 'CC benchmarks/parsetostruct.upb_table.c (benchmarks.SpeedMessage1, byref)' |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage1.upb_table_byref $< \ |
|
-DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ |
|
-DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ |
|
-DMESSAGE_FILE=\"google_message1.dat\" \ |
|
-DBYREF=true $(LIBUPB) |
|
$(E) 'CC benchmarks/parsetostruct.upb_table.c (benchmarks.SpeedMessage2, byval)' |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage2.upb_table_byval $< \ |
|
-DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ |
|
-DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ |
|
-DMESSAGE_FILE=\"google_message2.dat\" \ |
|
-DBYREF=false $(LIBUPB) |
|
$(E) 'CC benchmarks/parsetostruct.upb_table.c (benchmarks.SpeedMessage2, byref)' |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage2.upb_table_byref $< \ |
|
-DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ |
|
-DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ |
|
-DMESSAGE_FILE=\"google_message2.dat\" \ |
|
-DBYREF=true $(LIBUPB) |
|
|
|
benchmarks/b.parsestream_googlemessage1.upb_table \ |
|
benchmarks/b.parsestream_googlemessage2.upb_table: \ |
|
benchmarks/parsestream.upb_table.c $(LIBUPB) benchmarks/google_messages.proto.pb |
|
$(E) 'CC benchmarks/parsestream.upb_table.c (benchmarks.SpeedMessage1)' |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsestream_googlemessage1.upb_table $< \ |
|
-DMESSAGE_NAME=\"benchmarks.SpeedMessage1\" \ |
|
-DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ |
|
-DMESSAGE_FILE=\"google_message1.dat\" \ |
|
$(LIBUPB) |
|
$(E) 'CC benchmarks/parsestream.upb_table.c (benchmarks.SpeedMessage2)' |
|
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -o benchmarks/b.parsestream_googlemessage2.upb_table $< \ |
|
-DMESSAGE_NAME=\"benchmarks.SpeedMessage2\" \ |
|
-DMESSAGE_DESCRIPTOR_FILE=\"google_messages.proto.pb\" \ |
|
-DMESSAGE_FILE=\"google_message2.dat\" \ |
|
$(LIBUPB) |
|
|
|
benchmarks/b.parsetostruct_googlemessage1.proto2_table \ |
|
benchmarks/b.parsetostruct_googlemessage2.proto2_table: \ |
|
benchmarks/parsetostruct.proto2_table.cc benchmarks/google_messages.pb.cc |
|
$(E) 'CXX benchmarks/parsetostruct.proto2_table.cc (benchmarks.SpeedMessage1)' |
|
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage1.proto2_table $< \ |
|
-DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ |
|
-DMESSAGE_FILE=\"google_message1.dat\" \ |
|
-DMESSAGE_HFILE=\"google_messages.pb.h\" \ |
|
benchmarks/google_messages.pb.cc -lprotobuf -lpthread |
|
$(E) 'CXX benchmarks/parsetostruct.proto2_table.cc (benchmarks.SpeedMessage2)' |
|
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage2.proto2_table $< \ |
|
-DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ |
|
-DMESSAGE_FILE=\"google_message2.dat\" \ |
|
-DMESSAGE_HFILE=\"google_messages.pb.h\" \ |
|
benchmarks/google_messages.pb.cc -lprotobuf -lpthread |
|
|
|
benchmarks/b.parsetostruct_googlemessage1.proto2_compiled \ |
|
benchmarks/b.parsetostruct_googlemessage2.proto2_compiled: \ |
|
benchmarks/parsetostruct.proto2_compiled.cc \ |
|
benchmarks/parsetostruct.proto2_table.cc benchmarks/google_messages.pb.cc |
|
$(E) 'CXX benchmarks/parsetostruct.proto2_compiled.cc (benchmarks.SpeedMessage1)' |
|
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage1.proto2_compiled $< \ |
|
-DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ |
|
-DMESSAGE_FILE=\"google_message1.dat\" \ |
|
-DMESSAGE_HFILE=\"google_messages.pb.h\" \ |
|
benchmarks/google_messages.pb.cc -lprotobuf -lpthread |
|
$(E) 'CXX benchmarks/parsetostruct.proto2_compiled.cc (benchmarks.SpeedMessage2)' |
|
$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetostruct_googlemessage2.proto2_compiled $< \ |
|
-DMESSAGE_CIDENT="benchmarks::SpeedMessage2" \ |
|
-DMESSAGE_FILE=\"google_message2.dat\" \ |
|
-DMESSAGE_HFILE=\"google_messages.pb.h\" \ |
|
benchmarks/google_messages.pb.cc -lprotobuf -lpthread |
|
|
|
|
|
# Lua extension ################################################################## |
|
|
|
LUA_CPPFLAGS = $(strip $(shell pkg-config --silence-errors --cflags lua || pkg-config --silence-errors --cflags lua5.1 || echo '-I/usr/local/include')) |
|
ifeq ($(shell uname), Darwin) |
|
LUA_LDFLAGS = -undefined dynamic_lookup |
|
else |
|
LUA_LDFLAGS = |
|
endif |
|
|
|
LUAEXT=lang_ext/lua/upb.so |
|
lua: $(LUAEXT) |
|
lang_ext/lua/upb.so: lang_ext/lua/upb.c $(LIBUPB_PIC) |
|
@echo CC lang_ext/lua/upb.c |
|
@$(CC) $(CFLAGS) $(CPPFLAGS) $(LUA_CPPFLAGS) -fpic -shared -o $@ $< src/libupb_pic.a $(LUA_LDFLAGS)
|
|
|