diff --git a/lib/import/import-grpc.mk b/lib/import/import-grpc.mk
new file mode 100644
index 0000000..737f0b5
--- /dev/null
+++ b/lib/import/import-grpc.mk
@@ -0,0 +1,3 @@
+GRPC_PORT_DIR := $(call select_from_ports,protobuf_grpc)
+
+INC_DIR += $(GRPC_PORT_DIR)/include
diff --git a/lib/import/import-protobuf.mk b/lib/import/import-protobuf.mk
new file mode 100644
index 0000000..099b02e
--- /dev/null
+++ b/lib/import/import-protobuf.mk
@@ -0,0 +1,5 @@
+PROTOBUF_PORT_DIR := $(call select_from_ports,protobuf_grpc)
+
+INC_DIR += $(PROTOBUF_PORT_DIR)/include
+
+PROTO_FILES_DIR := $(PROTOBUF_PORT_DIR)/proto/protobuf/src
diff --git a/lib/mk/grpc.mk b/lib/mk/grpc.mk
new file mode 100644
index 0000000..a125796
--- /dev/null
+++ b/lib/mk/grpc.mk
@@ -0,0 +1,571 @@
+include $(REP_DIR)/lib/import/import-grpc.mk
+include $(REP_DIR)/lib/import/import-protobuf.mk
+
+GRPC_DIR := $(GRPC_PORT_DIR)/src/lib/grpc
+GRPC_SRC_DIR := $(GRPC_DIR)/src/cpp
+GRPC_CORE_SRC_DIR := $(GRPC_DIR)/src/core
+GRPC_PROTO_DIR := $(GRPC_DIR)/src/proto/grpc
+
+LIBS += base
+LIBS += libc
+LIBS += libssl
+LIBS += protobuf
+LIBS += stdcxx
+LIBS += zlib
+
+SHARED_LIB := yes
+
+CC_CXX_WARN_STRICT :=
+CC_OPT += -DGPR_CUSTOM_SYNC -DHAVE_CONFIG_H
+
+INC_DIR += $(GRPC_DIR)
+INC_DIR += $(GRPC_DIR)/src/core/ext/upb-generated
+INC_DIR += $(GRPC_DIR)/third_party/upb
+INC_DIR += $(GRPC_DIR)/third_party/abseil-cpp
+INC_DIR += $(GRPC_DIR)/third_party/address_sorting/include
+INC_DIR += $(GRPC_DIR)/third_party/cares/cares
+INC_DIR += $(GRPC_DIR)/third_party/cares/config_freebsd
+
+GENODE_TOOL_DIR := /usr/local/genode/protobuf_grpc/current/bin
+PROTOC := $(GENODE_TOOL_DIR)/protoc
+GRPC_PLUGIN := $(GENODE_TOOL_DIR)/grpc_cpp_plugin
+
+SRC_CC := client/channel_cc.cc
+SRC_CC += client/client_context.cc
+SRC_CC += client/client_interceptor.cc
+SRC_CC += client/create_channel.cc
+SRC_CC += client/create_channel_internal.cc
+SRC_CC += client/create_channel_posix.cc
+SRC_CC += client/credentials_cc.cc
+SRC_CC += client/cronet_credentials.cc
+SRC_CC += client/generic_stub.cc
+SRC_CC += client/insecure_credentials.cc
+SRC_CC += client/secure_credentials.cc
+SRC_CC += codegen/codegen_init.cc
+SRC_CC += common/alarm.cc
+SRC_CC += common/auth_property_iterator.cc
+SRC_CC += common/channel_arguments.cc
+SRC_CC += common/completion_queue_cc.cc
+SRC_CC += common/core_codegen.cc
+SRC_CC += common/resource_quota_cc.cc
+SRC_CC += common/rpc_method.cc
+SRC_CC += common/secure_auth_context.cc
+SRC_CC += common/secure_channel_arguments.cc
+SRC_CC += common/secure_create_auth_context.cc
+SRC_CC += common/validate_service_config.cc
+SRC_CC += common/version_cc.cc
+SRC_CC += ext/filters/census/grpc_context.cc
+SRC_CC += ext/filters/client_channel/backend_metric.cc
+SRC_CC += ext/filters/client_channel/backup_poller.cc
+SRC_CC += ext/filters/client_channel/channel_connectivity.cc
+SRC_CC += ext/filters/client_channel/client_channel.cc
+SRC_CC += ext/filters/client_channel/client_channel_channelz.cc
+SRC_CC += ext/filters/client_channel/client_channel_factory.cc
+SRC_CC += ext/filters/client_channel/client_channel_plugin.cc
+SRC_CC += ext/filters/client_channel/connector.cc
+SRC_CC += ext/filters/client_channel/global_subchannel_pool.cc
+SRC_CC += ext/filters/client_channel/health/health_check_client.cc
+SRC_CC += ext/filters/client_channel/http_connect_handshaker.cc
+SRC_CC += ext/filters/client_channel/http_proxy.cc
+SRC_CC += ext/filters/client_channel/lb_policy.cc
+SRC_CC += ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
+SRC_CC += ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
+SRC_CC += ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
+SRC_CC += ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
+SRC_CC += ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
+SRC_CC += ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+SRC_CC += ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+SRC_CC += ext/filters/client_channel/lb_policy/xds/xds.cc
+SRC_CC += ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
+SRC_CC += ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc
+SRC_CC += ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc
+SRC_CC += ext/filters/client_channel/lb_policy_registry.cc
+SRC_CC += ext/filters/client_channel/local_subchannel_pool.cc
+SRC_CC += ext/filters/client_channel/parse_address.cc
+SRC_CC += ext/filters/client_channel/proxy_mapper.cc
+SRC_CC += ext/filters/client_channel/proxy_mapper_registry.cc
+SRC_CC += ext/filters/client_channel/resolver.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
+SRC_CC += ext/filters/client_channel/resolver/fake/fake_resolver.cc
+SRC_CC += ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
+SRC_CC += ext/filters/client_channel/resolver/xds/xds_resolver.cc
+SRC_CC += ext/filters/client_channel/resolver_registry.cc
+SRC_CC += ext/filters/client_channel/resolver_result_parsing.cc
+SRC_CC += ext/filters/client_channel/resolving_lb_policy.cc
+SRC_CC += ext/filters/client_channel/retry_throttle.cc
+SRC_CC += ext/filters/client_channel/server_address.cc
+SRC_CC += ext/filters/client_channel/service_config.cc
+SRC_CC += ext/filters/client_channel/subchannel.cc
+SRC_CC += ext/filters/client_channel/subchannel_pool_interface.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+SRC_CC += ext/filters/client_idle/client_idle_filter.cc
+SRC_CC += ext/filters/deadline/deadline_filter.cc
+SRC_CC += ext/filters/http/client/http_client_filter.cc
+SRC_CC += ext/filters/http/client_authority_filter.cc
+SRC_CC += ext/filters/http/http_filters_plugin.cc
+SRC_CC += ext/filters/http/message_compress/message_compress_filter.cc
+SRC_CC += ext/filters/http/server/http_server_filter.cc
+SRC_CC += ext/filters/max_age/max_age_filter.cc
+SRC_CC += ext/filters/message_size/message_size_filter.cc
+SRC_CC += ext/filters/workarounds/workaround_cronet_compression_filter.cc
+SRC_CC += ext/filters/workarounds/workaround_utils.cc
+SRC_CC += ext/transport/chttp2/alpn/alpn.cc
+SRC_CC += ext/transport/chttp2/client/authority.cc
+SRC_CC += ext/transport/chttp2/client/chttp2_connector.cc
+SRC_CC += ext/transport/chttp2/client/insecure/channel_create.cc
+SRC_CC += ext/transport/chttp2/client/insecure/channel_create_posix.cc
+SRC_CC += ext/transport/chttp2/client/secure/secure_channel_create.cc
+SRC_CC += ext/transport/chttp2/server/chttp2_server.cc
+SRC_CC += ext/transport/chttp2/server/insecure/server_chttp2.cc
+SRC_CC += ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
+SRC_CC += ext/transport/chttp2/server/secure/server_secure_chttp2.cc
+SRC_CC += ext/transport/chttp2/transport/bin_decoder.cc
+SRC_CC += ext/transport/chttp2/transport/bin_encoder.cc
+SRC_CC += ext/transport/chttp2/transport/chttp2_plugin.cc
+SRC_CC += ext/transport/chttp2/transport/chttp2_transport.cc
+SRC_CC += ext/transport/chttp2/transport/context_list.cc
+SRC_CC += ext/transport/chttp2/transport/flow_control.cc
+SRC_CC += ext/transport/chttp2/transport/frame_data.cc
+SRC_CC += ext/transport/chttp2/transport/frame_goaway.cc
+SRC_CC += ext/transport/chttp2/transport/frame_ping.cc
+SRC_CC += ext/transport/chttp2/transport/frame_rst_stream.cc
+SRC_CC += ext/transport/chttp2/transport/frame_settings.cc
+SRC_CC += ext/transport/chttp2/transport/frame_window_update.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
+SRC_CC += ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
+SRC_CC += ext/transport/chttp2/transport/hpack_encoder.cc
+SRC_CC += ext/transport/chttp2/transport/hpack_parser.cc
+SRC_CC += ext/transport/chttp2/transport/hpack_table.cc
+SRC_CC += ext/transport/chttp2/transport/http2_settings.cc
+SRC_CC += ext/transport/chttp2/transport/huffsyms.cc
+SRC_CC += ext/transport/chttp2/transport/incoming_metadata.cc
+SRC_CC += ext/transport/chttp2/transport/parsing.cc
+SRC_CC += ext/transport/chttp2/transport/stream_lists.cc
+SRC_CC += ext/transport/chttp2/transport/stream_map.cc
+SRC_CC += ext/transport/chttp2/transport/varint.cc
+SRC_CC += ext/transport/chttp2/transport/writing.cc
+SRC_CC += ext/transport/cronet/client/secure/cronet_channel_create.cc
+SRC_CC += ext/transport/cronet/transport/cronet_api_dummy.cc
+SRC_CC += ext/transport/cronet/transport/cronet_transport.cc
+SRC_CC += ext/transport/inproc/inproc_plugin.cc
+SRC_CC += ext/transport/inproc/inproc_transport.cc
+SRC_CC += lib/avl/avl.cc
+SRC_CC += lib/backoff/backoff.cc
+SRC_CC += lib/channel/channel_args.cc
+SRC_CC += lib/channel/channel_stack.cc
+SRC_CC += lib/channel/channel_stack_builder.cc
+SRC_CC += lib/channel/channel_trace.cc
+SRC_CC += lib/channel/channelz.cc
+SRC_CC += lib/channel/channelz_registry.cc
+SRC_CC += lib/channel/connected_channel.cc
+SRC_CC += lib/channel/handshaker.cc
+SRC_CC += lib/channel/handshaker_registry.cc
+SRC_CC += lib/channel/status_util.cc
+SRC_CC += lib/compression/compression.cc
+SRC_CC += lib/compression/compression_args.cc
+SRC_CC += lib/compression/compression_internal.cc
+SRC_CC += lib/compression/message_compress.cc
+SRC_CC += lib/compression/stream_compression.cc
+SRC_CC += lib/compression/stream_compression_gzip.cc
+SRC_CC += lib/compression/stream_compression_identity.cc
+SRC_CC += lib/debug/stats.cc
+SRC_CC += lib/debug/stats_data.cc
+SRC_CC += lib/debug/trace.cc
+SRC_CC += lib/gpr/alloc.cc
+SRC_CC += lib/gpr/atm.cc
+SRC_CC += lib/gpr/cpu_iphone.cc
+SRC_CC += lib/gpr/cpu_linux.cc
+SRC_CC += lib/gpr/cpu_posix.cc
+SRC_CC += lib/gpr/cpu_windows.cc
+SRC_CC += lib/gpr/env_linux.cc
+SRC_CC += lib/gpr/env_posix.cc
+SRC_CC += lib/gpr/env_windows.cc
+SRC_CC += lib/gpr/log.cc
+SRC_CC += lib/gpr/log_android.cc
+SRC_CC += lib/gpr/log_linux.cc
+SRC_CC += lib/gpr/log_posix.cc
+SRC_CC += lib/gpr/log_windows.cc
+SRC_CC += lib/gpr/mpscq.cc
+SRC_CC += lib/gpr/murmur_hash.cc
+SRC_CC += lib/gpr/string.cc
+SRC_CC += lib/gpr/string_posix.cc
+SRC_CC += lib/gpr/string_util_windows.cc
+SRC_CC += lib/gpr/string_windows.cc
+SRC_CC += lib/gpr/sync.cc
+SRC_CC += lib/gpr/sync_posix.cc
+SRC_CC += lib/gpr/sync_windows.cc
+SRC_CC += lib/gpr/time.cc
+SRC_CC += lib/gpr/time_posix.cc
+SRC_CC += lib/gpr/time_precise.cc
+SRC_CC += lib/gpr/time_windows.cc
+SRC_CC += lib/gpr/tls_pthread.cc
+SRC_CC += lib/gpr/tmpfile_msys.cc
+SRC_CC += lib/gpr/tmpfile_posix.cc
+SRC_CC += lib/gpr/tmpfile_windows.cc
+SRC_CC += lib/gpr/wrap_memcpy.cc
+SRC_CC += lib/gprpp/arena.cc
+SRC_CC += lib/gprpp/fork.cc
+SRC_CC += lib/gprpp/global_config_env.cc
+SRC_CC += lib/gprpp/host_port.cc
+SRC_CC += lib/gprpp/thd_posix.cc
+SRC_CC += lib/gprpp/thd_windows.cc
+SRC_CC += lib/http/format_request.cc
+SRC_CC += lib/http/httpcli.cc
+SRC_CC += lib/http/httpcli_security_connector.cc
+SRC_CC += lib/http/parser.cc
+SRC_CC += lib/iomgr/buffer_list.cc
+SRC_CC += lib/iomgr/call_combiner.cc
+SRC_CC += lib/iomgr/cfstream_handle.cc
+SRC_CC += lib/iomgr/combiner.cc
+SRC_CC += lib/iomgr/endpoint.cc
+SRC_CC += lib/iomgr/endpoint_cfstream.cc
+SRC_CC += lib/iomgr/endpoint_pair_posix.cc
+SRC_CC += lib/iomgr/endpoint_pair_uv.cc
+SRC_CC += lib/iomgr/endpoint_pair_windows.cc
+SRC_CC += lib/iomgr/error.cc
+SRC_CC += lib/iomgr/error_cfstream.cc
+SRC_CC += lib/iomgr/ev_epoll1_linux.cc
+SRC_CC += lib/iomgr/ev_epollex_linux.cc
+SRC_CC += lib/iomgr/ev_poll_posix.cc
+SRC_CC += lib/iomgr/ev_posix.cc
+SRC_CC += lib/iomgr/ev_windows.cc
+SRC_CC += lib/iomgr/exec_ctx.cc
+SRC_CC += lib/iomgr/executor.cc
+SRC_CC += lib/iomgr/executor/mpmcqueue.cc
+SRC_CC += lib/iomgr/executor/threadpool.cc
+SRC_CC += lib/iomgr/fork_posix.cc
+SRC_CC += lib/iomgr/fork_windows.cc
+SRC_CC += lib/iomgr/gethostname_fallback.cc
+SRC_CC += lib/iomgr/gethostname_host_name_max.cc
+SRC_CC += lib/iomgr/gethostname_sysconf.cc
+SRC_CC += lib/iomgr/grpc_if_nametoindex_posix.cc
+SRC_CC += lib/iomgr/internal_errqueue.cc
+SRC_CC += lib/iomgr/iocp_windows.cc
+SRC_CC += lib/iomgr/iomgr.cc
+SRC_CC += lib/iomgr/iomgr_custom.cc
+SRC_CC += lib/iomgr/iomgr_internal.cc
+SRC_CC += lib/iomgr/iomgr_posix.cc
+SRC_CC += lib/iomgr/iomgr_posix_cfstream.cc
+SRC_CC += lib/iomgr/iomgr_uv.cc
+SRC_CC += lib/iomgr/iomgr_windows.cc
+SRC_CC += lib/iomgr/is_epollexclusive_available.cc
+SRC_CC += lib/iomgr/load_file.cc
+SRC_CC += lib/iomgr/lockfree_event.cc
+SRC_CC += lib/iomgr/polling_entity.cc
+SRC_CC += lib/iomgr/pollset.cc
+SRC_CC += lib/iomgr/pollset_custom.cc
+SRC_CC += lib/iomgr/pollset_set.cc
+SRC_CC += lib/iomgr/pollset_set_custom.cc
+SRC_CC += lib/iomgr/pollset_set_windows.cc
+SRC_CC += lib/iomgr/pollset_uv.cc
+SRC_CC += lib/iomgr/pollset_windows.cc
+SRC_CC += lib/iomgr/resolve_address.cc
+SRC_CC += lib/iomgr/resolve_address_custom.cc
+SRC_CC += lib/iomgr/resolve_address_posix.cc
+SRC_CC += lib/iomgr/resolve_address_windows.cc
+SRC_CC += lib/iomgr/resource_quota.cc
+SRC_CC += lib/iomgr/sockaddr_utils.cc
+SRC_CC += lib/iomgr/socket_factory_posix.cc
+SRC_CC += lib/iomgr/socket_mutator.cc
+SRC_CC += lib/iomgr/socket_utils_common_posix.cc
+SRC_CC += lib/iomgr/socket_utils_linux.cc
+SRC_CC += lib/iomgr/socket_utils_posix.cc
+SRC_CC += lib/iomgr/socket_utils_uv.cc
+SRC_CC += lib/iomgr/socket_utils_windows.cc
+SRC_CC += lib/iomgr/socket_windows.cc
+SRC_CC += lib/iomgr/tcp_client.cc
+SRC_CC += lib/iomgr/tcp_client_cfstream.cc
+SRC_CC += lib/iomgr/tcp_client_custom.cc
+SRC_CC += lib/iomgr/tcp_client_posix.cc
+SRC_CC += lib/iomgr/tcp_client_windows.cc
+SRC_CC += lib/iomgr/tcp_custom.cc
+SRC_CC += lib/iomgr/tcp_posix.cc
+SRC_CC += lib/iomgr/tcp_server.cc
+SRC_CC += lib/iomgr/tcp_server_custom.cc
+SRC_CC += lib/iomgr/tcp_server_posix.cc
+SRC_CC += lib/iomgr/tcp_server_utils_posix_common.cc
+SRC_CC += lib/iomgr/tcp_server_utils_posix_ifaddrs.cc
+SRC_CC += lib/iomgr/tcp_server_utils_posix_noifaddrs.cc
+SRC_CC += lib/iomgr/tcp_server_windows.cc
+SRC_CC += lib/iomgr/tcp_uv.cc
+SRC_CC += lib/iomgr/tcp_windows.cc
+SRC_CC += lib/iomgr/time_averaged_stats.cc
+SRC_CC += lib/iomgr/timer.cc
+SRC_CC += lib/iomgr/timer_custom.cc
+SRC_CC += lib/iomgr/timer_generic.cc
+SRC_CC += lib/iomgr/timer_heap.cc
+SRC_CC += lib/iomgr/timer_manager.cc
+SRC_CC += lib/iomgr/timer_uv.cc
+SRC_CC += lib/iomgr/udp_server.cc
+SRC_CC += lib/iomgr/unix_sockets_posix.cc
+SRC_CC += lib/iomgr/unix_sockets_posix_noop.cc
+SRC_CC += lib/iomgr/wakeup_fd_eventfd.cc
+SRC_CC += lib/iomgr/wakeup_fd_nospecial.cc
+SRC_CC += lib/iomgr/wakeup_fd_pipe.cc
+SRC_CC += lib/iomgr/wakeup_fd_posix.cc
+SRC_CC += lib/json/json.cc
+SRC_CC += lib/json/json_reader.cc
+SRC_CC += lib/json/json_string.cc
+SRC_CC += lib/json/json_writer.cc
+SRC_CC += lib/profiling/basic_timers.cc
+SRC_CC += lib/profiling/stap_timers.cc
+SRC_CC += lib/security/context/security_context.cc
+SRC_CC += lib/security/credentials/alts/alts_credentials.cc
+SRC_CC += lib/security/credentials/alts/check_gcp_environment.cc
+SRC_CC += lib/security/credentials/alts/check_gcp_environment_linux.cc
+SRC_CC += lib/security/credentials/alts/check_gcp_environment_no_op.cc
+SRC_CC += lib/security/credentials/alts/check_gcp_environment_windows.cc
+SRC_CC += lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
+SRC_CC += lib/security/credentials/alts/grpc_alts_credentials_options.cc
+SRC_CC += lib/security/credentials/alts/grpc_alts_credentials_server_options.cc
+SRC_CC += lib/security/credentials/composite/composite_credentials.cc
+SRC_CC += lib/security/credentials/credentials.cc
+SRC_CC += lib/security/credentials/credentials_metadata.cc
+SRC_CC += lib/security/credentials/fake/fake_credentials.cc
+SRC_CC += lib/security/credentials/google_default/credentials_generic.cc
+SRC_CC += lib/security/credentials/google_default/google_default_credentials.cc
+SRC_CC += lib/security/credentials/iam/iam_credentials.cc
+SRC_CC += lib/security/credentials/jwt/json_token.cc
+SRC_CC += lib/security/credentials/jwt/jwt_credentials.cc
+SRC_CC += lib/security/credentials/jwt/jwt_verifier.cc
+SRC_CC += lib/security/credentials/local/local_credentials.cc
+SRC_CC += lib/security/credentials/oauth2/oauth2_credentials.cc
+SRC_CC += lib/security/credentials/plugin/plugin_credentials.cc
+SRC_CC += lib/security/credentials/ssl/ssl_credentials.cc
+SRC_CC += lib/security/credentials/tls/grpc_tls_credentials_options.cc
+SRC_CC += lib/security/credentials/tls/spiffe_credentials.cc
+SRC_CC += lib/security/security_connector/alts/alts_security_connector.cc
+SRC_CC += lib/security/security_connector/fake/fake_security_connector.cc
+SRC_CC += lib/security/security_connector/load_system_roots_fallback.cc
+SRC_CC += lib/security/security_connector/load_system_roots_linux.cc
+SRC_CC += lib/security/security_connector/local/local_security_connector.cc
+SRC_CC += lib/security/security_connector/security_connector.cc
+SRC_CC += lib/security/security_connector/ssl/ssl_security_connector.cc
+SRC_CC += lib/security/security_connector/ssl_utils.cc
+SRC_CC += lib/security/security_connector/ssl_utils_config.cc
+SRC_CC += lib/security/security_connector/tls/spiffe_security_connector.cc
+SRC_CC += lib/security/transport/client_auth_filter.cc
+SRC_CC += lib/security/transport/secure_endpoint.cc
+SRC_CC += lib/security/transport/security_handshaker.cc
+SRC_CC += lib/security/transport/server_auth_filter.cc
+SRC_CC += lib/security/transport/target_authority_table.cc
+SRC_CC += lib/security/transport/tsi_error.cc
+SRC_CC += lib/security/util/json_util.cc
+SRC_CC += lib/slice/b64.cc
+SRC_CC += lib/slice/percent_encoding.cc
+SRC_CC += lib/slice/slice.cc
+SRC_CC += lib/slice/slice_buffer.cc
+SRC_CC += lib/slice/slice_intern.cc
+SRC_CC += lib/slice/slice_string_helpers.cc
+SRC_CC += lib/surface/api_trace.cc
+SRC_CC += lib/surface/byte_buffer.cc
+SRC_CC += lib/surface/byte_buffer_reader.cc
+SRC_CC += lib/surface/call.cc
+SRC_CC += lib/surface/call_details.cc
+SRC_CC += lib/surface/call_log_batch.cc
+SRC_CC += lib/surface/channel.cc
+SRC_CC += lib/surface/channel_init.cc
+SRC_CC += lib/surface/channel_ping.cc
+SRC_CC += lib/surface/channel_stack_type.cc
+SRC_CC += lib/surface/completion_queue.cc
+SRC_CC += lib/surface/completion_queue_factory.cc
+SRC_CC += lib/surface/event_string.cc
+SRC_CC += lib/surface/init.cc
+SRC_CC += lib/surface/init_secure.cc
+SRC_CC += lib/surface/lame_client.cc
+SRC_CC += lib/surface/metadata_array.cc
+SRC_CC += lib/surface/server.cc
+SRC_CC += lib/surface/validate_metadata.cc
+SRC_CC += lib/surface/version.cc
+SRC_CC += lib/transport/bdp_estimator.cc
+SRC_CC += lib/transport/byte_stream.cc
+SRC_CC += lib/transport/connectivity_state.cc
+SRC_CC += lib/transport/error_utils.cc
+SRC_CC += lib/transport/metadata.cc
+SRC_CC += lib/transport/metadata_batch.cc
+SRC_CC += lib/transport/pid_controller.cc
+SRC_CC += lib/transport/static_metadata.cc
+SRC_CC += lib/transport/status_conversion.cc
+SRC_CC += lib/transport/status_metadata.cc
+SRC_CC += lib/transport/timeout_encoding.cc
+SRC_CC += lib/transport/transport.cc
+SRC_CC += lib/transport/transport_op_string.cc
+SRC_CC += lib/uri/uri_parser.cc
+SRC_CC += server/channel_argument_option.cc
+SRC_CC += server/create_default_thread_pool.cc
+SRC_CC += server/dynamic_thread_pool.cc
+SRC_CC += server/external_connection_acceptor_impl.cc
+SRC_CC += server/health/default_health_check_service.cc
+SRC_CC += server/health/health_check_service.cc
+SRC_CC += server/insecure_server_credentials.cc
+SRC_CC += server/secure_server_credentials.cc
+SRC_CC += server/server_builder.cc
+SRC_CC += server/server_cc.cc
+SRC_CC += server/server_context.cc
+SRC_CC += server/server_credentials.cc
+SRC_CC += server/server_posix.cc
+SRC_CC += thread_manager/thread_manager.cc
+SRC_CC += tsi/alts/crypt/aes_gcm.cc
+SRC_CC += tsi/alts/crypt/gsec.cc
+SRC_CC += tsi/alts/frame_protector/alts_counter.cc
+SRC_CC += tsi/alts/frame_protector/alts_crypter.cc
+SRC_CC += tsi/alts/frame_protector/alts_frame_protector.cc
+SRC_CC += tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc
+SRC_CC += tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc
+SRC_CC += tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc
+SRC_CC += tsi/alts/frame_protector/frame_handler.cc
+SRC_CC += tsi/alts/handshaker/alts_handshaker_client.cc
+SRC_CC += tsi/alts/handshaker/alts_shared_resource.cc
+SRC_CC += tsi/alts/handshaker/alts_tsi_handshaker.cc
+SRC_CC += tsi/alts/handshaker/alts_tsi_utils.cc
+SRC_CC += tsi/alts/handshaker/transport_security_common_api.cc
+SRC_CC += tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
+SRC_CC += tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc
+SRC_CC += tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc
+SRC_CC += tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc
+SRC_CC += tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
+SRC_CC += tsi/fake_transport_security.cc
+SRC_CC += tsi/local_transport_security.cc
+SRC_CC += tsi/ssl/session_cache/ssl_session_boringssl.cc
+SRC_CC += tsi/ssl/session_cache/ssl_session_cache.cc
+SRC_CC += tsi/ssl/session_cache/ssl_session_openssl.cc
+SRC_CC += tsi/ssl_transport_security.cc
+SRC_CC += tsi/transport_security.cc
+SRC_CC += tsi/transport_security_grpc.cc
+SRC_CC += util/byte_buffer_cc.cc
+SRC_CC += util/core_stats.cc
+SRC_CC += util/error_details.cc
+SRC_CC += util/status.cc
+SRC_CC += util/string_ref.cc
+SRC_CC += util/time_cc.cc
+SRC_CC += plugin_registry/grpc_plugin_registry.cc
+
+# generated files
+SRC_CC += reflection.grpc.pb.cc
+SRC_CC += stats.pb.cc
+SRC_CC += status.pb.cc
+
+SRC_C := ext/upb-generated/envoy/api/v2/core/address.upb.c
+SRC_C += ext/upb-generated/envoy/api/v2/core/base.upb.c
+SRC_C += ext/upb-generated/envoy/api/v2/core/http_uri.upb.c
+SRC_C += ext/upb-generated/envoy/api/v2/discovery.upb.c
+SRC_C += ext/upb-generated/envoy/api/v2/eds.upb.c
+SRC_C += ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c
+SRC_C += ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c
+SRC_C += ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c
+SRC_C += ext/upb-generated/envoy/type/percent.upb.c
+SRC_C += ext/upb-generated/google/protobuf/any.upb.c
+SRC_C += ext/upb-generated/google/protobuf/duration.upb.c
+SRC_C += ext/upb-generated/google/protobuf/struct.upb.c
+SRC_C += ext/upb-generated/google/protobuf/timestamp.upb.c
+SRC_C += ext/upb-generated/google/protobuf/wrappers.upb.c
+SRC_C += ext/upb-generated/google/rpc/status.upb.c
+SRC_C += ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c
+SRC_C += ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c
+SRC_C += ext/upb-generated/src/proto/grpc/health/v1/health.upb.c
+SRC_C += ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c
+SRC_C += ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c
+SRC_C += third_party/address_sorting/address_sorting.c
+SRC_C += third_party/address_sorting/address_sorting_posix.c
+SRC_C += third_party/address_sorting/address_sorting_windows.c
+SRC_C += third_party/cares/cares/ares__get_hostent.c
+SRC_C += third_party/cares/cares/ares_parse_soa_reply.c
+SRC_C += third_party/cares/cares/ares_free_string.c
+SRC_C += third_party/cares/cares/ares_strerror.c
+SRC_C += third_party/cares/cares/ares_parse_mx_reply.c
+SRC_C += third_party/cares/cares/ares_process.c
+SRC_C += third_party/cares/cares/ares_library_init.c
+SRC_C += third_party/cares/cares/ares_parse_ns_reply.c
+SRC_C += third_party/cares/cares/ares_options.c
+SRC_C += third_party/cares/cares/bitncmp.c
+SRC_C += third_party/cares/cares/inet_net_pton.c
+SRC_C += third_party/cares/cares/ares_mkquery.c
+SRC_C += third_party/cares/cares/ares_strsplit.c
+SRC_C += third_party/cares/cares/ares_search.c
+SRC_C += third_party/cares/cares/ares_getopt.c
+SRC_C += third_party/cares/cares/ares__close_sockets.c
+SRC_C += third_party/cares/cares/ares_cancel.c
+SRC_C += third_party/cares/cares/ares_platform.c
+SRC_C += third_party/cares/cares/ares_parse_a_reply.c
+SRC_C += third_party/cares/cares/ares_gethostbyaddr.c
+SRC_C += third_party/cares/cares/ares_strdup.c
+SRC_C += third_party/cares/cares/ahost.c
+SRC_C += third_party/cares/cares/ares_gethostbyname.c
+SRC_C += third_party/cares/cares/ares_nowarn.c
+SRC_C += third_party/cares/cares/ares__read_line.c
+SRC_C += third_party/cares/cares/ares_timeout.c
+SRC_C += third_party/cares/cares/ares_expand_name.c
+SRC_C += third_party/cares/cares/inet_ntop.c
+SRC_C += third_party/cares/cares/ares_parse_ptr_reply.c
+SRC_C += third_party/cares/cares/ares_parse_srv_reply.c
+SRC_C += third_party/cares/cares/ares_expand_string.c
+SRC_C += third_party/cares/cares/ares_getenv.c
+SRC_C += third_party/cares/cares/ares_parse_aaaa_reply.c
+SRC_C += third_party/cares/cares/windows_port.c
+SRC_C += third_party/cares/cares/ares_destroy.c
+SRC_C += third_party/cares/cares/ares_init.c
+SRC_C += third_party/cares/cares/ares_parse_txt_reply.c
+SRC_C += third_party/cares/cares/ares_strcasecmp.c
+SRC_C += third_party/cares/cares/ares_data.c
+SRC_C += third_party/cares/cares/ares_getnameinfo.c
+SRC_C += third_party/cares/cares/ares_parse_naptr_reply.c
+SRC_C += third_party/cares/cares/ares_version.c
+SRC_C += third_party/cares/cares/ares_create_query.c
+SRC_C += third_party/cares/cares/ares_free_hostent.c
+SRC_C += third_party/cares/cares/ares_fds.c
+SRC_C += third_party/cares/cares/ares_android.c
+SRC_C += third_party/cares/cares/ares_getsock.c
+SRC_C += third_party/cares/cares/ares__timeval.c
+SRC_C += third_party/cares/cares/ares_send.c
+SRC_C += third_party/cares/cares/ares_writev.c
+SRC_C += third_party/cares/cares/ares_query.c
+SRC_C += third_party/cares/cares/ares_llist.c
+SRC_C += third_party/upb/upb/decode.c
+SRC_C += third_party/upb/upb/encode.c
+SRC_C += third_party/upb/upb/msg.c
+SRC_C += third_party/upb/upb/upb.c
+
+# provide a dummy for if_indextoname
+SRC_C += third_party/genode/if_indextoname.c
+
+vpath %.c $(GRPC_CORE_SRC_DIR)
+vpath %.c $(GRPC_DIR)
+vpath %.cc $(GRPC_SRC_DIR)
+vpath %.cc $(GRPC_CORE_SRC_DIR)
+vpath stats.proto $(GRPC_PROTO_DIR)/core
+vpath status.proto $(GRPC_PROTO_DIR)/status
+vpath reflection.proto $(GRPC_PROTO_DIR)/reflection/v1alpha
+
+$(SRC_CC): stats.pb.h \
+ status.pb.h \
+ reflection.grpc.pb.h
+
+stats.pb.h: stats.proto
+ $(VERBOSE)$(PROTOC) --proto_path=$(GRPC_PROTO_DIR)/core \
+ --proto_path=$(PROTO_FILES_DIR) \
+ --cpp_out=. \
+ $<
+
+status.pb.h: status.proto
+ $(VERBOSE)$(PROTOC) --proto_path=$(GRPC_PROTO_DIR)/status \
+ --proto_path=$(PROTO_FILES_DIR) \
+ --cpp_out=. \
+ $<
+
+reflection.grpc.pb.h: reflection.proto
+ $(VERBOSE)$(PROTOC) --proto_path=$(GRPC_PROTO_DIR)/reflection/v1alpha \
+ --proto_path=$(PROTO_FILES_DIR) \
+ --cpp_out=. \
+ $<
+ $(VERBOSE)$(PROTOC) --plugin=protoc-gen-grpc=$(GRPC_PLUGIN) \
+ --proto_path=$(PROTO_FILES_DIR) \
+ --proto_path=$(GRPC_PROTO_DIR)/reflection/v1alpha \
+ --grpc_out=. \
+ $<
diff --git a/lib/mk/protobuf.mk b/lib/mk/protobuf.mk
new file mode 100644
index 0000000..947b05c
--- /dev/null
+++ b/lib/mk/protobuf.mk
@@ -0,0 +1,98 @@
+include $(REP_DIR)/lib/import/import-protobuf.mk
+
+PROTOBUF_SRC_DIR := $(PROTOBUF_PORT_DIR)/src/lib/protobuf/src/google/protobuf
+
+LIBS := base
+LIBS := libc
+LIBS := zlib
+LIBS := stdcxx
+
+SHARED_LIB := yes
+
+CC_CXX_WARN_STRICT :=
+CC_OPT += -DHAVE_PTHREAD=0 -Wno-sign-compare
+
+INC_DIR += $(PROTOBUF_PORT_DIR)/src/lib/protobuf/src
+
+SRC_CC := \
+ any.cc \
+ any.pb.cc \
+ any_lite.cc \
+ api.pb.cc \
+ arena.cc \
+ descriptor.cc \
+ descriptor.pb.cc \
+ descriptor_database.cc \
+ duration.pb.cc \
+ dynamic_message.cc \
+ empty.pb.cc \
+ extension_set.cc \
+ extension_set_heavy.cc \
+ field_mask.pb.cc \
+ generated_message_reflection.cc \
+ generated_message_table_driven.cc \
+ generated_message_util.cc \
+ implicit_weak_message.cc \
+ map_field.cc \
+ message.cc \
+ message_lite.cc \
+ parse_context.cc \
+ reflection_ops.cc \
+ repeated_field.cc \
+ service.cc \
+ source_context.pb.cc \
+ struct.pb.cc \
+ text_format.cc \
+ timestamp.pb.cc \
+ type.pb.cc \
+ unknown_field_set.cc \
+ wire_format_lite.cc \
+ wire_format.cc \
+ wrappers.pb.cc \
+ compiler/importer.cc \
+ compiler/parser.cc \
+ compiler/plugin.pb.cc \
+ stubs/bytestream.cc \
+ stubs/common.cc \
+ stubs/int128.cc \
+ stubs/mathlimits.cc \
+ stubs/status.cc \
+ stubs/statusor.cc \
+ stubs/stringpiece.cc \
+ stubs/stringprintf.cc \
+ stubs/structurally_valid.cc \
+ stubs/strutil.cc \
+ stubs/substitute.cc \
+ stubs/time.cc \
+ io/coded_stream.cc \
+ io/gzip_stream.cc \
+ io/io_win32.cc \
+ io/printer.cc \
+ io/strtod.cc \
+ io/tokenizer.cc \
+ io/zero_copy_stream.cc \
+ io/zero_copy_stream_impl.cc \
+ io/zero_copy_stream_impl_lite.cc \
+ util/delimited_message_util.cc \
+ util/field_comparator.cc \
+ util/field_mask_util.cc \
+ util/json_util.cc \
+ util/message_differencer.cc \
+ util/time_util.cc \
+ util/type_resolver_util.cc \
+ util/internal/datapiece.cc \
+ util/internal/default_value_objectwriter.cc \
+ util/internal/error_listener.cc \
+ util/internal/field_mask_utility.cc \
+ util/internal/json_escaping.cc \
+ util/internal/json_objectwriter.cc \
+ util/internal/json_stream_parser.cc \
+ util/internal/object_writer.cc \
+ util/internal/proto_writer.cc \
+ util/internal/protostream_objectsource.cc \
+ util/internal/protostream_objectwriter.cc \
+ util/internal/type_info.cc \
+ util/internal/type_info_test_helper.cc \
+ util/internal/utility.cc \
+
+vpath %.cc $(PROTOBUF_SRC_DIR)
diff --git a/ports/protobuf_grpc.hash b/ports/protobuf_grpc.hash
new file mode 100644
index 0000000..65a450f
--- /dev/null
+++ b/ports/protobuf_grpc.hash
@@ -0,0 +1 @@
+650017daf022bced2f8d03f706f02fdc3073fdf9
diff --git a/ports/protobuf_grpc.port b/ports/protobuf_grpc.port
new file mode 100644
index 0000000..125da42
--- /dev/null
+++ b/ports/protobuf_grpc.port
@@ -0,0 +1,107 @@
+LICENSE := GPLv2
+VERSION := 19.09
+
+DOWNLOADS := protobuf.git
+DOWNLOADS += grpc.git
+DOWNLOADS += grpc-host.git
+
+#
+# !!! IMPORTANT !!!
+# PROTOBUF_VERSION must match the version that gRPC uses in the
+# third_party/protobuf sub directory!
+#
+GRPC_VERSION := v1.24.0
+PROTOBUF_VERSION := v3.8.0
+
+URL(protobuf) := https://github.com/protocolbuffers/protobuf.git
+DIR(protobuf) := src/lib/protobuf
+REV(protobuf) := $(PROTOBUF_VERSION)
+
+URL(grpc) := https://github.com/grpc/grpc.git
+DIR(grpc) := src/lib/grpc
+REV(grpc) := $(GRPC_VERSION)
+
+#
+# This is required, as the patched sources will not build
+# for the host tools.
+#
+URL(grpc-host) := https://github.com/grpc/grpc.git
+DIR(grpc-host) := src/lib/grpc-host
+REV(grpc-host) := $(GRPC_VERSION)
+
+PATCHES := $(addprefix src/lib/protobuf/patches/, \
+ 01-mutex.patch \
+ 02-run_once.patch \
+ 03-thread.patch)
+PATCHES += $(addprefix src/lib/grpc/patches/, \
+ 01_mutex.patch \
+ 02_generated_includes.patch \
+ 03_if_nametoindex.patch \
+ 04_socket_stuff.patch \
+ 05_example.patch \
+ 06_if_indextoname.patch \
+ 07_send_recv.patch \
+ 08_grpc_accept4.patch)
+
+PATCH_OPT_PROTOBUF := -p1 -d src/lib/protobuf
+PATCH_OPT(src/lib/protobuf/patches/01-mutex.patch) := $(PATCH_OPT_PROTOBUF)
+PATCH_OPT(src/lib/protobuf/patches/02-run_once.patch) := $(PATCH_OPT_PROTOBUF)
+PATCH_OPT(src/lib/protobuf/patches/03-thread.patch) := $(PATCH_OPT_PROTOBUF)
+
+PATCH_OPT_GRPC := -p1 -d src/lib/grpc
+PATCH_OPT(src/lib/grpc/patches/01_mutex.patch) := $(PATCH_OPT_GRPC)
+PATCH_OPT(src/lib/grpc/patches/02_generated_includes.patch) := $(PATCH_OPT_GRPC)
+PATCH_OPT(src/lib/grpc/patches/03_if_nametoindex.patch) := $(PATCH_OPT_GRPC)
+PATCH_OPT(src/lib/grpc/patches/04_socket_stuff.patch) := $(PATCH_OPT_GRPC)
+PATCH_OPT(src/lib/grpc/patches/05_example.patch) := $(PATCH_OPT_GRPC)
+PATCH_OPT(src/lib/grpc/patches/06_if_indextoname.patch) := $(PATCH_OPT_GRPC)
+PATCH_OPT(src/lib/grpc/patches/07_send_recv.patch) := $(PATCH_OPT_GRPC)
+PATCH_OPT(src/lib/grpc/patches/08_grpc_accept4.patch) := $(PATCH_OPT_GRPC)
+
+DIRS := include/grpc/cpp/common
+DIRS += include/grpc/cpp/util
+DIRS += include/grpc/cpp/server
+DIRS += include/grpc
+DIRS += include/grpc/impl/codegen
+DIRS += include/grpc/support
+DIRS += include/grpcpp
+DIRS += include/grpcpp/security
+DIRS += include/grpcpp/support
+DIRS += include/grpcpp/generic
+DIRS += include/grpcpp/impl
+DIRS += include/grpcpp/impl/codegen
+DIRS += include/grpcpp/impl/codegen/security
+DIRS += include/grpcpp/ext
+DIRS += include/google/protobuf
+DIRS += include/google/protobuf/compiler
+DIRS += include/google/protobuf/io
+DIRS += include/google/protobuf/stubs
+DIRS += include/google/protobuf/util
+DIRS += proto/protobuf/src/google/protobuf
+
+DIR_CONTENT(include/grpc/cpp/common) := src/lib/grpc/src/cpp/common/*.h
+DIR_CONTENT(include/grpc/cpp/util) := src/lib/grpc/src/cpp/util/*.h
+DIR_CONTENT(include/grpc/cpp/server) := src/lib/grpc/src/cpp/server/*.h
+DIR_CONTENT(include/grpc) := src/lib/grpc/include/grpc/*.h
+DIR_CONTENT(include/grpc/impl/codegen) := src/lib/grpc/include/grpc/impl/codegen/*.h
+DIR_CONTENT(include/grpc/support) := src/lib/grpc/include/grpc/support/*.h
+DIR_CONTENT(include/grpcpp) := src/lib/grpc/include/grpcpp/*.h
+DIR_CONTENT(include/grpcpp/security) := src/lib/grpc/include/grpcpp/security/*.h
+DIR_CONTENT(include/grpcpp/support) := src/lib/grpc/include/grpcpp/support/*.h
+DIR_CONTENT(include/grpcpp/generic) := src/lib/grpc/include/grpcpp/generic/*.h
+DIR_CONTENT(include/grpcpp/impl) := src/lib/grpc/include/grpcpp/impl/*.h
+DIR_CONTENT(include/grpcpp/impl/codegen) := src/lib/grpc/include/grpcpp/impl/codegen/*.h
+DIR_CONTENT(include/grpcpp/impl/codegen/security) := src/lib/grpc/include/grpcpp/impl/codegen/security/*.h
+DIR_CONTENT(include/grpcpp/ext) := src/lib/grpc/include/grpcpp/ext/*.h
+
+
+DIR_CONTENT(include/google/protobuf) := src/lib/protobuf/src/google/protobuf/*.h \
+ src/lib/protobuf/src/google/protobuf/*.inc
+DIR_CONTENT(include/google/protobuf/compiler) := src/lib/protobuf/src/google/protobuf/compiler/*.h
+DIR_CONTENT(include/google/protobuf/io) := src/lib/protobuf/src/google/protobuf/io/*.h
+DIR_CONTENT(include/google/protobuf/stubs) := src/lib/protobuf/src/google/protobuf/stubs/*.h
+DIR_CONTENT(include/google/protobuf/util) := src/lib/protobuf/src/google/protobuf/util/*.h
+
+DIR_CONTENT(proto/protobuf/src/google/protobuf) := src/lib/protobuf/src/google/protobuf/*.proto
+
+# vim: syntax=make
diff --git a/recipes/api/grpc/content.mk b/recipes/api/grpc/content.mk
new file mode 100644
index 0000000..fe27adf
--- /dev/null
+++ b/recipes/api/grpc/content.mk
@@ -0,0 +1,14 @@
+content: include/grpc include/grpcpp LICENSE
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/protobuf_grpc)
+
+include/grpc:
+ mkdir -p $@
+ cp -r $(PORT_DIR)/$@/* $@
+
+include/grpcpp:
+ mkdir -p $@
+ cp -r $(PORT_DIR)/$@/* $@
+
+LICENSE:
+ cp $(PORT_DIR)/src/lib/grpc/LICENSE $@
diff --git a/recipes/api/grpc/hash b/recipes/api/grpc/hash
new file mode 100644
index 0000000..accb419
--- /dev/null
+++ b/recipes/api/grpc/hash
@@ -0,0 +1 @@
+2019-10-30 21572ce91e72f70f403e0e80771b8a56856948a1
diff --git a/recipes/api/protobuf/content.mk b/recipes/api/protobuf/content.mk
new file mode 100644
index 0000000..16bdbb4
--- /dev/null
+++ b/recipes/api/protobuf/content.mk
@@ -0,0 +1,10 @@
+content: include/google LICENSE
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/protobuf_grpc)
+
+include/google:
+ mkdir -p $@
+ cp -r $(PORT_DIR)/$@/* $@
+
+LICENSE:
+ cp $(PORT_DIR)/src/lib/protobuf/LICENSE $@
diff --git a/recipes/api/protobuf/hash b/recipes/api/protobuf/hash
new file mode 100644
index 0000000..3ef2d39
--- /dev/null
+++ b/recipes/api/protobuf/hash
@@ -0,0 +1 @@
+2019-10-03 2e2ea2ddc580cc856796b077264cffa997ca8e47
diff --git a/recipes/src/grpc/api b/recipes/src/grpc/api
new file mode 100644
index 0000000..3b2fe54
--- /dev/null
+++ b/recipes/src/grpc/api
@@ -0,0 +1 @@
+grpc
diff --git a/recipes/src/grpc/content.mk b/recipes/src/grpc/content.mk
new file mode 100644
index 0000000..00aca86
--- /dev/null
+++ b/recipes/src/grpc/content.mk
@@ -0,0 +1,28 @@
+MIRROR_FROM_REP_DIR = lib/import/import-grpc.mk \
+ lib/import/import-protobuf.mk \
+ lib/mk/grpc.mk
+
+content: $(MIRROR_FROM_REP_DIR) src/lib/grpc/target.mk LICENSE
+
+$(MIRROR_FROM_REP_DIR):
+ $(mirror_from_rep_dir)
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/protobuf_grpc)
+
+src/lib/grpc/target.mk:
+ mkdir -p src/lib/grpc/src
+ cp -r $(PORT_DIR)/src/lib/grpc/src/* \
+ src/lib/grpc/src/
+ mkdir -p src/lib/grpc/third_party
+ cp -r $(PORT_DIR)/src/lib/grpc/third_party/* \
+ src/lib/grpc/third_party/
+ mkdir -p proto/
+ cp -r $(PORT_DIR)/proto/* \
+ proto/
+ mkdir -p src/lib/grpc/include
+ cp -r $(PORT_DIR)/src/lib/grpc/include/* \
+ src/lib/grpc/include/
+ echo "LIBS := grpc" > $@
+
+LICENSE:
+ cp $(PORT_DIR)/src/lib/grpc/LICENSE $@
diff --git a/recipes/src/grpc/hash b/recipes/src/grpc/hash
new file mode 100644
index 0000000..7a3c4ff
--- /dev/null
+++ b/recipes/src/grpc/hash
@@ -0,0 +1 @@
+2019-10-30 f5f6c562db81992382fbe81170c9adba460b6b09
diff --git a/recipes/src/grpc/used_apis b/recipes/src/grpc/used_apis
new file mode 100644
index 0000000..2a03a83
--- /dev/null
+++ b/recipes/src/grpc/used_apis
@@ -0,0 +1,6 @@
+base
+libc
+libssl
+protobuf
+stdcxx
+zlib
diff --git a/recipes/src/protobuf/api b/recipes/src/protobuf/api
new file mode 100644
index 0000000..b0c79cc
--- /dev/null
+++ b/recipes/src/protobuf/api
@@ -0,0 +1 @@
+protobuf
diff --git a/recipes/src/protobuf/content.mk b/recipes/src/protobuf/content.mk
new file mode 100644
index 0000000..7db3e8f
--- /dev/null
+++ b/recipes/src/protobuf/content.mk
@@ -0,0 +1,17 @@
+MIRROR_FROM_REP_DIR = lib/import/import-protobuf.mk lib/mk/protobuf.mk
+
+content: $(MIRROR_FROM_REP_DIR) src/lib/protobuf/target.mk LICENSE
+
+$(MIRROR_FROM_REP_DIR):
+ $(mirror_from_rep_dir)
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/protobuf_grpc)
+
+src/lib/protobuf/target.mk:
+ mkdir -p src/lib/protobuf/src
+ cp -r $(PORT_DIR)/src/lib/protobuf/src/* \
+ src/lib/protobuf/src/
+ echo "LIBS := protobuf" > $@
+
+LICENSE:
+ cp $(PORT_DIR)/src/lib/protobuf/LICENSE $@
diff --git a/recipes/src/protobuf/hash b/recipes/src/protobuf/hash
new file mode 100644
index 0000000..ef02eb7
--- /dev/null
+++ b/recipes/src/protobuf/hash
@@ -0,0 +1 @@
+2019-10-30 76caade7ae69175c339d8160c94aed44ae1c7a22
diff --git a/recipes/src/protobuf/used_apis b/recipes/src/protobuf/used_apis
new file mode 100644
index 0000000..6b41737
--- /dev/null
+++ b/recipes/src/protobuf/used_apis
@@ -0,0 +1,4 @@
+base
+libc
+stdcxx
+zlib
diff --git a/run/grpc.run b/run/grpc.run
new file mode 100644
index 0000000..3ba0a0d
--- /dev/null
+++ b/run/grpc.run
@@ -0,0 +1,213 @@
+create_boot_directory
+
+
+import_from_depot [depot_user]/src/[base_src]
+import_from_depot [depot_user]/src/dynamic_rom
+import_from_depot [depot_user]/src/init
+import_from_depot [depot_user]/src/libc
+import_from_depot [depot_user]/src/libcrypto
+import_from_depot [depot_user]/src/nic_router
+import_from_depot [depot_user]/src/posix
+import_from_depot [depot_user]/src/protobuf
+import_from_depot [depot_user]/src/libssl
+import_from_depot [depot_user]/src/report_rom
+import_from_depot [depot_user]/src/stdcxx
+import_from_depot [depot_user]/src/vfs
+import_from_depot [depot_user]/src/vfs_lwip
+import_from_depot [depot_user]/src/zlib
+
+
+set build_components {
+ test/grpc/server
+ test/grpc/client
+}
+
+
+build $build_components
+
+
+set nic_router_reporting 0
+
+
+set config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+append_if $nic_router_reporting config {
+
+
+
+
+
+
+
+
+
+}
+append config {
+
+
+
+ }
+append_if $nic_router_reporting config {
+ }
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2000-01-01 00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2000-01-01 00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2000-01-02 00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+
+install_config $config
+
+
+set boot_modules {
+ grpc_server
+ grpc_client
+ grpc.lib.so
+ libc_pipe.lib.so
+}
+
+
+append qemu_args " -nographic "
+
+
+build_boot_image $boot_modules
+
+
+run_genode_until {.*say hello} 20
diff --git a/run/protobuf.run b/run/protobuf.run
new file mode 100644
index 0000000..e1b1225
--- /dev/null
+++ b/run/protobuf.run
@@ -0,0 +1,138 @@
+create_boot_directory
+
+import_from_depot [depot_user]/src/[base_src]
+import_from_depot [depot_user]/src/init
+import_from_depot [depot_user]/src/ram_fs
+import_from_depot [depot_user]/src/sequence
+import_from_depot [depot_user]/src/vfs
+import_from_depot [depot_user]/src/zlib
+
+
+set build_components {
+ test/protobuf/add_person
+ test/protobuf/list_people
+}
+
+build $build_components
+
+set config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+Muster Hans
+hans@muster.com
+123456789012345
+home
+
+
+ 2
+Hans Muster
+muster@hans.com
+999999999999999
+mobile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2000-01-01 00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2000-01-01 00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2000-01-02 00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+set boot_modules {
+ add_person
+ list_people
+ libc.lib.so
+ libm.lib.so
+ stdcxx.lib.so
+ protobuf.lib.so
+ posix.lib.so
+}
+
+append qemu_args " -nographic "
+
+build_boot_image $boot_modules
+
+run_genode_until {child "sequence" exited with exit value 0} 20
diff --git a/src/lib/grpc/patches/01_mutex.patch b/src/lib/grpc/patches/01_mutex.patch
new file mode 100644
index 0000000..7e3902e
--- /dev/null
+++ b/src/lib/grpc/patches/01_mutex.patch
@@ -0,0 +1,110 @@
+commit b4f45e0fa3e07a91623b1039dfea8dfa77f792e0
+Author: Pirmin Duss
+Date: Mon Sep 23 15:15:49 2019 +0200
+
+ mutex fixes
+
+diff --git a/include/grpc/impl/codegen/sync_custom.h b/include/grpc/impl/codegen/sync_custom.h
+index 69b1bf6..dd0bb95 100644
+--- a/include/grpc/impl/codegen/sync_custom.h
++++ b/include/grpc/impl/codegen/sync_custom.h
+@@ -21,15 +21,15 @@
+
+ #include
+
+-#include
++#include
+
+ /* Users defining GPR_CUSTOM_SYNC need to define the following macros. */
+
+ #ifdef GPR_CUSTOM_SYNC
+
+-typedef GPR_CUSTOM_MU_TYPE gpr_mu;
+-typedef GPR_CUSTOM_CV_TYPE gpr_cv;
+-typedef GPR_CUSTOM_ONCE_TYPE gpr_once;
++typedef Genode::Lock gpr_mu;
++typedef pthread_cond_t gpr_cv;
++typedef pthread_once_t gpr_once;
+
+ #define GPR_ONCE_INIT GPR_CUSTOM_ONCE_INIT
+
+diff --git a/include/grpcpp/impl/codegen/sync.h b/include/grpcpp/impl/codegen/sync.h
+index 146f182..d1a60cb 100644
+--- a/include/grpcpp/impl/codegen/sync.h
++++ b/include/grpcpp/impl/codegen/sync.h
+@@ -26,6 +26,7 @@
+ #endif
+
+ #include
++#include
+
+ #include
+ #include
+@@ -58,7 +59,7 @@ class Mutex {
+ private:
+ union {
+ gpr_mu mu_;
+- std::mutex do_not_use_sth_;
++ Genode::Lock do_not_use_sth_;
+ #ifdef GPR_HAS_PTHREAD_H
+ pthread_mutex_t do_not_use_pth_;
+ #endif
+diff --git a/src/lib/grpc/src/cpp/server/external_connection_acceptor_impl.h b/src/lib/grpc/src/cpp/server/external_connection_acceptor_impl.h
+index b5bd935..e835bbf 100644
+--- a/src/cpp/server/external_connection_acceptor_impl.h
++++ b/src/cpp/server/external_connection_acceptor_impl.h
+@@ -20,7 +20,7 @@
+ #define SRC_CPP_SERVER_EXTERNAL_CONNECTION_ACCEPTOR_IMPL_H_
+
+ #include
+-#include
++#include
+
+ #include
+ #include
+@@ -60,7 +60,7 @@ class ExternalConnectionAcceptorImpl
+ const grpc::string name_;
+ std::shared_ptr creds_;
+ grpc_core::TcpServerFdHandler* handler_ = nullptr; // not owned
+- std::mutex mu_;
++ Genode::Lock mu_;
+ bool has_acceptor_ = false;
+ bool started_ = false;
+ bool shutdown_ = false;
+diff --git a/src/lib/grpc/src/cpp/server/external_connection_acceptor_impl.cc b/src/lib/grpc/src/cpp/server/external_connection_acceptor_impl.cc
+index 7f0e2dc..a788b0d 100644
+--- a/src/cpp/server/external_connection_acceptor_impl.cc
++++ b/src/cpp/server/external_connection_acceptor_impl.cc
+@@ -52,7 +52,7 @@ ExternalConnectionAcceptorImpl::ExternalConnectionAcceptorImpl(
+
+ std::unique_ptr
+ ExternalConnectionAcceptorImpl::GetAcceptor() {
+- std::lock_guard lock(mu_);
++ std::lock_guard lock(mu_);
+ GPR_ASSERT(!has_acceptor_);
+ has_acceptor_ = true;
+ return std::unique_ptr(
+@@ -61,7 +61,7 @@ ExternalConnectionAcceptorImpl::GetAcceptor() {
+
+ void ExternalConnectionAcceptorImpl::HandleNewConnection(
+ experimental::ExternalConnectionAcceptor::NewConnectionParameters* p) {
+- std::lock_guard lock(mu_);
++ std::lock_guard lock(mu_);
+ if (shutdown_ || !started_) {
+ // TODO(yangg) clean up.
+ gpr_log(
+@@ -76,12 +76,12 @@ void ExternalConnectionAcceptorImpl::HandleNewConnection(
+ }
+
+ void ExternalConnectionAcceptorImpl::Shutdown() {
+- std::lock_guard lock(mu_);
++ std::lock_guard lock(mu_);
+ shutdown_ = true;
+ }
+
+ void ExternalConnectionAcceptorImpl::Start() {
+- std::lock_guard lock(mu_);
++ std::lock_guard lock(mu_);
+ GPR_ASSERT(!started_);
+ GPR_ASSERT(has_acceptor_);
+ GPR_ASSERT(!shutdown_);
diff --git a/src/lib/grpc/patches/02_generated_includes.patch b/src/lib/grpc/patches/02_generated_includes.patch
new file mode 100644
index 0000000..2d189e6
--- /dev/null
+++ b/src/lib/grpc/patches/02_generated_includes.patch
@@ -0,0 +1,39 @@
+diff --git a/src/cpp/util/core_stats.h b/src/cpp/util/core_stats.h
+index 6366d7d..0f0e2ee 100644
+--- a/src/cpp/util/core_stats.h
++++ b/src/cpp/util/core_stats.h
+@@ -19,7 +19,7 @@
+ #ifndef GRPC_INTERNAL_CPP_UTIL_CORE_STATS_H
+ #define GRPC_INTERNAL_CPP_UTIL_CORE_STATS_H
+
+-#include "src/proto/grpc/core/stats.pb.h"
++#include "stats.pb.h"
+
+ #include "src/core/lib/debug/stats.h"
+
+diff --git a/src/cpp/util/error_details.cc b/src/cpp/util/error_details.cc
+index a1aafcb..6be9390 100644
+--- a/src/cpp/util/error_details.cc
++++ b/src/cpp/util/error_details.cc
+@@ -18,7 +18,7 @@
+
+ #include
+
+-#include "src/proto/grpc/status/status.pb.h"
++#include "status.pb.h"
+
+ namespace grpc_impl {
+
+diff --git a/src/cpp/ext/proto_server_reflection.h b/src/cpp/ext/proto_server_reflection.h
+index bf40c3c180..69f36c3e96 100644
+--- a/src/cpp/ext/proto_server_reflection.h
++++ b/src/cpp/ext/proto_server_reflection.h
+@@ -23,7 +23,7 @@
+ #include
+
+ #include
+-#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h"
++#include "reflection.grpc.pb.h"
+
+ namespace grpc {
+
diff --git a/src/lib/grpc/patches/03_if_nametoindex.patch b/src/lib/grpc/patches/03_if_nametoindex.patch
new file mode 100644
index 0000000..46335f7
--- /dev/null
+++ b/src/lib/grpc/patches/03_if_nametoindex.patch
@@ -0,0 +1,20 @@
+diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc
+index f1ba20dcec..0d94d79246 100644
+--- a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc
++++ b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc
+@@ -29,13 +29,8 @@
+
+ #include
+
+-uint32_t grpc_if_nametoindex(char* name) {
+- uint32_t out = if_nametoindex(name);
+- if (out == 0) {
+- gpr_log(GPR_DEBUG, "if_nametoindex failed for name %s. errno %d", name,
+- errno);
+- }
+- return out;
++uint32_t grpc_if_nametoindex(char*) {
++ return 1;
+ }
+
+ #endif /* GRPC_IF_NAMETOINDEX == 1 && \
diff --git a/src/lib/grpc/patches/04_socket_stuff.patch b/src/lib/grpc/patches/04_socket_stuff.patch
new file mode 100644
index 0000000..d1c02c5
--- /dev/null
+++ b/src/lib/grpc/patches/04_socket_stuff.patch
@@ -0,0 +1,152 @@
+diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc
+index 47d9f51b09..66abe6982a 100644
+--- a/src/core/lib/iomgr/socket_utils_common_posix.cc
++++ b/src/core/lib/iomgr/socket_utils_common_posix.cc
+@@ -70,21 +70,21 @@ grpc_error* grpc_set_socket_nonblocking(int fd, int non_blocking) {
+ return GRPC_ERROR_NONE;
+ }
+
+-grpc_error* grpc_set_socket_no_sigpipe_if_possible(int fd) {
+-#ifdef GRPC_HAVE_SO_NOSIGPIPE
+- int val = 1;
+- int newval;
+- socklen_t intlen = sizeof(newval);
+- if (0 != setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val))) {
+- return GRPC_OS_ERROR(errno, "setsockopt(SO_NOSIGPIPE)");
+- }
+- if (0 != getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &newval, &intlen)) {
+- return GRPC_OS_ERROR(errno, "getsockopt(SO_NOSIGPIPE)");
+- }
+- if ((newval != 0) != (val != 0)) {
+- return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_NOSIGPIPE");
+- }
+-#endif
++grpc_error* grpc_set_socket_no_sigpipe_if_possible(int /*fd*/) {
++//#ifdef GRPC_HAVE_SO_NOSIGPIPE
++// int val = 1;
++// int newval;
++// socklen_t intlen = sizeof(newval);
++// if (0 != setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val))) {
++// return GRPC_OS_ERROR(errno, "setsockopt(SO_NOSIGPIPE)");
++// }
++// if (0 != getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &newval, &intlen)) {
++// return GRPC_OS_ERROR(errno, "getsockopt(SO_NOSIGPIPE)");
++// }
++// if ((newval != 0) != (val != 0)) {
++// return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_NOSIGPIPE");
++// }
++//#endif
+ return GRPC_ERROR_NONE;
+ }
+
+@@ -125,22 +125,22 @@ grpc_error* grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes) {
+ }
+
+ /* set a socket to close on exec */
+-grpc_error* grpc_set_socket_cloexec(int fd, int close_on_exec) {
+- int oldflags = fcntl(fd, F_GETFD, 0);
+- if (oldflags < 0) {
+- return GRPC_OS_ERROR(errno, "fcntl");
+- }
+-
+- if (close_on_exec) {
+- oldflags |= FD_CLOEXEC;
+- } else {
+- oldflags &= ~FD_CLOEXEC;
+- }
+-
+- if (fcntl(fd, F_SETFD, oldflags) != 0) {
+- return GRPC_OS_ERROR(errno, "fcntl");
+- }
+-
++grpc_error* grpc_set_socket_cloexec(int /*fd*/, int /*close_on_exec*/) {
++// int oldflags = fcntl(fd, F_GETFD, 0);
++// if (oldflags < 0) {
++// return GRPC_OS_ERROR(errno, "fcntl");
++// }
++//
++// if (close_on_exec) {
++// oldflags |= FD_CLOEXEC;
++// } else {
++// oldflags &= ~FD_CLOEXEC;
++// }
++//
++// if (fcntl(fd, F_SETFD, oldflags) != 0) {
++// return GRPC_OS_ERROR(errno, "fcntl");
++// }
++//
+ return GRPC_ERROR_NONE;
+ }
+
+@@ -163,24 +163,24 @@ grpc_error* grpc_set_socket_reuse_addr(int fd, int reuse) {
+ }
+
+ /* set a socket to reuse old addresses */
+-grpc_error* grpc_set_socket_reuse_port(int fd, int reuse) {
++grpc_error* grpc_set_socket_reuse_port(int /*fd*/, int /*reuse*/) {
+ #ifndef SO_REUSEPORT
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "SO_REUSEPORT unavailable on compiling system");
+ #else
+- int val = (reuse != 0);
+- int newval;
+- socklen_t intlen = sizeof(newval);
+- if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val))) {
+- return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEPORT)");
+- }
+- if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &newval, &intlen)) {
+- return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEPORT)");
+- }
+- if ((newval != 0) != val) {
+- return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEPORT");
+- }
+-
++// int val = (reuse != 0);
++// int newval;
++// socklen_t intlen = sizeof(newval);
++// if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val))) {
++// return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEPORT)");
++// }
++// if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &newval, &intlen)) {
++// return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEPORT)");
++// }
++// if ((newval != 0) != val) {
++// return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEPORT");
++// }
++//
+ return GRPC_ERROR_NONE;
+ #endif
+ }
+@@ -210,19 +210,19 @@ bool grpc_is_socket_reuse_port_supported() {
+ }
+
+ /* disable nagle */
+-grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) {
+- int val = (low_latency != 0);
+- int newval;
+- socklen_t intlen = sizeof(newval);
+- if (0 != setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val))) {
+- return GRPC_OS_ERROR(errno, "setsockopt(TCP_NODELAY)");
+- }
+- if (0 != getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen)) {
+- return GRPC_OS_ERROR(errno, "getsockopt(TCP_NODELAY)");
+- }
+- if ((newval != 0) != val) {
+- return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set TCP_NODELAY");
+- }
++grpc_error* grpc_set_socket_low_latency(int /*fd*/, int /*low_latency*/) {
++// int val = (low_latency != 0);
++// int newval;
++// socklen_t intlen = sizeof(newval);
++// if (0 != setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val))) {
++// return GRPC_OS_ERROR(errno, "setsockopt(TCP_NODELAY)");
++// }
++// if (0 != getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen)) {
++// return GRPC_OS_ERROR(errno, "getsockopt(TCP_NODELAY)");
++// }
++// if ((newval != 0) != val) {
++// return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set TCP_NODELAY");
++// }
+ return GRPC_ERROR_NONE;
+ }
+
diff --git a/src/lib/grpc/patches/05_example.patch b/src/lib/grpc/patches/05_example.patch
new file mode 100644
index 0000000..24a0041
--- /dev/null
+++ b/src/lib/grpc/patches/05_example.patch
@@ -0,0 +1,26 @@
+diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc
+index 932583c84a..0fa38aac38 100644
+--- a/examples/cpp/helloworld/greeter_client.cc
++++ b/examples/cpp/helloworld/greeter_client.cc
+@@ -77,7 +77,7 @@ int main(int argc, char** argv) {
+ // localhost at port 50051). We indicate that the channel isn't authenticated
+ // (use of InsecureChannelCredentials()).
+ GreeterClient greeter(grpc::CreateChannel(
+- "localhost:50051", grpc::InsecureChannelCredentials()));
++ "10.10.10.55:50051", grpc::InsecureChannelCredentials()));
+ std::string user("world");
+ std::string reply = greeter.SayHello(user);
+ std::cout << "Greeter received: " << reply << std::endl;
+diff --git a/examples/cpp/helloworld/greeter_server.cc b/examples/cpp/helloworld/greeter_server.cc
+index f36ad906a2..03025b7920 100644
+--- a/examples/cpp/helloworld/greeter_server.cc
++++ b/examples/cpp/helloworld/greeter_server.cc
+@@ -47,7 +47,7 @@ class GreeterServiceImpl final : public Greeter::Service {
+ };
+
+ void RunServer() {
+- std::string server_address("0.0.0.0:50051");
++ std::string server_address("10.10.10.55:50051");
+ GreeterServiceImpl service;
+
+ ServerBuilder builder;
diff --git a/src/lib/grpc/patches/06_if_indextoname.patch b/src/lib/grpc/patches/06_if_indextoname.patch
new file mode 100644
index 0000000..d3a5507
--- /dev/null
+++ b/src/lib/grpc/patches/06_if_indextoname.patch
@@ -0,0 +1,12 @@
+diff --git a/third_party/genode/if_indextoname.c b/third_party/genode/if_indextoname.c
+new file mode 100644
+index 0000000000..9ea67cee0c
+--- /dev/null
++++ b/third_party/genode/if_indextoname.c
+@@ -0,0 +1,6 @@
++char * if_indextoname(unsigned int ifindex, char *ifname)
++{
++ const char* name = "eth0";
++ ifname = name;
++ return ifname;
++}
diff --git a/src/lib/protobuf/patches/01-mutex.patch b/src/lib/protobuf/patches/01-mutex.patch
new file mode 100644
index 0000000..44f6699
--- /dev/null
+++ b/src/lib/protobuf/patches/01-mutex.patch
@@ -0,0 +1,28 @@
+commit 3a55e1d3c8ab37fb14a9a2875db0e031044d4863
+Author: Pirmin Duss
+Date: Mon Sep 23 16:16:57 2019 +0200
+
+ Mutex fixes
+
+diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h
+index a311889..967be6a 100644
+--- a/src/google/protobuf/stubs/mutex.h
++++ b/src/google/protobuf/stubs/mutex.h
+@@ -30,7 +30,7 @@
+ #ifndef GOOGLE_PROTOBUF_STUBS_MUTEX_H_
+ #define GOOGLE_PROTOBUF_STUBS_MUTEX_H_
+
+-#include
++#include
+
+ #ifdef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
+
+@@ -104,7 +104,7 @@ class PROTOBUF_EXPORT GOOGLE_PROTOBUF_CAPABILITY("mutex") WrappedMutex {
+
+ private:
+ #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
+- std::mutex mu_;
++ Genode::Lock mu_;
+ #else // ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
+ CriticalSectionLock mu_;
+ #endif // #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
diff --git a/src/lib/protobuf/patches/02-run_once.patch b/src/lib/protobuf/patches/02-run_once.patch
new file mode 100644
index 0000000..09d6cd4
--- /dev/null
+++ b/src/lib/protobuf/patches/02-run_once.patch
@@ -0,0 +1,34 @@
+commit 420f5bb78bfd61825ad5d3bc52a27469f298d17b
+Author: Pirmin Duss
+Date: Mon Sep 23 16:33:08 2019 +0200
+
+ run_once fix
+
+diff --git a/src/google/protobuf/stubs/once.h b/src/google/protobuf/stubs/once.h
+index 070d36d..3602ee7 100644
+--- a/src/google/protobuf/stubs/once.h
++++ b/src/google/protobuf/stubs/once.h
+@@ -31,19 +31,16 @@
+ #ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__
+ #define GOOGLE_PROTOBUF_STUBS_ONCE_H__
+
+-#include
+-#include
+-
+ #include
+
+ namespace google {
+ namespace protobuf {
+ namespace internal {
+
+-using once_flag = std::once_flag;
+-template
+-void call_once(Args&&... args ) {
+- std::call_once(std::forward(args)...);
++using once_flag = int;
++template
++void call_once(once_flag, FN fn, Args&&... args ) {
++ fn(std::forward(args)...);
+ }
+
+ } // namespace internal
diff --git a/src/lib/protobuf/patches/03-thread.patch b/src/lib/protobuf/patches/03-thread.patch
new file mode 100644
index 0000000..50fdac3
--- /dev/null
+++ b/src/lib/protobuf/patches/03-thread.patch
@@ -0,0 +1,45 @@
+diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
+index 36d7307..04a565b 100644
+--- a/src/google/protobuf/generated_message_util.cc
++++ b/src/google/protobuf/generated_message_util.cc
+@@ -799,8 +799,8 @@ void InitSCCImpl(SCCInfoBase* scc) {
+ // Either the default in case no initialization is running or the id of the
+ // thread that is currently initializing.
+ #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
+- static std::atomic runner;
+- auto me = std::this_thread::get_id();
++ static std::atomic runner = -1LL;
++ auto me = 1LL;
+ #else
+ // This is a lightweight replacement for std::thread::id. std::thread does not
+ // work on Windows XP SP2 with the latest VC++ libraries, because it utilizes
+@@ -811,20 +811,20 @@ void InitSCCImpl(SCCInfoBase* scc) {
+
+ // This will only happen because the constructor will call InitSCC while
+ // constructing the default instance.
+- if (runner.load(std::memory_order_relaxed) == me) {
+- // Because we're in the process of constructing the default instance.
+- // We can be assured that we're already exploring this SCC.
+- GOOGLE_CHECK_EQ(scc->visit_status.load(std::memory_order_relaxed),
+- SCCInfoBase::kRunning);
+- return;
+- }
++ if (runner.load(std::memory_order_relaxed) == me) {
++ // Because we're in the process of constructing the default instance.
++ // We can be assured that we're already exploring this SCC.
++ GOOGLE_CHECK_EQ(scc->visit_status.load(std::memory_order_relaxed),
++ SCCInfoBase::kRunning);
++ return;
++ }
+ InitProtobufDefaults();
+ mu.Lock();
+- runner.store(me, std::memory_order_relaxed);
++ runner.store(me, std::memory_order_relaxed);
+ InitSCC_DFS(scc);
+
+ #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
+- runner.store(std::thread::id{}, std::memory_order_relaxed);
++ runner.store(0, std::memory_order_relaxed);
+ #else
+ runner.store(-1, std::memory_order_relaxed);
+ #endif // #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
diff --git a/src/test/grpc/client/target.mk b/src/test/grpc/client/target.mk
new file mode 100644
index 0000000..44b2c17
--- /dev/null
+++ b/src/test/grpc/client/target.mk
@@ -0,0 +1,34 @@
+GRPC_DIR := $(call select_from_ports,protobuf_grpc)/src/lib/grpc
+PROTO_DIR := $(GRPC_DIR)/examples/protos
+TARGET := grpc_client
+
+LIBS := posix
+LIBS += protobuf
+LIBS += stdcxx
+LIBS += grpc
+LIBS += libc_pipe
+
+CC_CXX_WARN_STRICT :=
+
+PROTOC := /usr/local/genode/protobuf_grpc/current/bin/protoc
+GRPC_PLUGIN := /usr/local/genode/protobuf_grpc/current/bin/grpc_cpp_plugin
+
+SRC_CC := greeter_client.cc
+SRC_CC += helloworld.pb.cc
+SRC_CC += helloworld.grpc.pb.cc
+
+vpath greeter_client.cc $(GRPC_DIR)/examples/cpp/helloworld
+vpath helloworld.proto $(PROTO_DIR)
+
+$(SRC_CC): helloworld.grpc.pb.h
+
+helloworld.pb.h: helloworld.proto
+ $(VERBOSE)$(PROTOC) --proto_path=$(PROTO_DIR) \
+ --cpp_out=. \
+ $<
+
+helloworld.grpc.pb.h: helloworld.proto helloworld.pb.h
+ $(VERBOSE)$(PROTOC) --plugin=protoc-gen-grpc=$(GRPC_PLUGIN) \
+ --proto_path=$(PROTO_DIR) \
+ --grpc_out=. \
+ $<
diff --git a/src/test/grpc/server/greeter_server.cc b/src/test/grpc/server/greeter_server.cc
new file mode 100644
index 0000000..36fd7c4
--- /dev/null
+++ b/src/test/grpc/server/greeter_server.cc
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include
+#include
+#include
+
+#include
+
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
+#include "helloworld.grpc.pb.h"
+#endif
+
+#include "greeter_server.h"
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+// Logic and data behind the server's behavior.
+class GreeterServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ printf("say hello\n");
+ std::string prefix("Hello ");
+ reply->set_message(prefix + request->name());
+ return Status::OK;
+ }
+};
+
+void RunServer() {
+ std::string server_address("10.10.10.55:50051");
+ GreeterServiceImpl service;
+
+ ServerBuilder builder;
+ // Listen on the given address without any authentication mechanism.
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ // Register "service" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to an *synchronous* service.
+ builder.RegisterService(&service);
+ // Finally assemble the server.
+ std::unique_ptr server(builder.BuildAndStart());
+ std::cout << "Server listening on " << server_address << std::endl;
+
+ // Wait for the server to shutdown. Note that some other thread must be
+ // responsible for shutting down the server for this call to ever return.
+ server->Wait();
+}
+
diff --git a/src/test/grpc/server/greeter_server.h b/src/test/grpc/server/greeter_server.h
new file mode 100644
index 0000000..1dc0617
--- /dev/null
+++ b/src/test/grpc/server/greeter_server.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void RunServer();
+
diff --git a/src/test/grpc/server/main.cc b/src/test/grpc/server/main.cc
new file mode 100644
index 0000000..d99ee89
--- /dev/null
+++ b/src/test/grpc/server/main.cc
@@ -0,0 +1,50 @@
+#include
+#include
+#include
+#include
+#include
+#include "greeter_server.h"
+
+enum { STACK_SIZE = 0xF000 };
+
+namespace Tee_server {
+ using namespace Genode;
+
+ class Runner;
+ class Server_main;
+}
+
+class Tee_server::Runner : public Thread
+{
+ public:
+ Runner(Env& env)
+ : Thread(env, "runner", STACK_SIZE)
+ {
+ }
+
+ void entry() override
+ {
+ Libc::with_libc([] () {
+ RunServer();
+ });
+ }
+};
+
+class Tee_server::Server_main
+{
+ private:
+ Env& _env;
+ Runner _runner { _env };
+
+ public:
+ Server_main(Env& env)
+ : _env(env)
+ {
+ _runner.start();
+ }
+};
+
+void Libc::Component::construct(Libc::Env &env)
+{
+ static Tee_server::Server_main main(env);
+}
diff --git a/src/test/grpc/server/target.mk b/src/test/grpc/server/target.mk
new file mode 100644
index 0000000..30aee75
--- /dev/null
+++ b/src/test/grpc/server/target.mk
@@ -0,0 +1,35 @@
+GRPC_DIR := $(call select_from_ports,protobuf_grpc)/src/lib/grpc
+PROTO_DIR := $(GRPC_DIR)/examples/protos
+TARGET := grpc_server
+
+LIBS += protobuf
+LIBS += stdcxx
+LIBS += grpc
+LIBS += libc_pipe
+LIBS += vfs
+LIBS += vfs_lwip
+
+CC_CXX_WARN_STRICT :=
+
+PROTOC := /usr/local/genode/protobuf_grpc/current/bin/protoc
+GRPC_PLUGIN := /usr/local/genode/protobuf_grpc/current/bin/grpc_cpp_plugin
+
+SRC_CC := main.cc
+SRC_CC += greeter_server.cc
+SRC_CC += helloworld.pb.cc
+SRC_CC += helloworld.grpc.pb.cc
+
+vpath helloworld.proto $(PROTO_DIR)
+
+$(SRC_CC): helloworld.grpc.pb.h
+
+helloworld.pb.h: helloworld.proto
+ $(VERBOSE)$(PROTOC) --proto_path=$(PROTO_DIR) \
+ --cpp_out=. \
+ $<
+
+helloworld.grpc.pb.h: helloworld.proto helloworld.pb.h
+ $(VERBOSE)$(PROTOC) --plugin=protoc-gen-grpc=$(GRPC_PLUGIN) \
+ --proto_path=$(PROTO_DIR) \
+ --grpc_out=. \
+ $<
diff --git a/src/test/protobuf/add_person/target.mk b/src/test/protobuf/add_person/target.mk
new file mode 100644
index 0000000..b956d41
--- /dev/null
+++ b/src/test/protobuf/add_person/target.mk
@@ -0,0 +1,23 @@
+PROTOBUF_DIR := $(call select_from_ports,protobuf_grpc)/src/lib/protobuf
+
+TARGET := add_person
+
+LIBS := posix protobuf stdcxx
+
+SRC_CC += add_person.cc \
+ addressbook.pb.cc
+
+PROTOC := /usr/local/genode/tool/current/bin/protoc
+
+CC_CXX_WARN_STRICT =
+
+vpath add_person.cc $(PROTOBUF_DIR)/examples
+vpath addressbook.proto $(PROTOBUF_DIR)/examples
+
+$(SRC_CC): addressbook.pb.h
+
+addressbook.pb.h: addressbook.proto
+ $(VERBOSE)$(PROTOC) --proto_path=$(PROTOBUF_DIR)/examples \
+ --proto_path=$(PROTO_FILES_DIR) \
+ --cpp_out=$(shell pwd) \
+ $<
diff --git a/src/test/protobuf/list_people/target.mk b/src/test/protobuf/list_people/target.mk
new file mode 100644
index 0000000..64d0170
--- /dev/null
+++ b/src/test/protobuf/list_people/target.mk
@@ -0,0 +1,23 @@
+PROTOBUF_DIR := $(call select_from_ports,protobuf_grpc)/src/lib/protobuf
+
+TARGET := list_people
+
+LIBS := posix protobuf stdcxx
+
+SRC_CC += list_people.cc \
+ addressbook.pb.cc
+
+PROTOC := /usr/local/genode/tool/current/bin/protoc
+
+CC_CXX_WARN_STRICT =
+
+vpath list_people.cc $(PROTOBUF_DIR)/examples
+vpath addressbook.proto $(PROTOBUF_DIR)/examples
+
+$(SRC_CC): addressbook.pb.h
+
+addressbook.pb.h: addressbook.proto
+ $(VERBOSE)$(PROTOC) --proto_path=$(PROTOBUF_DIR)/examples \
+ --proto_path=$(PROTO_FILES_DIR) \
+ --cpp_out=$(shell pwd) \
+ $<
diff --git a/tool/tool_chain_protobuf b/tool/tool_chain_protobuf
new file mode 100755
index 0000000..c357c82
--- /dev/null
+++ b/tool/tool_chain_protobuf
@@ -0,0 +1,92 @@
+#!/usr/bin/make -f
+#
+# \brief Tool for preparing the protobuf tool-chain for the Genode OS Framework
+# \author Pirmin Duss
+# \date 2019-09-24
+#
+
+SHELL = bash
+ECHO = @echo -e
+VERBOSE = @
+
+help:
+ $(ECHO)
+ $(ECHO) "Build protobuf and gRPC tools for the Genode OS Framework tool chain"
+ $(ECHO)
+ $(ECHO) "--- available commands ---"
+ $(ECHO) "build - build protobuf tools"
+ $(ECHO) "install - install protobuf tools to '$(INSTALL_LOCATION)'"
+ $(ECHO) "clean - clean everything except contrib sources"
+ $(ECHO)
+ $(ECHO) "--- available command line options ---"
+ $(ECHO) "MAKE_JOBS=4 - number of parallel make jobs (default: 4)"
+ $(ECHO)
+
+.PHONY: build help install
+
+#
+# Enable parallel build for 2nd-level $(MAKE) by default
+#
+
+MAKE_JOBS ?= 4
+
+#
+# Source, build and install location
+#
+
+SUDO ?= sudo
+
+TOOL_VERSION := 19.08
+
+GENODE_DIR ?= $(realpath $(dir $(firstword $(MAKEFILE_LIST)))/..)/../..
+CONTRIB_DIR := $(shell $(GENODE_DIR)/tool/ports/current protobuf_grpc)/src/lib
+HOST_TOOL_DIR := $(CONTRIB_DIR)/grpc-host
+GRPC_DIR := $(CONTRIB_DIR)/grpc
+
+DEFAULT_INSTALL_LOCATION := /usr/local/genode/protobuf_grpc/$(TOOL_VERSION)
+INSTALL_LOCATION ?= $(DEFAULT_INSTALL_LOCATION)
+
+configure: extract \
+ $(CONTRIB_DIR)/grpc-host/configure
+
+extract:
+ $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port protobuf_grpc
+
+$(CONTRIB_DIR)/grpc-host/configure:
+ $(VERBOSE)cd $(CONTRIB_DIR)/grpc-host && \
+ git submodule update --init
+
+autogen_protoc:
+ $(VERBOSE)cd $(HOST_TOOL_DIR)/third_party/protobuf && \
+ prefix=$(INSTALL_LOCATION) ./autogen.sh
+
+build: bin/grpc_cpp_plugin
+
+# this also build `protoc` from protobuf
+bin/grpc_cpp_plugin: configure autogen_protoc
+ $(VERBOSE)cd $(HOST_TOOL_DIR) && \
+ prefix=$(INSTALL_LOCATION) make -j$(MAKE_JOBS)
+
+install: copy_generated
+ $(VERBOSE)cd $(HOST_TOOL_DIR) && \
+ prefix=$(INSTALL_LOCATION) make install
+ $(VERBOSE)cp $(HOST_TOOL_DIR)/bins/opt/protobuf/protoc $(INSTALL_LOCATION)/bin
+ifeq ($(INSTALL_LOCATION),$(DEFAULT_INSTALL_LOCATION))
+ $(VERBOSE)$(SUDO) ln -snf $(TOOL_VERSION) $(dir $(INSTALL_LOCATION))/current
+endif
+
+copy_generated:
+ $(VERBOSE)cp -f $(HOST_TOOL_DIR)/src/core/ext/upb-generated/src/proto/grpc/gcp/*.h $(GRPC_DIR)/src/core/ext/upb-generated/src/proto/grpc/gcp/
+ $(VERBOSE)mkdir -p $(GRPC_DIR)/third_party/upb/upb
+ $(VERBOSE)cp -f $(HOST_TOOL_DIR)/third_party/upb/upb/*.{h,inc,c} $(GRPC_DIR)/third_party/upb/upb
+ $(VERBOSE)mkdir -p $(GRPC_DIR)/third_party/abseil-cpp/absl
+ $(VERBOSE)cp -Rf $(HOST_TOOL_DIR)/third_party/abseil-cpp/absl/* $(GRPC_DIR)/third_party/abseil-cpp/absl
+ $(VERBOSE)mkdir -p $(GRPC_DIR)/third_party/address_sorting/include
+ $(VERBOSE)cp -Rf $(HOST_TOOL_DIR)/third_party/address_sorting/include $(GRPC_DIR)/third_party/address_sorting/include
+ $(VERBOSE)mkdir -p $(GRPC_DIR)/third_party/cares/cares
+ $(VERBOSE)cp -Rf $(HOST_TOOL_DIR)/third_party/cares/ares_build.h $(GRPC_DIR)/third_party/cares/cares
+ $(VERBOSE)cp -Rf $(HOST_TOOL_DIR)/third_party/cares/cares/*.{h,c} $(GRPC_DIR)/third_party/cares/cares
+
+clean:
+ $(VERBOSE)cd $(CONTRIB_DIR)/grpc-host && \
+ prefix=$(INSTALL_LOCATION) make clean