From ac845a1cd0df9213409b6a41c838306d7693d2ab Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 27 Dec 2019 11:48:49 -0800 Subject: [PATCH 01/31] Fix log statement --- src/core/lib/iomgr/executor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 63d946c2479..9f92c9fae21 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -143,7 +143,7 @@ void Executor::SetThreading(bool threading) { if (threading) { if (curr_num_threads > 0) { - EXECUTOR_TRACE("(%s) SetThreading(true). curr_num_threads == 0", name_); + EXECUTOR_TRACE("(%s) SetThreading(true). curr_num_threads > 0", name_); return; } From 867d5f805216111bce9961132c4edc612bb5fa92 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 3 Jan 2020 06:52:31 -0800 Subject: [PATCH 02/31] Comment out unused-parameter --- src/core/ext/filters/client_channel/xds/xds_client.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/xds/xds_client.cc b/src/core/ext/filters/client_channel/xds/xds_client.cc index 56b8c2a1c16..3f4ed94cb52 100644 --- a/src/core/ext/filters/client_channel/xds/xds_client.cc +++ b/src/core/ext/filters/client_channel/xds/xds_client.cc @@ -1301,7 +1301,7 @@ void XdsClient::WatchClusterData( w->OnClusterChanged(std::move(update)); } -void XdsClient::CancelClusterDataWatch(StringView cluster, +void XdsClient::CancelClusterDataWatch(StringView /*cluster*/, ClusterWatcherInterface* watcher) { auto it = cluster_state_.cluster_watchers.find(watcher); if (it != cluster_state_.cluster_watchers.end()) { From f1b29deea62afeb62237d740421415cdb43a57c0 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 17 Dec 2019 17:44:52 -0800 Subject: [PATCH 03/31] Improve cancellation mechanism: * Remove the weird cancellation_future; * Convert all CancelledError into RpcError with CANCELLED; * Move part of call logic from Cython to Python layer; * Make unary-stream call based on reader API instead of async generator. --- .../grpc/_cython/_cygrpc/aio/call.pxd.pxi | 13 +- .../grpc/_cython/_cygrpc/aio/call.pyx.pxi | 107 +++++--------- .../grpc/_cython/_cygrpc/aio/channel.pyx.pxi | 37 +---- .../grpcio/grpc/experimental/aio/_call.py | 132 ++++++++++-------- .../grpcio_tests/tests_aio/unit/call_test.py | 15 +- 5 files changed, 129 insertions(+), 175 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pxd.pxi index 3844797c50e..b800cee6028 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pxd.pxi @@ -22,13 +22,12 @@ cdef class _AioCall: # time we need access to the event loop. object _loop - # Streaming call only attributes: - # - # A asyncio.Event that indicates if the status is received on the client side. - object _status_received - # A tuple of key value pairs representing the initial metadata sent by peer. - tuple _initial_metadata + # Flag indicates whether cancel being called or not. Cancellation from + # Core or peer works perfectly fine with normal procedure. However, we + # need this flag to clean up resources for cancellation from the + # application layer. Directly cancelling tasks might cause segfault + # because Core is holding a pointer for the callback handler. + bint _is_locally_cancelled cdef grpc_call* _create_grpc_call(self, object timeout, bytes method) except * cdef void _destroy_grpc_call(self) - cdef AioRpcStatus _cancel_and_create_status(self, object cancellation_future) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi index b98809a12e0..0b5c9a7589a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi @@ -33,8 +33,7 @@ cdef class _AioCall: self._grpc_call_wrapper = GrpcCallWrapper() self._loop = asyncio.get_event_loop() self._create_grpc_call(deadline, method) - - self._status_received = asyncio.Event(loop=self._loop) + self._is_locally_cancelled = False def __dealloc__(self): self._destroy_grpc_call() @@ -78,17 +77,21 @@ cdef class _AioCall: """Destroys the corresponding Core object for this RPC.""" grpc_call_unref(self._grpc_call_wrapper.call) - cdef AioRpcStatus _cancel_and_create_status(self, object cancellation_future): - """Cancels the RPC in Core, and return the final RPC status.""" - cdef AioRpcStatus status + def cancel(self, AioRpcStatus status): + """Cancels the RPC in Core with given RPC status. + + Above abstractions must invoke this method to set Core objects into + proper state. + """ + self._is_locally_cancelled = True + cdef object details cdef char *c_details cdef grpc_call_error error # Try to fetch application layer cancellation details in the future. # * If cancellation details present, cancel with status; # * If details not present, cancel with unknown reason. - if cancellation_future.done(): - status = cancellation_future.result() + if status is not None: details = str_to_bytes(status.details()) self._references.append(details) c_details = details @@ -100,7 +103,6 @@ cdef class _AioCall: NULL, ) assert error == GRPC_CALL_OK - return status else: # By implementation, grpc_call_cancel always return OK error = grpc_call_cancel(self._grpc_call_wrapper.call, NULL) @@ -111,12 +113,9 @@ cdef class _AioCall: None, None, ) - cancellation_future.set_result(status) - return status async def unary_unary(self, bytes request, - object cancellation_future, object initial_metadata_observer, object status_observer): """Performs a unary unary RPC. @@ -145,19 +144,10 @@ cdef class _AioCall: receive_initial_metadata_op, receive_message_op, receive_status_on_client_op) - try: - await execute_batch(self._grpc_call_wrapper, - ops, - self._loop) - except asyncio.CancelledError: - status = self._cancel_and_create_status(cancellation_future) - initial_metadata_observer(None) - status_observer(status) - raise - else: - initial_metadata_observer( - receive_initial_metadata_op.initial_metadata() - ) + # Executes all operations in one batch. + await execute_batch(self._grpc_call_wrapper, + ops, + self._loop) status = AioRpcStatus( receive_status_on_client_op.code(), @@ -179,6 +169,11 @@ cdef class _AioCall: cdef ReceiveStatusOnClientOperation op = ReceiveStatusOnClientOperation(_EMPTY_FLAGS) cdef tuple ops = (op,) await execute_batch(self._grpc_call_wrapper, ops, self._loop) + + # Halts if the RPC is locally cancelled + if self._is_locally_cancelled: + return + cdef AioRpcStatus status = AioRpcStatus( op.code(), op.details(), @@ -186,52 +181,30 @@ cdef class _AioCall: op.error_string(), ) status_observer(status) - self._status_received.set() - - def _handle_cancellation_from_application(self, - object cancellation_future, - object status_observer): - def _cancellation_action(finished_future): - if not self._status_received.set(): - status = self._cancel_and_create_status(finished_future) - status_observer(status) - self._status_received.set() - - cancellation_future.add_done_callback(_cancellation_action) - async def _message_async_generator(self): + async def receive_serialized_message(self): + """Receives one single raw message in bytes.""" cdef bytes received_message - # Infinitely receiving messages, until: + # Receives a message. Returns None when failed: # * EOF, no more messages to read; - # * The client application cancells; + # * The client application cancels; # * The server sends final status. - while True: - if self._status_received.is_set(): - return - - received_message = await _receive_message( - self._grpc_call_wrapper, - self._loop - ) - if received_message is None: - # The read operation failed, Core should explain why it fails - await self._status_received.wait() - return - else: - yield received_message + received_message = await _receive_message( + self._grpc_call_wrapper, + self._loop + ) + return received_message async def unary_stream(self, bytes request, - object cancellation_future, object initial_metadata_observer, object status_observer): - """Actual implementation of the complete unary-stream call. - - Needs to pay extra attention to the raise mechanism. If we want to - propagate the final status exception, then we have to raise it. - Othersize, it would end normally and raise `StopAsyncIteration()`. - """ + """Implementation of the start of a unary-stream call.""" + # Peer may prematurely end this RPC at any point. We need a corutine + # that watches if the server sends the final status. + self._loop.create_task(self._handle_status_once_received(status_observer)) + cdef tuple outbound_ops cdef Operation initial_metadata_op = SendInitialMetadataOperation( _EMPTY_METADATA, @@ -248,21 +221,13 @@ cdef class _AioCall: send_close_op, ) - # Actually sends out the request message. + # Sends out the request message. await execute_batch(self._grpc_call_wrapper, - outbound_ops, - self._loop) - - # Peer may prematurely end this RPC at any point. We need a mechanism - # that handles both the normal case and the error case. - self._loop.create_task(self._handle_status_once_received(status_observer)) - self._handle_cancellation_from_application(cancellation_future, - status_observer) + outbound_ops, + self._loop) # Receives initial metadata. initial_metadata_observer( await _receive_initial_metadata(self._grpc_call_wrapper, self._loop), ) - - return self._message_async_generator() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pyx.pxi index 81b6c208619..4b6dd8c3b35 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pyx.pxi @@ -26,38 +26,13 @@ cdef class AioChannel: def close(self): grpc_channel_destroy(self.channel) - async def unary_unary(self, - bytes method, - bytes request, - object deadline, - object cancellation_future, - object initial_metadata_observer, - object status_observer): - """Assembles a unary-unary RPC. + def call(self, + bytes method, + object deadline): + """Assembles a Cython Call object. Returns: - The response message in bytes. + The _AioCall object. """ cdef _AioCall call = _AioCall(self, deadline, method) - return await call.unary_unary(request, - cancellation_future, - initial_metadata_observer, - status_observer) - - def unary_stream(self, - bytes method, - bytes request, - object deadline, - object cancellation_future, - object initial_metadata_observer, - object status_observer): - """Assembles a unary-stream RPC. - - Returns: - An async generator that yields raw responses. - """ - cdef _AioCall call = _AioCall(self, deadline, method) - return call.unary_stream(request, - cancellation_future, - initial_metadata_observer, - status_observer) + return call diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index be7a48157d0..9e32cbd51f0 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -15,6 +15,7 @@ import asyncio from typing import AsyncIterable, Awaitable, Dict, Optional +import logging import grpc from grpc import _common @@ -167,8 +168,7 @@ class Call(_base_call.Call): raise NotImplementedError() def cancelled(self) -> bool: - return self._cancellation.done( - ) or self._code == grpc.StatusCode.CANCELLED + return self._code == grpc.StatusCode.CANCELLED def done(self) -> bool: return self._status.done() @@ -205,14 +205,17 @@ class Call(_base_call.Call): cancellation (by application) and Core receiving status from peer. We make no promise here which one will win. """ - if self._status.done(): - return - else: - self._status.set_result(status) - self._code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE[ - status.code()] + logging.debug('Call._set_status, %s, %s', self._status.done(), status) + # In case of the RPC finished without receiving metadata. + if not self._initial_metadata.done(): + self._initial_metadata.set_result(None) + + # Sets final status + self._status.set_result(status) + self._code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE[status.code()] async def _raise_rpc_error_if_not_ok(self) -> None: + await self._status if self._code != grpc.StatusCode.OK: raise _create_rpc_error(await self.initial_metadata(), self._status.result()) @@ -245,12 +248,11 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): Returned when an instance of `UnaryUnaryMultiCallable` object is called. """ _request: RequestType - _deadline: Optional[float] _channel: cygrpc.AioChannel - _method: bytes _request_serializer: SerializingFunction _response_deserializer: DeserializingFunction _call: asyncio.Task + _cython_call: cygrpc._AioCall def __init__(self, request: RequestType, deadline: Optional[float], channel: cygrpc.AioChannel, method: bytes, @@ -258,11 +260,10 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): response_deserializer: DeserializingFunction) -> None: super().__init__() self._request = request - self._deadline = deadline self._channel = channel - self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._cython_call = self._channel.call(method, deadline) self._call = self._loop.create_task(self._invoke()) def __del__(self) -> None: @@ -275,19 +276,20 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): serialized_request = _common.serialize(self._request, self._request_serializer) - # NOTE(lidiz) asyncio.CancelledError is not a good transport for - # status, since the Task class do not cache the exact - # asyncio.CancelledError object. So, the solution is catching the error - # in Cython layer, then cancel the RPC and update the status, finally - # re-raise the CancelledError. - serialized_response = await self._channel.unary_unary( - self._method, - serialized_request, - self._deadline, - self._cancellation, - self._set_initial_metadata, - self._set_status, - ) + # NOTE(lidiz) asyncio.CancelledError is not a good transport for status, + # because the asyncio.Task class do not cache the exception object. + # https://github.com/python/cpython/blob/edad4d89e357c92f70c0324b937845d652b20afd/Lib/asyncio/tasks.py#L785 + try: + serialized_response = await self._cython_call.unary_unary( + serialized_request, + self._set_initial_metadata, + self._set_status, + ) + except asyncio.CancelledError: + # Only this class can inject the CancelledError into the RPC + # coroutine, so we are certain that this exception is due to local + # cancellation. + assert self._code == grpc.StatusCode.CANCELLED await self._raise_rpc_error_if_not_ok() return _common.deserialize(serialized_response, @@ -295,8 +297,8 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): def _cancel(self, status: cygrpc.AioRpcStatus) -> bool: """Forwards the application cancellation reasoning.""" - if not self._status.done() and not self._cancellation.done(): - self._cancellation.set_result(status) + if not self._status.done(): + self._set_status(status) self._call.cancel() return True else: @@ -328,13 +330,11 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): Returned when an instance of `UnaryStreamMultiCallable` object is called. """ _request: RequestType - _deadline: Optional[float] _channel: cygrpc.AioChannel - _method: bytes _request_serializer: SerializingFunction _response_deserializer: DeserializingFunction - _call: asyncio.Task - _bytes_aiter: AsyncIterable[bytes] + _cython_call: cygrpc._AioCall + _send_unary_request_task: asyncio.Task _message_aiter: AsyncIterable[ResponseType] def __init__(self, request: RequestType, deadline: Optional[float], @@ -343,13 +343,13 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): response_deserializer: DeserializingFunction) -> None: super().__init__() self._request = request - self._deadline = deadline self._channel = channel - self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer - self._call = self._loop.create_task(self._invoke()) - self._message_aiter = self._process() + self._send_unary_request_task = self._loop.create_task( + self._send_unary_request()) + self._message_aiter = self._fetch_stream_responses() + self._cython_call = self._channel.call(method, deadline) def __del__(self) -> None: if not self._status.done(): @@ -357,32 +357,18 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): cygrpc.AioRpcStatus(cygrpc.StatusCode.cancelled, _GC_CANCELLATION_DETAILS, None, None)) - async def _invoke(self) -> ResponseType: + async def _send_unary_request(self) -> ResponseType: serialized_request = _common.serialize(self._request, self._request_serializer) + await self._cython_call.unary_stream( + serialized_request, self._set_initial_metadata, self._set_status) - self._bytes_aiter = await self._channel.unary_stream( - self._method, - serialized_request, - self._deadline, - self._cancellation, - self._set_initial_metadata, - self._set_status, - ) - - async def _process(self) -> ResponseType: - await self._call - async for serialized_response in self._bytes_aiter: - if self._cancellation.done(): - await self._status - if self._status.done(): - # Raises pre-maturely if final status received here. Generates - # more helpful stack trace for end users. - await self._raise_rpc_error_if_not_ok() - yield _common.deserialize(serialized_response, - self._response_deserializer) - - await self._raise_rpc_error_if_not_ok() + async def _fetch_stream_responses(self) -> ResponseType: + await self._send_unary_request_task + message = await self._read() + while message: + yield message + message = await self._read() def _cancel(self, status: cygrpc.AioRpcStatus) -> bool: """Forwards the application cancellation reasoning. @@ -395,8 +381,15 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): and the client calling "cancel" at the same time, this method respects the winner in Core. """ - if not self._status.done() and not self._cancellation.done(): - self._cancellation.set_result(status) + if not self._status.done(): + self._set_status(status) + self._cython_call.cancel(status) + + if not self._send_unary_request_task.done(): + # Injects CancelledError to the Task. The exception will + # propagate to _fetch_stream_responses as well, if the sending + # is not done. + self._send_unary_request_task.cancel() return True else: return False @@ -409,8 +402,25 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): def __aiter__(self) -> AsyncIterable[ResponseType]: return self._message_aiter + async def _read(self) -> ResponseType: + serialized_response = await self._cython_call.receive_serialized_message( + ) + if serialized_response is None: + return None + else: + return _common.deserialize(serialized_response, + self._response_deserializer) + async def read(self) -> ResponseType: if self._status.done(): await self._raise_rpc_error_if_not_ok() raise asyncio.InvalidStateError(_RPC_ALREADY_FINISHED_DETAILS) - return await self._message_aiter.__anext__() + + response_message = await self._read() + if response_message is None: + # If the read operation failed, Core should explain why. + await self._raise_rpc_error_if_not_ok() + # If everything is okay, there is something wrong internally. + assert False, 'Read operation failed with StatusCode.OK' + else: + return response_message diff --git a/src/python/grpcio_tests/tests_aio/unit/call_test.py b/src/python/grpcio_tests/tests_aio/unit/call_test.py index 78e6dac21ae..849b5f471c8 100644 --- a/src/python/grpcio_tests/tests_aio/unit/call_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/call_test.py @@ -126,18 +126,23 @@ class TestUnaryUnaryCall(AioTestBase): self.assertTrue(call.cancel()) self.assertFalse(call.cancel()) - with self.assertRaises(asyncio.CancelledError) as exception_context: + with self.assertRaises(grpc.RpcError) as exception_context: await call + # The info in the RpcError should match the info in Call object. + rpc_error = exception_context.exception + self.assertEqual(rpc_error.code(), await call.code()) + self.assertEqual(rpc_error.details(), await call.details()) + self.assertEqual(rpc_error.trailing_metadata(), await + call.trailing_metadata()) + self.assertEqual(rpc_error.debug_error_string(), await + call.debug_error_string()) + self.assertTrue(call.cancelled()) self.assertEqual(await call.code(), grpc.StatusCode.CANCELLED) self.assertEqual(await call.details(), 'Locally cancelled by application!') - # NOTE(lidiz) The CancelledError is almost always re-created, - # so we might not want to use it to transmit data. - # https://github.com/python/cpython/blob/edad4d89e357c92f70c0324b937845d652b20afd/Lib/asyncio/tasks.py#L785 - class TestUnaryStreamCall(AioTestBase): From 65e4f17a2c5afe4c0df12867b55270a345fbc742 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 17 Dec 2019 19:29:21 -0800 Subject: [PATCH 04/31] Remove unused code --- src/python/grpcio/grpc/experimental/aio/_call.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index 9e32cbd51f0..1b0ace52376 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -149,14 +149,12 @@ class Call(_base_call.Call): _code: grpc.StatusCode _status: Awaitable[cygrpc.AioRpcStatus] _initial_metadata: Awaitable[MetadataType] - _cancellation: asyncio.Future def __init__(self) -> None: self._loop = asyncio.get_event_loop() self._code = None self._status = self._loop.create_future() self._initial_metadata = self._loop.create_future() - self._cancellation = self._loop.create_future() def cancel(self) -> bool: """Placeholder cancellation method. @@ -205,7 +203,6 @@ class Call(_base_call.Call): cancellation (by application) and Core receiving status from peer. We make no promise here which one will win. """ - logging.debug('Call._set_status, %s, %s', self._status.done(), status) # In case of the RPC finished without receiving metadata. if not self._initial_metadata.done(): self._initial_metadata.set_result(None) From e8283e4818edd1e31709447e612c54a4f38ce43e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 17 Dec 2019 19:32:06 -0800 Subject: [PATCH 05/31] Reword the comment --- src/python/grpcio/grpc/experimental/aio/_call.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index 1b0ace52376..bd720c159ac 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -417,7 +417,7 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): if response_message is None: # If the read operation failed, Core should explain why. await self._raise_rpc_error_if_not_ok() - # If everything is okay, there is something wrong internally. + # If no exception raised, there is something wrong internally. assert False, 'Read operation failed with StatusCode.OK' else: return response_message From d49b0849f05bf6d98897cb8a26ffee0fc4fef877 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 18 Dec 2019 13:35:25 -0800 Subject: [PATCH 06/31] Adding more catch clauses for CancelledError --- .../grpc/_cython/_cygrpc/aio/call.pyx.pxi | 6 ++ .../grpcio/grpc/experimental/aio/_call.py | 43 ++++++--- .../grpcio_tests/tests_aio/unit/call_test.py | 92 +++++++++++++++++++ 3 files changed, 129 insertions(+), 12 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi index 0b5c9a7589a..a726084ec4d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi @@ -77,6 +77,11 @@ cdef class _AioCall: """Destroys the corresponding Core object for this RPC.""" grpc_call_unref(self._grpc_call_wrapper.call) + @property + def locally_cancelled(self): + """Grant Python layer access of the cancelled flag.""" + return self._is_locally_cancelled + def cancel(self, AioRpcStatus status): """Cancels the RPC in Core with given RPC status. @@ -145,6 +150,7 @@ cdef class _AioCall: receive_status_on_client_op) # Executes all operations in one batch. + # Might raise CancelledError, handling it in Python UnaryUnaryCall. await execute_batch(self._grpc_call_wrapper, ops, self._loop) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index bd720c159ac..c8fb5d18568 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -15,7 +15,6 @@ import asyncio from typing import AsyncIterable, Awaitable, Dict, Optional -import logging import grpc from grpc import _common @@ -42,6 +41,8 @@ _NON_OK_CALL_REPRESENTATION = ('<{} of RPC that terminated with:\n' '\tdebug_error_string = "{}"\n' '>') +_EMPTY_METADATA = tuple() + class AioRpcError(grpc.RpcError): """An implementation of RpcError to be used by the asynchronous API. @@ -205,7 +206,7 @@ class Call(_base_call.Call): """ # In case of the RPC finished without receiving metadata. if not self._initial_metadata.done(): - self._initial_metadata.set_result(None) + self._initial_metadata.set_result(_EMPTY_METADATA) # Sets final status self._status.set_result(status) @@ -283,10 +284,10 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): self._set_status, ) except asyncio.CancelledError: - # Only this class can inject the CancelledError into the RPC - # coroutine, so we are certain that this exception is due to local - # cancellation. - assert self._code == grpc.StatusCode.CANCELLED + if self._code != grpc.StatusCode.CANCELLED: + self.cancel() + + # Raises RpcError here if RPC failed or cancelled await self._raise_rpc_error_if_not_ok() return _common.deserialize(serialized_response, @@ -357,8 +358,16 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): async def _send_unary_request(self) -> ResponseType: serialized_request = _common.serialize(self._request, self._request_serializer) - await self._cython_call.unary_stream( - serialized_request, self._set_initial_metadata, self._set_status) + try: + await self._cython_call.unary_stream( + serialized_request, + self._set_initial_metadata, + self._set_status + ) + except asyncio.CancelledError: + if self._code != grpc.StatusCode.CANCELLED: + self.cancel() + await self._raise_rpc_error_if_not_ok() async def _fetch_stream_responses(self) -> ResponseType: await self._send_unary_request_task @@ -400,12 +409,21 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): return self._message_aiter async def _read(self) -> ResponseType: - serialized_response = await self._cython_call.receive_serialized_message( - ) - if serialized_response is None: + # Wait for the request being sent + await self._send_unary_request_task + + # Reads response message from Core + try: + raw_response = await self._cython_call.receive_serialized_message() + except asyncio.CancelledError: + if self._code != grpc.StatusCode.CANCELLED: + self.cancel() + await self._raise_rpc_error_if_not_ok() + + if raw_response is None: return None else: - return _common.deserialize(serialized_response, + return _common.deserialize(raw_response, self._response_deserializer) async def read(self) -> ResponseType: @@ -414,6 +432,7 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): raise asyncio.InvalidStateError(_RPC_ALREADY_FINISHED_DETAILS) response_message = await self._read() + if response_message is None: # If the read operation failed, Core should explain why. await self._raise_rpc_error_if_not_ok() diff --git a/src/python/grpcio_tests/tests_aio/unit/call_test.py b/src/python/grpcio_tests/tests_aio/unit/call_test.py index 849b5f471c8..bbca4dd3996 100644 --- a/src/python/grpcio_tests/tests_aio/unit/call_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/call_test.py @@ -33,6 +33,8 @@ _LOCAL_CANCEL_DETAILS_EXPECTATION = 'Locally cancelled by application!' _RESPONSE_INTERVAL_US = test_constants.SHORT_TIMEOUT * 1000 * 1000 _UNREACHABLE_TARGET = '0.1:1111' +_INFINITE_INTERVAL_US = 2**31-1 + class TestUnaryUnaryCall(AioTestBase): @@ -143,6 +145,29 @@ class TestUnaryUnaryCall(AioTestBase): self.assertEqual(await call.details(), 'Locally cancelled by application!') + async def test_cancel_unary_unary_in_task(self): + async with aio.insecure_channel(self._server_target) as channel: + stub = test_pb2_grpc.TestServiceStub(channel) + coro_started = asyncio.Event() + call = stub.EmptyCall(messages_pb2.SimpleRequest()) + + async def another_coro(): + coro_started.set() + await call + + task = self.loop.create_task(another_coro()) + await coro_started.wait() + + self.assertFalse(task.done()) + task.cancel() + + self.assertEqual(grpc.StatusCode.CANCELLED, await call.code()) + + with self.assertRaises(grpc.RpcError) as exception_context: + await task + self.assertEqual(grpc.StatusCode.CANCELLED, + exception_context.exception.code()) + class TestUnaryStreamCall(AioTestBase): @@ -328,6 +353,73 @@ class TestUnaryStreamCall(AioTestBase): self.assertEqual(await call.code(), grpc.StatusCode.OK) + async def test_cancel_unary_stream_in_task_using_read(self): + async with aio.insecure_channel(self._server_target) as channel: + stub = test_pb2_grpc.TestServiceStub(channel) + coro_started = asyncio.Event() + + # Configs the server method to block forever + request = messages_pb2.StreamingOutputCallRequest() + request.response_parameters.append( + messages_pb2.ResponseParameters( + size=_RESPONSE_PAYLOAD_SIZE, + interval_us=_INFINITE_INTERVAL_US, + )) + + # Invokes the actual RPC + call = stub.StreamingOutputCall(request) + + async def another_coro(): + coro_started.set() + await call.read() + + task = self.loop.create_task(another_coro()) + await coro_started.wait() + + self.assertFalse(task.done()) + task.cancel() + + self.assertEqual(grpc.StatusCode.CANCELLED, await call.code()) + + with self.assertRaises(grpc.RpcError) as exception_context: + await task + self.assertEqual(grpc.StatusCode.CANCELLED, + exception_context.exception.code()) + + async def test_cancel_unary_stream_in_task_using_async_for(self): + async with aio.insecure_channel(self._server_target) as channel: + stub = test_pb2_grpc.TestServiceStub(channel) + coro_started = asyncio.Event() + + # Configs the server method to block forever + request = messages_pb2.StreamingOutputCallRequest() + request.response_parameters.append( + messages_pb2.ResponseParameters( + size=_RESPONSE_PAYLOAD_SIZE, + interval_us=_INFINITE_INTERVAL_US, + )) + + # Invokes the actual RPC + call = stub.StreamingOutputCall(request) + + async def another_coro(): + coro_started.set() + async for _ in call: + pass + + task = self.loop.create_task(another_coro()) + await coro_started.wait() + + self.assertFalse(task.done()) + task.cancel() + + self.assertEqual(grpc.StatusCode.CANCELLED, await call.code()) + + with self.assertRaises(grpc.RpcError) as exception_context: + await task + self.assertEqual(grpc.StatusCode.CANCELLED, + exception_context.exception.code()) + if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG) From 413d29218e06c1407fe6226cc3c41f50cd386ce7 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 18 Dec 2019 13:57:09 -0800 Subject: [PATCH 07/31] Make YAPF happy --- src/python/grpcio/grpc/experimental/aio/_call.py | 8 +++----- src/python/grpcio_tests/tests_aio/unit/call_test.py | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index c8fb5d18568..96415fa9521 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -359,11 +359,9 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): serialized_request = _common.serialize(self._request, self._request_serializer) try: - await self._cython_call.unary_stream( - serialized_request, - self._set_initial_metadata, - self._set_status - ) + await self._cython_call.unary_stream(serialized_request, + self._set_initial_metadata, + self._set_status) except asyncio.CancelledError: if self._code != grpc.StatusCode.CANCELLED: self.cancel() diff --git a/src/python/grpcio_tests/tests_aio/unit/call_test.py b/src/python/grpcio_tests/tests_aio/unit/call_test.py index bbca4dd3996..c0a7fa17017 100644 --- a/src/python/grpcio_tests/tests_aio/unit/call_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/call_test.py @@ -33,7 +33,7 @@ _LOCAL_CANCEL_DETAILS_EXPECTATION = 'Locally cancelled by application!' _RESPONSE_INTERVAL_US = test_constants.SHORT_TIMEOUT * 1000 * 1000 _UNREACHABLE_TARGET = '0.1:1111' -_INFINITE_INTERVAL_US = 2**31-1 +_INFINITE_INTERVAL_US = 2**31 - 1 class TestUnaryUnaryCall(AioTestBase): From 6f0ffef2e94f24475b6197ad920ab287ce8050e8 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 18 Dec 2019 16:15:37 -0800 Subject: [PATCH 08/31] Resolve a TODO and handle one more cancellation corner case --- .../grpcio/grpc/experimental/aio/_call.py | 21 ++++++++++--------- .../grpcio_tests/tests_aio/unit/call_test.py | 4 ---- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index 96415fa9521..7acb5494b4b 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -308,16 +308,17 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): _LOCAL_CANCELLATION_DETAILS, None, None)) def __await__(self) -> ResponseType: - """Wait till the ongoing RPC request finishes. - - Returns: - Response of the RPC call. - - Raises: - RpcError: Indicating that the RPC terminated with non-OK status. - asyncio.CancelledError: Indicating that the RPC was canceled. - """ - response = yield from self._call + """Wait till the ongoing RPC request finishes.""" + try: + response = yield from self._call + except asyncio.CancelledError: + # Even if we converted all other CancelledError, there is still + # this corner case. If the application cancels immediately after + # the Call object is created, we will observe this + # `CancelledError`. + if not self.cancelled(): + self.cancel() + raise _create_rpc_error(_EMPTY_METADATA, self._status.result()) return response diff --git a/src/python/grpcio_tests/tests_aio/unit/call_test.py b/src/python/grpcio_tests/tests_aio/unit/call_test.py index c0a7fa17017..cecce1c79d5 100644 --- a/src/python/grpcio_tests/tests_aio/unit/call_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/call_test.py @@ -121,10 +121,6 @@ class TestUnaryUnaryCall(AioTestBase): self.assertFalse(call.cancelled()) - # TODO(https://github.com/grpc/grpc/issues/20869) remove sleep. - # Force the loop to execute the RPC task. - await asyncio.sleep(0) - self.assertTrue(call.cancel()) self.assertFalse(call.cancel()) From a3d7733dd02054654c53e93e93781c96f8f371e1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 19 Dec 2019 13:58:03 -0800 Subject: [PATCH 09/31] Passing cancel signal to Core for Unary Call as well --- .../grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi | 11 ----------- src/python/grpcio/grpc/experimental/aio/_call.py | 1 + 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi index a726084ec4d..c10d79cb7d3 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi @@ -77,11 +77,6 @@ cdef class _AioCall: """Destroys the corresponding Core object for this RPC.""" grpc_call_unref(self._grpc_call_wrapper.call) - @property - def locally_cancelled(self): - """Grant Python layer access of the cancelled flag.""" - return self._is_locally_cancelled - def cancel(self, AioRpcStatus status): """Cancels the RPC in Core with given RPC status. @@ -112,12 +107,6 @@ cdef class _AioCall: # By implementation, grpc_call_cancel always return OK error = grpc_call_cancel(self._grpc_call_wrapper.call, NULL) assert error == GRPC_CALL_OK - status = AioRpcStatus( - StatusCode.cancelled, - _UNKNOWN_CANCELLATION_DETAILS, - None, - None, - ) async def unary_unary(self, bytes request, diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index 7acb5494b4b..a8969b06edb 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -297,6 +297,7 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): """Forwards the application cancellation reasoning.""" if not self._status.done(): self._set_status(status) + self._cython_call.cancel(status) self._call.cancel() return True else: From 4e3d980f7038f229a09121cf885e9fcf39221d1d Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 2 Jan 2020 10:23:06 -0800 Subject: [PATCH 10/31] Convert local cancellation exception into CancelledError --- .../grpcio/grpc/experimental/aio/_call.py | 24 +++++++++----- .../grpcio_tests/tests_aio/unit/call_test.py | 33 ++++--------------- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index a8969b06edb..1557b678d66 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -150,12 +150,14 @@ class Call(_base_call.Call): _code: grpc.StatusCode _status: Awaitable[cygrpc.AioRpcStatus] _initial_metadata: Awaitable[MetadataType] + _locally_cancelled: bool def __init__(self) -> None: self._loop = asyncio.get_event_loop() self._code = None self._status = self._loop.create_future() self._initial_metadata = self._loop.create_future() + self._locally_cancelled = False def cancel(self) -> bool: """Placeholder cancellation method. @@ -204,6 +206,10 @@ class Call(_base_call.Call): cancellation (by application) and Core receiving status from peer. We make no promise here which one will win. """ + # In case of local cancellation, flip the flag. + if status.details() is _LOCAL_CANCELLATION_DETAILS: + self._locally_cancelled = True + # In case of the RPC finished without receiving metadata. if not self._initial_metadata.done(): self._initial_metadata.set_result(_EMPTY_METADATA) @@ -212,7 +218,9 @@ class Call(_base_call.Call): self._status.set_result(status) self._code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE[status.code()] - async def _raise_rpc_error_if_not_ok(self) -> None: + async def _raise_if_not_ok(self) -> None: + if self._locally_cancelled: + raise asyncio.CancelledError() await self._status if self._code != grpc.StatusCode.OK: raise _create_rpc_error(await self.initial_metadata(), @@ -287,8 +295,8 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): if self._code != grpc.StatusCode.CANCELLED: self.cancel() - # Raises RpcError here if RPC failed or cancelled - await self._raise_rpc_error_if_not_ok() + # Raises here if RPC failed or cancelled + await self._raise_if_not_ok() return _common.deserialize(serialized_response, self._response_deserializer) @@ -319,7 +327,7 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): # `CancelledError`. if not self.cancelled(): self.cancel() - raise _create_rpc_error(_EMPTY_METADATA, self._status.result()) + raise return response @@ -367,7 +375,7 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): except asyncio.CancelledError: if self._code != grpc.StatusCode.CANCELLED: self.cancel() - await self._raise_rpc_error_if_not_ok() + raise async def _fetch_stream_responses(self) -> ResponseType: await self._send_unary_request_task @@ -418,7 +426,7 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): except asyncio.CancelledError: if self._code != grpc.StatusCode.CANCELLED: self.cancel() - await self._raise_rpc_error_if_not_ok() + raise if raw_response is None: return None @@ -428,14 +436,14 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): async def read(self) -> ResponseType: if self._status.done(): - await self._raise_rpc_error_if_not_ok() + await self._raise_if_not_ok() raise asyncio.InvalidStateError(_RPC_ALREADY_FINISHED_DETAILS) response_message = await self._read() if response_message is None: # If the read operation failed, Core should explain why. - await self._raise_rpc_error_if_not_ok() + await self._raise_if_not_ok() # If no exception raised, there is something wrong internally. assert False, 'Read operation failed with StatusCode.OK' else: diff --git a/src/python/grpcio_tests/tests_aio/unit/call_test.py b/src/python/grpcio_tests/tests_aio/unit/call_test.py index cecce1c79d5..bdf2fbfda6b 100644 --- a/src/python/grpcio_tests/tests_aio/unit/call_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/call_test.py @@ -124,18 +124,10 @@ class TestUnaryUnaryCall(AioTestBase): self.assertTrue(call.cancel()) self.assertFalse(call.cancel()) - with self.assertRaises(grpc.RpcError) as exception_context: + with self.assertRaises(asyncio.CancelledError): await call # The info in the RpcError should match the info in Call object. - rpc_error = exception_context.exception - self.assertEqual(rpc_error.code(), await call.code()) - self.assertEqual(rpc_error.details(), await call.details()) - self.assertEqual(rpc_error.trailing_metadata(), await - call.trailing_metadata()) - self.assertEqual(rpc_error.debug_error_string(), await - call.debug_error_string()) - self.assertTrue(call.cancelled()) self.assertEqual(await call.code(), grpc.StatusCode.CANCELLED) self.assertEqual(await call.details(), @@ -159,10 +151,8 @@ class TestUnaryUnaryCall(AioTestBase): self.assertEqual(grpc.StatusCode.CANCELLED, await call.code()) - with self.assertRaises(grpc.RpcError) as exception_context: + with self.assertRaises(asyncio.CancelledError): await task - self.assertEqual(grpc.StatusCode.CANCELLED, - exception_context.exception.code()) class TestUnaryStreamCall(AioTestBase): @@ -201,7 +191,7 @@ class TestUnaryStreamCall(AioTestBase): call.details()) self.assertFalse(call.cancel()) - with self.assertRaises(grpc.RpcError) as exception_context: + with self.assertRaises(asyncio.CancelledError): await call.read() self.assertTrue(call.cancelled()) @@ -232,7 +222,7 @@ class TestUnaryStreamCall(AioTestBase): self.assertFalse(call.cancel()) self.assertFalse(call.cancel()) - with self.assertRaises(grpc.RpcError) as exception_context: + with self.assertRaises(asyncio.CancelledError): await call.read() async def test_early_cancel_unary_stream(self): @@ -256,16 +246,11 @@ class TestUnaryStreamCall(AioTestBase): self.assertTrue(call.cancel()) self.assertFalse(call.cancel()) - with self.assertRaises(grpc.RpcError) as exception_context: + with self.assertRaises(asyncio.CancelledError): await call.read() self.assertTrue(call.cancelled()) - self.assertEqual(grpc.StatusCode.CANCELLED, - exception_context.exception.code()) - self.assertEqual(_LOCAL_CANCEL_DETAILS_EXPECTATION, - exception_context.exception.details()) - self.assertEqual(grpc.StatusCode.CANCELLED, await call.code()) self.assertEqual(_LOCAL_CANCEL_DETAILS_EXPECTATION, await call.details()) @@ -377,10 +362,8 @@ class TestUnaryStreamCall(AioTestBase): self.assertEqual(grpc.StatusCode.CANCELLED, await call.code()) - with self.assertRaises(grpc.RpcError) as exception_context: + with self.assertRaises(asyncio.CancelledError): await task - self.assertEqual(grpc.StatusCode.CANCELLED, - exception_context.exception.code()) async def test_cancel_unary_stream_in_task_using_async_for(self): async with aio.insecure_channel(self._server_target) as channel: @@ -411,10 +394,8 @@ class TestUnaryStreamCall(AioTestBase): self.assertEqual(grpc.StatusCode.CANCELLED, await call.code()) - with self.assertRaises(grpc.RpcError) as exception_context: + with self.assertRaises(asyncio.CancelledError): await task - self.assertEqual(grpc.StatusCode.CANCELLED, - exception_context.exception.code()) if __name__ == '__main__': From 9a3ddd8d76170ed9a0c040e3b0d343cd2e698a40 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 3 Jan 2020 10:28:40 -0800 Subject: [PATCH 11/31] Correct comment wording --- src/python/grpcio/grpc/experimental/aio/_call.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index 1557b678d66..36f07ce4d92 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -321,7 +321,7 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): try: response = yield from self._call except asyncio.CancelledError: - # Even if we converted all other CancelledError, there is still + # Even if we caught all other CancelledError, there is still # this corner case. If the application cancels immediately after # the Call object is created, we will observe this # `CancelledError`. From 324d2e64beb31ced7682e6ddab85e7b1f740c52b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 3 Jan 2020 12:54:21 -0800 Subject: [PATCH 12/31] Replace or with || --- src/core/lib/gpr/time_precise.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/gpr/time_precise.cc b/src/core/lib/gpr/time_precise.cc index 3223a84c7ad..e40228d3d0d 100644 --- a/src/core/lib/gpr/time_precise.cc +++ b/src/core/lib/gpr/time_precise.cc @@ -31,7 +31,7 @@ #include "src/core/lib/gpr/time_precise.h" -#if GPR_CYCLE_COUNTER_RDTSC_32 or GPR_CYCLE_COUNTER_RDTSC_64 +#if GPR_CYCLE_COUNTER_RDTSC_32 || GPR_CYCLE_COUNTER_RDTSC_64 #if GPR_LINUX static bool read_freq_from_kernel(double* freq) { // Google production kernel export the frequency for us in kHz. From 252de4f05ccb5703a1d4e8ae473e3b07f5af7f0c Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Fri, 20 Dec 2019 18:01:55 -0800 Subject: [PATCH 13/31] Revert "Support CentOS 7 for gRPC.NET" --- CMakeLists.txt | 1 - Makefile | 2 - build.yaml | 1 - grpc.gyp | 1 - src/csharp/ext/std++compat.cc | 46 ------------------- .../artifacts/distribtest_targets.py | 4 +- 6 files changed, 2 insertions(+), 53 deletions(-) delete mode 100644 src/csharp/ext/std++compat.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index cf6258b464c..b6be8766fd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5855,7 +5855,6 @@ if(gRPC_BUILD_CSHARP_EXT) add_library(grpc_csharp_ext SHARED src/csharp/ext/grpc_csharp_ext.c - src/csharp/ext/std++compat.cc ) set_target_properties(grpc_csharp_ext PROPERTIES diff --git a/Makefile b/Makefile index 7ef9c09b9e1..3522efe847c 100644 --- a/Makefile +++ b/Makefile @@ -8145,7 +8145,6 @@ $(OBJDIR)/$(CONFIG)/test/cpp/qps/usage_timer.o: $(GENDIR)/src/proto/grpc/testing LIBGRPC_CSHARP_EXT_SRC = \ src/csharp/ext/grpc_csharp_ext.c \ - src/csharp/ext/std++compat.cc \ PUBLIC_HEADERS_C += \ @@ -23368,7 +23367,6 @@ src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP) src/cpp/util/core_stats.cc: $(OPENSSL_DEP) src/cpp/util/error_details.cc: $(OPENSSL_DEP) src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP) -src/csharp/ext/std++compat.cc: $(OPENSSL_DEP) test/core/bad_client/bad_client.cc: $(OPENSSL_DEP) test/core/bad_ssl/server_common.cc: $(OPENSSL_DEP) test/core/end2end/data/client_certs.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index accfad1ee20..444a862c39a 100644 --- a/build.yaml +++ b/build.yaml @@ -2258,7 +2258,6 @@ libs: language: csharp src: - src/csharp/ext/grpc_csharp_ext.c - - src/csharp/ext/std++compat.cc deps: - grpc - gpr diff --git a/grpc.gyp b/grpc.gyp index 5caad279cec..3568105522b 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2309,7 +2309,6 @@ ], 'sources': [ 'src/csharp/ext/grpc_csharp_ext.c', - 'src/csharp/ext/std++compat.cc', ], }, { diff --git a/src/csharp/ext/std++compat.cc b/src/csharp/ext/std++compat.cc deleted file mode 100644 index 1ab3fb21e1d..00000000000 --- a/src/csharp/ext/std++compat.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Copyright 2019 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 - -#if defined(__GNUC__) - -namespace std { - -// CentOS 7 (GLIBC_2.17 / GLIBCXX_3.4.19) doesn't have a following symbol -// which was added to GLIBCXX_3.4.20. gRPC uses Debian 8 which has -// GLIBCXX_3.4.20 when building .net artifacts so artifacts can have symbols -// which are not available on CentOS 7. -// To support CentOS 7, missing symbols are provided as weak symbols. -void __attribute__((weak)) __throw_out_of_range_fmt(char const* fmt, ...) { - va_list ap; - char buf[1024]; // That should be big enough. - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - buf[sizeof(buf) - 1] = 0; - va_end(ap); - - __throw_range_error(buf); -} - -} // namespace std - -#endif // defined(__GNUC__) diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index 2b602198b17..337a25acf4f 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -275,8 +275,8 @@ class CppDistribTest(object): if self.platform == 'linux': return create_docker_jobspec( self.name, - 'tools/dockerfile/distribtest/cpp_%s_%s' % (self.docker_suffix, - self.arch), + 'tools/dockerfile/distribtest/cpp_%s_%s' % + (self.docker_suffix, self.arch), 'test/distrib/cpp/run_distrib_test_%s.sh' % self.testcase, timeout_seconds=45 * 60) elif self.platform == 'windows': From 5207eba9ff30c19abeb923a7e040848177b59c01 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Thu, 5 Sep 2019 16:30:32 -0700 Subject: [PATCH 14/31] Add abseil --- BUILD | 14 +- BUILD.gn | 3 + CMakeLists.txt | 56 ++- Makefile | 324 ++++++++++++------ PYTHON-MANIFEST.in | 1 + bazel/grpc_build_system.bzl | 23 +- build.yaml | 9 +- cmake/abseil-cpp.cmake | 12 + cmake/gRPCConfig.cmake.in | 1 + config.m4 | 34 ++ config.w32 | 36 ++ examples/cpp/helloworld/CMakeLists.txt | 2 + .../cmake_externalproject/CMakeLists.txt | 245 ++++++------- gRPC-C++.podspec | 3 + gRPC-Core.podspec | 3 + grpc.gemspec | 102 ++++++ grpc.gyp | 7 + include/grpc/impl/codegen/port_platform.h | 2 +- package.xml | 102 ++++++ setup.py | 6 +- src/android/test/interop/app/CMakeLists.txt | 1 + src/core/lib/channel/channelz.h | 12 +- src/core/lib/gprpp/optional.h | 16 + src/python/grpcio/grpc_core_dependencies.py | 27 ++ templates/CMakeLists.txt.template | 77 +++-- templates/Makefile.template | 49 ++- templates/config.m4.template | 1 + templates/config.w32.template | 1 + test/distrib/cpp/run_distrib_test_cmake.bat | 8 + test/distrib/cpp/run_distrib_test_cmake.sh | 8 + ...n_distrib_test_cmake_as_externalproject.sh | 1 - .../cpp/run_distrib_test_cmake_pkgconfig.sh | 8 + tools/distrib/python/grpcio_tools/setup.py | 6 +- .../linux/grpc_bazel_build_in_docker.sh | 4 - 34 files changed, 887 insertions(+), 317 deletions(-) diff --git a/BUILD b/BUILD index 27dbd4e514e..a4f583755cd 100644 --- a/BUILD +++ b/BUILD @@ -69,11 +69,6 @@ config_setting( values = {"cpu": "darwin"}, ) -config_setting( - name = "grpc_use_absl", - values = {"define": "GRPC_USE_ABSL=1"}, -) - python_config_settings() # This should be updated along with build.yaml @@ -560,6 +555,9 @@ grpc_cc_library( "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h", ], + external_deps = [ + "absl/strings", + ], language = "c++", public_hdrs = GPR_PUBLIC_HDRS, deps = [ @@ -614,6 +612,9 @@ grpc_cc_library( grpc_cc_library( name = "inlined_vector", + external_deps = [ + "absl/container:inlined_vector", + ], language = "c++", public_hdrs = [ "src/core/lib/gprpp/inlined_vector.h", @@ -631,6 +632,9 @@ grpc_cc_library( grpc_cc_library( name = "optional", + external_deps = [ + "absl/types:optional", + ], language = "c++", public_hdrs = [ "src/core/lib/gprpp/optional.h", diff --git a/BUILD.gn b/BUILD.gn index 5626759924d..e19c197c847 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -158,6 +158,9 @@ config("grpc_config") { "src/core/lib/profiling/timers.h", ] deps = [ + ":absl/container:inlined_vector", + ":absl/strings:strings", + ":absl/types:optional", ] public_configs = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index b6be8766fd3..449ec9c5322 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,38 @@ else() set(gRPC_BENCHMARK_PROVIDER "none") endif() +set(gRPC_ABSL_PROVIDER "module" CACHE STRING "Provider of absl library") +set_property(CACHE gRPC_ABSL_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_ABSL_USED_TARGETS + absl_algorithm + absl_atomic_hook + absl_bad_optional_access + absl_base + absl_base_internal + absl_bits + absl_compressed_tuple + absl_config + absl_core_headers + absl_dynamic_annotations + absl_endian + absl_inlined_vector + absl_inlined_vector_internal + absl_int128 + absl_log_severity + absl_memory + absl_optional + absl_raw_logging_internal + absl_span + absl_spinlock_wait + absl_strings + absl_strings_internal + absl_throw_delegate + absl_type_traits + absl_utility + absl_meta +) + set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library") if(UNIX) @@ -153,6 +185,7 @@ else() set(_gRPC_CORE_NOSTDCXX_FLAGS "") endif() +include(cmake/abseil-cpp.cmake) include(cmake/address_sorting.cmake) include(cmake/benchmark.cmake) include(cmake/cares.cmake) @@ -1052,6 +1085,9 @@ target_include_directories(gpr ) target_link_libraries(gpr ${_gRPC_ALLTARGETS_LIBRARIES} + absl::inlined_vector + absl::strings + absl::optional ) if(_gRPC_PLATFORM_ANDROID) target_link_libraries(gpr @@ -3254,6 +3290,7 @@ target_include_directories(dns_test_util target_link_libraries(dns_test_util ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -5891,15 +5928,6 @@ target_link_libraries(grpc_csharp_ext ) - -if(gRPC_INSTALL) - install(TARGETS grpc_csharp_ext EXPORT gRPCTargets - RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} - LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} - ) -endif() - endif() add_library(upb @@ -18457,7 +18485,7 @@ generate_pkgconfig( "gRPC platform support library" "${gRPC_CORE_VERSION}" "" - "-lgpr" + "-lgpr -labsl_bad_optional_access -labsl_strings -labsl_strings_internal -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_dynamic_annotations -labsl_throw_delegate -labsl_raw_logging_internal -labsl_log_severity" "" "gpr.pc") @@ -18467,7 +18495,7 @@ generate_pkgconfig( "high performance general RPC framework" "${gRPC_CORE_VERSION}" "gpr openssl" - "-lgrpc -laddress_sorting -lupb -lcares -lz" + "-lgrpc -laddress_sorting -lupb -lcares -lz -labsl_bad_optional_access -labsl_strings -labsl_strings_internal -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_dynamic_annotations -labsl_throw_delegate -labsl_raw_logging_internal -labsl_log_severity" "" "grpc.pc") @@ -18477,7 +18505,7 @@ generate_pkgconfig( "high performance general RPC framework without SSL" "${gRPC_CORE_VERSION}" "gpr" - "-lgrpc_unsecure" + "-lgrpc_unsecure -labsl_bad_optional_access -labsl_strings -labsl_strings_internal -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_dynamic_annotations -labsl_throw_delegate -labsl_raw_logging_internal -labsl_log_severity" "" "grpc_unsecure.pc") @@ -18487,7 +18515,7 @@ generate_pkgconfig( "C++ wrapper for gRPC" "${PACKAGE_VERSION}" "grpc" - "-lgrpc++" + "-lgrpc++ -labsl_bad_optional_access -labsl_strings -labsl_strings_internal -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_dynamic_annotations -labsl_throw_delegate -labsl_raw_logging_internal -labsl_log_severity" "" "grpc++.pc") @@ -18497,6 +18525,6 @@ generate_pkgconfig( "C++ wrapper for gRPC without SSL" "${PACKAGE_VERSION}" "grpc_unsecure" - "-lgrpc++_unsecure" + "-lgrpc++_unsecure -labsl_bad_optional_access -labsl_strings -labsl_strings_internal -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_dynamic_annotations -labsl_throw_delegate -labsl_raw_logging_internal -labsl_log_severity" "" "grpc++_unsecure.pc") diff --git a/Makefile b/Makefile index 3522efe847c..bcae905d5d3 100644 --- a/Makefile +++ b/Makefile @@ -363,7 +363,7 @@ CXXFLAGS += -stdlib=libc++ LDFLAGS += -framework CoreFoundation endif CFLAGS += -g -CPPFLAGS += -g -Wall -Wextra -DOSATOMIC_USE_INLINED=1 -Ithird_party/upb -Isrc/core/ext/upb-generated +CPPFLAGS += -g -Wall -Wextra -DOSATOMIC_USE_INLINED=1 -Ithird_party/abseil-cpp -Ithird_party/upb -Isrc/core/ext/upb-generated COREFLAGS += -fno-exceptions LDFLAGS += -g @@ -722,6 +722,9 @@ ADDRESS_SORTING_MERGE_OBJS = $(LIBADDRESS_SORTING_OBJS) ADDRESS_SORTING_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libaddress_sorting.a CPPFLAGS := -Ithird_party/address_sorting/include $(CPPFLAGS) +GRPC_ABSEIL_DEP = $(LIBDIR)/$(CONFIG)/libgrpc_abseil.a +GRPC_ABSEIL_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libgrpc_abseil.a + UPB_DEP = $(LIBDIR)/$(CONFIG)/libupb.a UPB_MERGE_OBJS = $(LIBUPB_OBJS) UPB_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libupb.a @@ -3433,18 +3436,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBADDRESS_SORTING_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) +$(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBADDRESS_SORTING_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else -$(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBADDRESS_SORTING_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) +$(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBADDRESS_SORTING_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.9 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.9 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) $(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.9 $(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so endif @@ -3474,7 +3477,7 @@ $(LIBDIR)/$(CONFIG)/libalts_test_util.a: openssl_dep_error else -$(LIBDIR)/$(CONFIG)/libalts_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBALTS_TEST_UTIL_OBJS) +$(LIBDIR)/$(CONFIG)/libalts_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBALTS_TEST_UTIL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libalts_test_util.a @@ -3573,7 +3576,7 @@ PUBLIC_HEADERS_C += \ LIBGPR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_SRC)))) -$(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGPR_OBJS) +$(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(LIBGPR_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr.a @@ -3585,18 +3588,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) +$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else -$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) +$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.9 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.9 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) $(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.9 $(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so endif @@ -4033,11 +4036,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE else -$(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBGRPC_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc.a endif @@ -4045,18 +4048,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else -$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.9 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.9 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.9 $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so endif @@ -4425,11 +4428,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_E else -$(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_CRONET_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBGRPC_CRONET_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a endif @@ -4437,18 +4440,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else -$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.9 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.9 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) $(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.9 $(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so endif @@ -4776,7 +4779,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a: openssl_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_TEST_UTIL_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBGRPC_TEST_UTIL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a @@ -5095,7 +5098,7 @@ PUBLIC_HEADERS_C += \ LIBGRPC_TEST_UTIL_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_TEST_UTIL_UNSECURE_SRC)))) -$(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a @@ -5451,11 +5454,11 @@ PUBLIC_HEADERS_C += \ LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC)))) -$(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(LIBGRPC_UNSECURE_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a endif @@ -5463,18 +5466,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a +$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else -$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a +$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.9 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.9 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) $(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.9 $(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so endif @@ -5503,7 +5506,7 @@ $(LIBDIR)/$(CONFIG)/libreconnect_server.a: openssl_dep_error else -$(LIBDIR)/$(CONFIG)/libreconnect_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBRECONNECT_SERVER_OBJS) +$(LIBDIR)/$(CONFIG)/libreconnect_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBRECONNECT_SERVER_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libreconnect_server.a @@ -5542,7 +5545,7 @@ $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a: openssl_dep_error else -$(LIBDIR)/$(CONFIG)/libtest_tcp_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBTEST_TCP_SERVER_OBJS) +$(LIBDIR)/$(CONFIG)/libtest_tcp_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBTEST_TCP_SERVER_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a @@ -5591,7 +5594,7 @@ $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS) +$(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a @@ -5641,7 +5644,7 @@ $(LIBDIR)/$(CONFIG)/libdns_test_util.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libdns_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDNS_TEST_UTIL_OBJS) +$(LIBDIR)/$(CONFIG)/libdns_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDNS_TEST_UTIL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libdns_test_util.a @@ -6200,11 +6203,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP else -$(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++.a endif @@ -6212,18 +6215,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll else -$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr -lupb + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr -lupb else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr -lupb + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr -lupb $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so endif @@ -6272,11 +6275,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EX else -$(LIBDIR)/$(CONFIG)/libgrpc++_alts.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_ALTS_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_alts.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_ALTS_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBGRPC++_ALTS_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBGRPC++_ALTS_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a endif @@ -6284,18 +6287,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ALTS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ALTS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll else -$(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ALTS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ALTS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_alts.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_alts.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ $(Q) ln -sf $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).so endif @@ -6339,7 +6342,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_CORE_STATS_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_CORE_STATS_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a @@ -6395,11 +6398,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$( else -$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBGRPC++_ERROR_DETAILS_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBGRPC++_ERROR_DETAILS_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a endif @@ -6407,18 +6410,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll else -$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_error_details.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_error_details.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so endif @@ -6465,7 +6468,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a @@ -6522,7 +6525,7 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHA else -$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a @@ -6534,18 +6537,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll else -$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so endif @@ -6590,7 +6593,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_CONFIG_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_CONFIG_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a @@ -6765,7 +6768,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_UTIL_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_UTIL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a @@ -6945,7 +6948,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_UTIL_UNSECURE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_UTIL_UNSECURE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a @@ -7487,11 +7490,11 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARE else -$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS) $(LIBGPR_OBJS) $(LIBGRPC_ABSEIL_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a endif @@ -7499,18 +7502,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) +$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr$(SHARED_VERSION_CORE)-dll -lgrpc_unsecure$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr$(SHARED_VERSION_CORE)-dll -lgrpc_unsecure$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll else -$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) +$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure -lupb + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure -lupb else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure -lupb + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure -lupb $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so endif @@ -7550,7 +7553,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC_BENCHMARK_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC_BENCHMARK_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a @@ -7606,7 +7609,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC_CLI_LIBS_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC_CLI_LIBS_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a @@ -7659,7 +7662,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a @@ -7710,7 +7713,7 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARE else -$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPCPP_CHANNELZ_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBGRPCPP_CHANNELZ_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a @@ -7722,18 +7725,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll else -$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpcpp_channelz.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpcpp_channelz.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).so.1 $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).so endif @@ -7781,7 +7784,7 @@ $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBHTTP2_CLIENT_MAIN_OBJS) +$(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBHTTP2_CLIENT_MAIN_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a @@ -7832,7 +7835,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libinterop_client_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_HELPER_OBJS) +$(LIBDIR)/$(CONFIG)/libinterop_client_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_HELPER_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a @@ -7886,7 +7889,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_client_main.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libinterop_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_MAIN_OBJS) +$(LIBDIR)/$(CONFIG)/libinterop_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_MAIN_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_main.a @@ -7937,7 +7940,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libinterop_server_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_HELPER_OBJS) +$(LIBDIR)/$(CONFIG)/libinterop_server_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_HELPER_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a @@ -7989,7 +7992,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_LIB_OBJS) +$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_LIB_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a @@ -8039,7 +8042,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_main.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libinterop_server_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_MAIN_OBJS) +$(LIBDIR)/$(CONFIG)/libinterop_server_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_MAIN_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_main.a @@ -8107,7 +8110,7 @@ $(LIBDIR)/$(CONFIG)/libqps.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libqps.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBQPS_OBJS) +$(LIBDIR)/$(CONFIG)/libqps.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBQPS_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libqps.a @@ -8162,7 +8165,7 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SH else -$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_CSHARP_EXT_OBJS) +$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBGRPC_CSHARP_EXT_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a @@ -8174,18 +8177,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else -$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else - $(Q) $(LDXX) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so.2 $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so endif @@ -8474,7 +8477,7 @@ $(LIBBORINGSSL_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=h $(LIBBORINGSSL_OBJS): CXXFLAGS += -fno-exceptions $(LIBBORINGSSL_OBJS): CFLAGS += -g -$(LIBDIR)/$(CONFIG)/libboringssl.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBBORINGSSL_OBJS) +$(LIBDIR)/$(CONFIG)/libboringssl.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(LIBBORINGSSL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl.a @@ -8514,7 +8517,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_TEST_UTIL_OBJS) +$(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_TEST_UTIL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a @@ -8569,7 +8572,7 @@ $(LIBDIR)/$(CONFIG)/libbenchmark.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libbenchmark.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBBENCHMARK_OBJS) +$(LIBDIR)/$(CONFIG)/libbenchmark.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBBENCHMARK_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbenchmark.a @@ -8612,7 +8615,7 @@ $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) else -$(LIBDIR)/$(CONFIG)/libupb.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBUPB_OBJS) +$(LIBDIR)/$(CONFIG)/libupb.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBUPB_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libupb.a @@ -8624,18 +8627,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBUPB_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBUPB_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else -$(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBUPB_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBUPB_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libupb.so.9 -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBS) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libupb.so.9 -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) $(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).so.9 $(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).so endif @@ -8792,7 +8795,7 @@ $(LIBDIR)/$(CONFIG)/libbad_client_test.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBBAD_CLIENT_TEST_OBJS) +$(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBBAD_CLIENT_TEST_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_client_test.a @@ -8833,7 +8836,7 @@ $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a: openssl_dep_error else -$(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBBAD_SSL_TEST_SERVER_OBJS) +$(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBBAD_SSL_TEST_SERVER_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a @@ -8951,7 +8954,7 @@ $(LIBDIR)/$(CONFIG)/libend2end_tests.a: openssl_dep_error else -$(LIBDIR)/$(CONFIG)/libend2end_tests.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBEND2END_TESTS_OBJS) +$(LIBDIR)/$(CONFIG)/libend2end_tests.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBEND2END_TESTS_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_tests.a @@ -9058,7 +9061,7 @@ PUBLIC_HEADERS_C += \ LIBEND2END_NOSEC_TESTS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBEND2END_NOSEC_TESTS_SRC)))) -$(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBEND2END_NOSEC_TESTS_OBJS) +$(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(LIBGRPC_ABSEIL_DEP) $(LIBEND2END_NOSEC_TESTS_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a @@ -9075,6 +9078,72 @@ ifneq ($(NO_DEPS),true) endif +# Add private ABSEIL target which contains all sources used by all baselib libraries. + + +LIBGRPC_ABSEIL_SRC = \ + third_party/abseil-cpp/absl/base/dynamic_annotations.cc \ + third_party/abseil-cpp/absl/base/internal/cycleclock.cc \ + third_party/abseil-cpp/absl/base/internal/raw_logging.cc \ + third_party/abseil-cpp/absl/base/internal/spinlock.cc \ + third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc \ + third_party/abseil-cpp/absl/base/internal/sysinfo.cc \ + third_party/abseil-cpp/absl/base/internal/thread_identity.cc \ + third_party/abseil-cpp/absl/base/internal/throw_delegate.cc \ + third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc \ + third_party/abseil-cpp/absl/base/log_severity.cc \ + third_party/abseil-cpp/absl/numeric/int128.cc \ + third_party/abseil-cpp/absl/strings/ascii.cc \ + third_party/abseil-cpp/absl/strings/charconv.cc \ + third_party/abseil-cpp/absl/strings/escaping.cc \ + third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc \ + third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc \ + third_party/abseil-cpp/absl/strings/internal/memutil.cc \ + third_party/abseil-cpp/absl/strings/internal/ostringstream.cc \ + third_party/abseil-cpp/absl/strings/internal/utf8.cc \ + third_party/abseil-cpp/absl/strings/match.cc \ + third_party/abseil-cpp/absl/strings/numbers.cc \ + third_party/abseil-cpp/absl/strings/str_cat.cc \ + third_party/abseil-cpp/absl/strings/str_replace.cc \ + third_party/abseil-cpp/absl/strings/str_split.cc \ + third_party/abseil-cpp/absl/strings/string_view.cc \ + third_party/abseil-cpp/absl/strings/substitute.cc \ + third_party/abseil-cpp/absl/types/bad_optional_access.cc \ + + +LIBGRPC_ABSEIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_ABSEIL_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libgrpc_abseil.a: openssl_dep_error + + +else + + +$(LIBDIR)/$(CONFIG)/libgrpc_abseil.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBGRPC_ABSEIL_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_abseil.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_abseil.a $(LIBGRPC_ABSEIL_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_abseil.a +endif + + + + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC_ABSEIL_OBJS:.o=.dep) +endif +endif + # All of the test targets, and protoc plugins @@ -23418,6 +23487,33 @@ test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP) test/cpp/util/subprocess.cc: $(OPENSSL_DEP) test/cpp/util/test_config_cc.cc: $(OPENSSL_DEP) test/cpp/util/test_credentials_provider.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/dynamic_annotations.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/internal/cycleclock.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/internal/raw_logging.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/internal/spinlock.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/internal/sysinfo.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/internal/thread_identity.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/internal/throw_delegate.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/base/log_severity.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/numeric/int128.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/ascii.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/charconv.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/escaping.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/internal/memutil.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/internal/ostringstream.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/internal/utf8.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/match.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/numbers.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/str_cat.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/str_replace.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/str_split.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/string_view.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/strings/substitute.cc: $(OPENSSL_DEP) +third_party/abseil-cpp/absl/types/bad_optional_access.cc: $(OPENSSL_DEP) third_party/upb/upb/decode.c: $(OPENSSL_DEP) third_party/upb/upb/encode.c: $(OPENSSL_DEP) third_party/upb/upb/msg.c: $(OPENSSL_DEP) diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in index 003b26a7d36..15bbd201a19 100644 --- a/PYTHON-MANIFEST.in +++ b/PYTHON-MANIFEST.in @@ -4,6 +4,7 @@ graft src/python/grpcio/grpcio.egg-info graft src/core graft src/boringssl graft include/grpc +graft third_party/abseil-cpp/absl graft third_party/address_sorting graft third_party/boringssl graft third_party/cares diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 3064940b01a..0abbc1d401b 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -85,23 +85,6 @@ def grpc_cc_library( if use_cfstream: linkopts = linkopts + if_mac(["-framework CoreFoundation"]) - # This is a temporary solution to enable absl dependency only for - # Bazel-build with grpc_use_absl enabled to abseilfy in-house classes - # such as inlined_vector before absl is fully supported. - # When https://github.com/grpc/grpc/pull/20184 is merged, it will - # be removed. - more_external_deps = [] - if name == "inlined_vector": - more_external_deps += select({ - "//:grpc_use_absl": ["@com_google_absl//absl/container:inlined_vector"], - "//conditions:default": [], - }) - if name == "gpr_base": - more_external_deps += select({ - "//:grpc_use_absl": ["@com_google_absl//absl/strings:strings"], - "//conditions:default": [], - }) - native.cc_library( name = name, srcs = srcs, @@ -117,13 +100,9 @@ def grpc_cc_library( "//:grpc_allow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=1"], "//:grpc_disallow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=0"], "//conditions:default": [], - }) + - select({ - "//:grpc_use_absl": ["GRPC_USE_ABSL=1"], - "//conditions:default": [], }), hdrs = hdrs + public_hdrs, - deps = deps + _get_external_deps(external_deps) + more_external_deps, + deps = deps + _get_external_deps(external_deps), copts = copts, visibility = visibility, testonly = testonly, diff --git a/build.yaml b/build.yaml index 444a862c39a..1f1d52ec88f 100644 --- a/build.yaml +++ b/build.yaml @@ -246,6 +246,10 @@ filegroups: - src/core/lib/gprpp/thd_windows.cc - src/core/lib/profiling/basic_timers.cc - src/core/lib/profiling/stap_timers.cc + deps: + - absl/container:inlined_vector + - absl/strings:strings + - absl/types:optional uses: - gpr_base_headers - name: gpr_base_headers @@ -1848,6 +1852,8 @@ libs: - test/cpp/naming/dns_test_util.h src: - test/cpp/naming/dns_test_util.cc + deps: + - gpr - name: grpc++ build: all language: c++ @@ -6252,7 +6258,8 @@ defaults: global: CFLAGS: -g COREFLAGS: -fno-exceptions - CPPFLAGS: -g -Wall -Wextra -DOSATOMIC_USE_INLINED=1 -Ithird_party/upb -Isrc/core/ext/upb-generated + CPPFLAGS: -g -Wall -Wextra -DOSATOMIC_USE_INLINED=1 -Ithird_party/abseil-cpp -Ithird_party/upb + -Isrc/core/ext/upb-generated LDFLAGS: -g zlib: CFLAGS: -fvisibility=hidden diff --git a/cmake/abseil-cpp.cmake b/cmake/abseil-cpp.cmake index 0730b32424c..078d495417f 100644 --- a/cmake/abseil-cpp.cmake +++ b/cmake/abseil-cpp.cmake @@ -18,9 +18,21 @@ if(gRPC_ABSL_PROVIDER STREQUAL "module") endif() if(EXISTS "${ABSL_ROOT_DIR}/CMakeLists.txt") add_subdirectory(${ABSL_ROOT_DIR} third_party/abseil-cpp) + if(TARGET absl_base) + if(gRPC_INSTALL AND _gRPC_INSTALL_SUPPORTED_FROM_MODULE) + install(TARGETS ${gRPC_ABSL_USED_TARGETS} EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}) + endif() + endif() else() message(WARNING "gRPC_ABSL_PROVIDER is \"module\" but ABSL_ROOT_DIR is wrong") endif() + if(gRPC_INSTALL AND NOT _gRPC_INSTALL_SUPPORTED_FROM_MODULE) + message(WARNING "gRPC_INSTALL will be forced to FALSE because gRPC_ABSL_PROVIDER is \"module\" and CMake version (${CMAKE_VERSION}) is less than 3.13.") + set(gRPC_INSTALL FALSE) + endif() elseif(gRPC_ABSL_PROVIDER STREQUAL "package") # Use "CONFIG" as there is no built-in cmake module for absl. find_package(absl REQUIRED CONFIG) diff --git a/cmake/gRPCConfig.cmake.in b/cmake/gRPCConfig.cmake.in index b03b2ba4084..5bfa73c291e 100644 --- a/cmake/gRPCConfig.cmake.in +++ b/cmake/gRPCConfig.cmake.in @@ -6,6 +6,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/modules) @_gRPC_FIND_PROTOBUF@ @_gRPC_FIND_SSL@ @_gRPC_FIND_CARES@ +@_gRPC_FIND_ABSL@ # Targets include(${CMAKE_CURRENT_LIST_DIR}/gRPCTargets.cmake) diff --git a/config.m4 b/config.m4 index a0418dfefa8..7ff33a3d1dd 100644 --- a/config.m4 +++ b/config.m4 @@ -8,6 +8,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/core/ext/upb-generated) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc) + PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/abseil-cpp) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/address_sorting/include) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/boringssl/include) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/upb) @@ -459,6 +460,33 @@ if test "$PHP_GRPC" != "no"; then src/php/ext/grpc/server.c \ src/php/ext/grpc/server_credentials.c \ src/php/ext/grpc/timeval.c \ + third_party/abseil-cpp/absl/base/dynamic_annotations.cc \ + third_party/abseil-cpp/absl/base/internal/cycleclock.cc \ + third_party/abseil-cpp/absl/base/internal/raw_logging.cc \ + third_party/abseil-cpp/absl/base/internal/spinlock.cc \ + third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc \ + third_party/abseil-cpp/absl/base/internal/sysinfo.cc \ + third_party/abseil-cpp/absl/base/internal/thread_identity.cc \ + third_party/abseil-cpp/absl/base/internal/throw_delegate.cc \ + third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc \ + third_party/abseil-cpp/absl/base/log_severity.cc \ + third_party/abseil-cpp/absl/numeric/int128.cc \ + third_party/abseil-cpp/absl/strings/ascii.cc \ + third_party/abseil-cpp/absl/strings/charconv.cc \ + third_party/abseil-cpp/absl/strings/escaping.cc \ + third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc \ + third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc \ + third_party/abseil-cpp/absl/strings/internal/memutil.cc \ + third_party/abseil-cpp/absl/strings/internal/ostringstream.cc \ + third_party/abseil-cpp/absl/strings/internal/utf8.cc \ + third_party/abseil-cpp/absl/strings/match.cc \ + third_party/abseil-cpp/absl/strings/numbers.cc \ + third_party/abseil-cpp/absl/strings/str_cat.cc \ + third_party/abseil-cpp/absl/strings/str_replace.cc \ + third_party/abseil-cpp/absl/strings/str_split.cc \ + third_party/abseil-cpp/absl/strings/string_view.cc \ + third_party/abseil-cpp/absl/strings/substitute.cc \ + third_party/abseil-cpp/absl/types/bad_optional_access.cc \ third_party/address_sorting/address_sorting.c \ third_party/address_sorting/address_sorting_posix.c \ third_party/address_sorting/address_sorting_windows.c \ @@ -832,6 +860,12 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/alts/zero_copy_frame_protector) PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/ssl/session_cache) PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/base) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/base/internal) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/numeric) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/strings) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/strings/internal) + PHP_ADD_BUILD_DIR($ext_builddir/third_party/abseil-cpp/absl/types) PHP_ADD_BUILD_DIR($ext_builddir/third_party/address_sorting) PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto) PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/asn1) diff --git a/config.w32 b/config.w32 index a2255c308eb..dd1ae1f2290 100644 --- a/config.w32 +++ b/config.w32 @@ -429,6 +429,33 @@ if (PHP_GRPC != "no") { "src\\php\\ext\\grpc\\server.c " + "src\\php\\ext\\grpc\\server_credentials.c " + "src\\php\\ext\\grpc\\timeval.c " + + "third_party\\abseil-cpp\\absl\\base\\dynamic_annotations.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\cycleclock.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\raw_logging.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\spinlock.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\spinlock_wait.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\sysinfo.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\thread_identity.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\throw_delegate.cc " + + "third_party\\abseil-cpp\\absl\\base\\internal\\unscaledcycleclock.cc " + + "third_party\\abseil-cpp\\absl\\base\\log_severity.cc " + + "third_party\\abseil-cpp\\absl\\numeric\\int128.cc " + + "third_party\\abseil-cpp\\absl\\strings\\ascii.cc " + + "third_party\\abseil-cpp\\absl\\strings\\charconv.cc " + + "third_party\\abseil-cpp\\absl\\strings\\escaping.cc " + + "third_party\\abseil-cpp\\absl\\strings\\internal\\charconv_bigint.cc " + + "third_party\\abseil-cpp\\absl\\strings\\internal\\charconv_parse.cc " + + "third_party\\abseil-cpp\\absl\\strings\\internal\\memutil.cc " + + "third_party\\abseil-cpp\\absl\\strings\\internal\\ostringstream.cc " + + "third_party\\abseil-cpp\\absl\\strings\\internal\\utf8.cc " + + "third_party\\abseil-cpp\\absl\\strings\\match.cc " + + "third_party\\abseil-cpp\\absl\\strings\\numbers.cc " + + "third_party\\abseil-cpp\\absl\\strings\\str_cat.cc " + + "third_party\\abseil-cpp\\absl\\strings\\str_replace.cc " + + "third_party\\abseil-cpp\\absl\\strings\\str_split.cc " + + "third_party\\abseil-cpp\\absl\\strings\\string_view.cc " + + "third_party\\abseil-cpp\\absl\\strings\\substitute.cc " + + "third_party\\abseil-cpp\\absl\\types\\bad_optional_access.cc " + "third_party\\address_sorting\\address_sorting.c " + "third_party\\address_sorting\\address_sorting_posix.c " + "third_party\\address_sorting\\address_sorting_windows.c " + @@ -724,6 +751,7 @@ if (PHP_GRPC != "no") { "/I"+configure_module_dirname+"\\include "+ "/I"+configure_module_dirname+"\\src\\core\\ext\\upb-generated "+ "/I"+configure_module_dirname+"\\src\\php\\ext\\grpc "+ + "/I"+configure_module_dirname+"\\third_party\\abseil-cpp "+ "/I"+configure_module_dirname+"\\third_party\\address_sorting\\include "+ "/I"+configure_module_dirname+"\\third_party\\boringssl\\include "+ "/I"+configure_module_dirname+"\\third_party\\upb "+ @@ -858,6 +886,14 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext\\grpc"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\base"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\base\\internal"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\numeric"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\strings"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\strings\\internal"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\abseil-cpp\\absl\\types"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\address_sorting"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto"); diff --git a/examples/cpp/helloworld/CMakeLists.txt b/examples/cpp/helloworld/CMakeLists.txt index e1618bf13f7..b972e270fb5 100644 --- a/examples/cpp/helloworld/CMakeLists.txt +++ b/examples/cpp/helloworld/CMakeLists.txt @@ -27,6 +27,8 @@ else() add_definitions(-D_WIN32_WINNT=0x600) endif() +find_package(Threads REQUIRED) + if(GRPC_AS_SUBMODULE) # One way to build a projects that uses gRPC is to just include the # entire gRPC project tree via "add_subdirectory". diff --git a/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt b/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt index 0d8470a8d68..dd646bf5da5 100644 --- a/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt +++ b/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt @@ -1,116 +1,129 @@ -# Copyright 2018 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. -# -# cmake "superbuild" file for C++ helloworld example. -# This build file demonstrates how to build the helloworld project -# and all its dependencies in a single cmake build (hence "superbuild") -# that is easy to build and maintain. -# cmake's ExternalProject_Add() is used to import all the sub-projects, -# including the "helloworld" project itself. -# See https://blog.kitware.com/cmake-superbuilds-git-submodules/ - -cmake_minimum_required(VERSION 3.5.1) - -# Project -project(HelloWorld-SuperBuild C CXX) - -include(ExternalProject) - -# Builds c-ares project from the git submodule. -# Note: For all external projects, instead of using checked-out code, one could -# specify GIT_REPOSITORY and GIT_TAG to have cmake download the dependency directly, -# without needing to add a submodule to your project. -ExternalProject_Add(c-ares - PREFIX c-ares - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/cares/cares" - CMAKE_CACHE_ARGS - -DCARES_SHARED:BOOL=OFF - -DCARES_STATIC:BOOL=ON - -DCARES_STATIC_PIC:BOOL=ON - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares -) - -# Builds protobuf project from the git submodule. -ExternalProject_Add(protobuf - PREFIX protobuf - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/protobuf/cmake" - CMAKE_CACHE_ARGS - -Dprotobuf_BUILD_TESTS:BOOL=OFF - -Dprotobuf_WITH_ZLIB:BOOL=OFF - -Dprotobuf_MSVC_STATIC_RUNTIME:BOOL=OFF - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/protobuf -) - -# Builds zlib project from the git submodule. -ExternalProject_Add(zlib - PREFIX zlib - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/zlib" - CMAKE_CACHE_ARGS - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/zlib -) - -# the location where protobuf-config.cmake will be installed varies by platform -if (WIN32) - set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf/cmake") -else() - set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf/lib/cmake/protobuf") -endif() - -# if OPENSSL_ROOT_DIR is set, propagate that hint path to the external projects with OpenSSL dependency. -set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "") -if (OPENSSL_ROOT_DIR) - set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}") -endif() - -# Builds gRPC based on locally checked-out sources and set arguments so that all the dependencies -# are correctly located. -ExternalProject_Add(grpc - PREFIX grpc - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../.." - CMAKE_CACHE_ARGS - -DgRPC_INSTALL:BOOL=ON - -DgRPC_BUILD_TESTS:BOOL=OFF - -DgRPC_PROTOBUF_PROVIDER:STRING=package - -DgRPC_PROTOBUF_PACKAGE_TYPE:STRING=CONFIG - -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} - -DgRPC_ZLIB_PROVIDER:STRING=package - -DZLIB_ROOT:STRING=${CMAKE_CURRENT_BINARY_DIR}/zlib - -DgRPC_CARES_PROVIDER:STRING=package - -Dc-ares_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares/lib/cmake/c-ares - -DgRPC_SSL_PROVIDER:STRING=package - ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/grpc - DEPENDS c-ares protobuf zlib -) - -# Build the helloworld projects itself using a CMakeLists.txt that assumes all the dependencies -# have already been installed. -# Even though helloworld is not really an "external project" from perspective of this build, -# we are still importing it using ExternalProject_Add because that allows us to use find_package() -# to locate all the dependencies (if we were building helloworld directly in this build we, -# we would have needed to manually import the libraries as opposed to reusing targets exported by -# gRPC and protobuf). -ExternalProject_Add(helloworld - PREFIX helloworld - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/helloworld" - INSTALL_COMMAND "" - CMAKE_CACHE_ARGS - -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} - -Dc-ares_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares/lib/cmake/c-ares - -DZLIB_ROOT:STRING=${CMAKE_CURRENT_BINARY_DIR}/zlib - ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} - -DgRPC_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/grpc/lib/cmake/grpc - DEPENDS protobuf grpc -) +# Copyright 2018 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. +# +# cmake "superbuild" file for C++ helloworld example. +# This build file demonstrates how to build the helloworld project +# and all its dependencies in a single cmake build (hence "superbuild") +# that is easy to build and maintain. +# cmake's ExternalProject_Add() is used to import all the sub-projects, +# including the "helloworld" project itself. +# See https://blog.kitware.com/cmake-superbuilds-git-submodules/ + +cmake_minimum_required(VERSION 3.5.1) + +# Project +project(HelloWorld-SuperBuild C CXX) + +include(ExternalProject) + +# Note: For all external projects, instead of using checked-out code, one could +# specify GIT_REPOSITORY and GIT_TAG to have cmake download the dependency directly, +# without needing to add a submodule to your project. + +# Builds absl project from the git submodule. +ExternalProject_Add(absl + PREFIX absl + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/abseil-cpp" + CMAKE_CACHE_ARGS + -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=TRUE + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/absl +) + +# Builds c-ares project from the git submodule. +ExternalProject_Add(c-ares + PREFIX c-ares + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/cares/cares" + CMAKE_CACHE_ARGS + -DCARES_SHARED:BOOL=OFF + -DCARES_STATIC:BOOL=ON + -DCARES_STATIC_PIC:BOOL=ON + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares +) + +# Builds protobuf project from the git submodule. +ExternalProject_Add(protobuf + PREFIX protobuf + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/protobuf/cmake" + CMAKE_CACHE_ARGS + -Dprotobuf_BUILD_TESTS:BOOL=OFF + -Dprotobuf_WITH_ZLIB:BOOL=OFF + -Dprotobuf_MSVC_STATIC_RUNTIME:BOOL=OFF + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/protobuf +) + +# Builds zlib project from the git submodule. +ExternalProject_Add(zlib + PREFIX zlib + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/zlib" + CMAKE_CACHE_ARGS + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/zlib +) + +# the location where protobuf-config.cmake will be installed varies by platform +if (WIN32) + set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf/cmake") +else() + set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf/lib/cmake/protobuf") +endif() + +# if OPENSSL_ROOT_DIR is set, propagate that hint path to the external projects with OpenSSL dependency. +set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "") +if (OPENSSL_ROOT_DIR) + set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}") +endif() + +# Builds gRPC based on locally checked-out sources and set arguments so that all the dependencies +# are correctly located. +ExternalProject_Add(grpc + PREFIX grpc + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../.." + CMAKE_CACHE_ARGS + -DgRPC_INSTALL:BOOL=ON + -DgRPC_BUILD_TESTS:BOOL=OFF + -DgRPC_PROTOBUF_PROVIDER:STRING=package + -DgRPC_PROTOBUF_PACKAGE_TYPE:STRING=CONFIG + -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} + -DgRPC_ZLIB_PROVIDER:STRING=package + -DZLIB_ROOT:STRING=${CMAKE_CURRENT_BINARY_DIR}/zlib + -DgRPC_ABSL_PROVIDER:STRING=package + -Dabsl_DIR:STRING=${CMAKE_CURRENT_BINARY_DIR}/absl/lib/cmake/absl + -DgRPC_CARES_PROVIDER:STRING=package + -Dc-ares_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares/lib/cmake/c-ares + -DgRPC_SSL_PROVIDER:STRING=package + ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/grpc + DEPENDS c-ares protobuf zlib absl +) + +# Build the helloworld projects itself using a CMakeLists.txt that assumes all the dependencies +# have already been installed. +# Even though helloworld is not really an "external project" from perspective of this build, +# we are still importing it using ExternalProject_Add because that allows us to use find_package() +# to locate all the dependencies (if we were building helloworld directly in this build we, +# we would have needed to manually import the libraries as opposed to reusing targets exported by +# gRPC and protobuf). +ExternalProject_Add(helloworld + PREFIX helloworld + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/helloworld" + INSTALL_COMMAND "" + CMAKE_CACHE_ARGS + -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} + -Dc-ares_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares/lib/cmake/c-ares + -DZLIB_ROOT:STRING=${CMAKE_CURRENT_BINARY_DIR}/zlib + -Dabsl_DIR:STRING=${CMAKE_CURRENT_BINARY_DIR}/absl/lib/cmake/absl + ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} + -DgRPC_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/grpc/lib/cmake/grpc + DEPENDS protobuf grpc +) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 815e0b6edcf..5bc0b71bb9e 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -214,6 +214,9 @@ Pod::Spec.new do |s| ss.dependency "#{s.name}/Interface", version ss.dependency 'gRPC-Core', version abseil_version = '0.20190808.1' + ss.dependency 'abseil/container/inlined_vector', abseil_version + ss.dependency 'abseil/strings/strings', abseil_version + ss.dependency 'abseil/types/optional', abseil_version ss.source_files = 'include/grpcpp/impl/codegen/core_codegen.h', 'src/core/ext/filters/client_channel/backend_metric.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 61382dc8c14..cfb7617214f 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -172,6 +172,9 @@ Pod::Spec.new do |s| ss.dependency "#{s.name}/Interface", version ss.dependency 'BoringSSL-GRPC', '0.0.5' abseil_version = '0.20190808.1' + ss.dependency 'abseil/container/inlined_vector', abseil_version + ss.dependency 'abseil/strings/strings', abseil_version + ss.dependency 'abseil/types/optional', abseil_version ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' ss.source_files = 'src/core/ext/filters/census/grpc_context.cc', diff --git a/grpc.gemspec b/grpc.gemspec index 90a3aaeab76..1a1309fbacf 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -865,6 +865,108 @@ Gem::Specification.new do |s| s.files += %w( src/core/tsi/transport_security_grpc.cc ) s.files += %w( src/core/tsi/transport_security_grpc.h ) s.files += %w( src/core/tsi/transport_security_interface.h ) + s.files += %w( third_party/abseil-cpp/absl/algorithm/algorithm.h ) + s.files += %w( third_party/abseil-cpp/absl/base/attributes.h ) + s.files += %w( third_party/abseil-cpp/absl/base/call_once.h ) + s.files += %w( third_party/abseil-cpp/absl/base/casts.h ) + s.files += %w( third_party/abseil-cpp/absl/base/config.h ) + s.files += %w( third_party/abseil-cpp/absl/base/const_init.h ) + s.files += %w( third_party/abseil-cpp/absl/base/dynamic_annotations.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/dynamic_annotations.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/atomic_hook.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/bits.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/cycleclock.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/cycleclock.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/endian.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/hide_ptr.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/identity.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/inline_variable.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/invoke.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/per_thread_tls.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/raw_logging.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/raw_logging.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/scheduling_mode.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/spinlock.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/spinlock.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/spinlock_linux.inc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/spinlock_wait.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/sysinfo.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/sysinfo.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/thread_annotations.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/thread_identity.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/thread_identity.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/throw_delegate.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/throw_delegate.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/unaligned_access.h ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h ) + s.files += %w( third_party/abseil-cpp/absl/base/log_severity.cc ) + s.files += %w( third_party/abseil-cpp/absl/base/log_severity.h ) + s.files += %w( third_party/abseil-cpp/absl/base/macros.h ) + s.files += %w( third_party/abseil-cpp/absl/base/optimization.h ) + s.files += %w( third_party/abseil-cpp/absl/base/options.h ) + s.files += %w( third_party/abseil-cpp/absl/base/policy_checks.h ) + s.files += %w( third_party/abseil-cpp/absl/base/port.h ) + s.files += %w( third_party/abseil-cpp/absl/base/thread_annotations.h ) + s.files += %w( third_party/abseil-cpp/absl/container/inlined_vector.h ) + s.files += %w( third_party/abseil-cpp/absl/container/internal/compressed_tuple.h ) + s.files += %w( third_party/abseil-cpp/absl/container/internal/inlined_vector.h ) + s.files += %w( third_party/abseil-cpp/absl/memory/memory.h ) + s.files += %w( third_party/abseil-cpp/absl/meta/type_traits.h ) + s.files += %w( third_party/abseil-cpp/absl/numeric/int128.cc ) + s.files += %w( third_party/abseil-cpp/absl/numeric/int128.h ) + s.files += %w( third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc ) + s.files += %w( third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc ) + s.files += %w( third_party/abseil-cpp/absl/strings/ascii.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/ascii.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/charconv.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/charconv.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/escaping.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/escaping.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/char_map.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/charconv_parse.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/memutil.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/memutil.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/ostringstream.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/ostringstream.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/str_join_internal.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/str_split_internal.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/utf8.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/internal/utf8.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/match.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/match.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/numbers.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/numbers.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/str_cat.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/str_cat.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/str_join.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/str_replace.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/str_replace.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/str_split.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/str_split.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/string_view.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/string_view.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/strip.h ) + s.files += %w( third_party/abseil-cpp/absl/strings/substitute.cc ) + s.files += %w( third_party/abseil-cpp/absl/strings/substitute.h ) + s.files += %w( third_party/abseil-cpp/absl/types/bad_optional_access.cc ) + s.files += %w( third_party/abseil-cpp/absl/types/bad_optional_access.h ) + s.files += %w( third_party/abseil-cpp/absl/types/internal/optional.h ) + s.files += %w( third_party/abseil-cpp/absl/types/internal/span.h ) + s.files += %w( third_party/abseil-cpp/absl/types/optional.h ) + s.files += %w( third_party/abseil-cpp/absl/types/span.h ) + s.files += %w( third_party/abseil-cpp/absl/utility/utility.h ) s.files += %w( third_party/address_sorting/address_sorting.c ) s.files += %w( third_party/address_sorting/address_sorting_internal.h ) s.files += %w( third_party/address_sorting/address_sorting_posix.c ) diff --git a/grpc.gyp b/grpc.gyp index 3568105522b..50765975510 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -55,6 +55,7 @@ '-Wall', '-Wextra', '-DOSATOMIC_USE_INLINED=1', + '-Ithird_party/abseil-cpp', '-Ithird_party/upb', '-Isrc/core/ext/upb-generated', ], @@ -131,6 +132,7 @@ '-Wall', '-Wextra', '-DOSATOMIC_USE_INLINED=1', + '-Ithird_party/abseil-cpp', '-Ithird_party/upb', '-Isrc/core/ext/upb-generated', ], @@ -139,6 +141,7 @@ '-Wall', '-Wextra', '-DOSATOMIC_USE_INLINED=1', + '-Ithird_party/abseil-cpp', '-Ithird_party/upb', '-Isrc/core/ext/upb-generated', '-stdlib=libc++', @@ -176,6 +179,9 @@ 'target_name': 'gpr', 'type': 'static_library', 'dependencies': [ + 'absl/container:inlined_vector', + 'absl/strings:strings', + 'absl/types:optional', ], 'sources': [ 'src/core/lib/gpr/alloc.cc', @@ -1487,6 +1493,7 @@ 'target_name': 'dns_test_util', 'type': 'static_library', 'dependencies': [ + 'gpr', ], 'sources': [ 'test/cpp/naming/dns_test_util.cc', diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 2973b94f9ef..98b516b625d 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -31,7 +31,7 @@ * Defines GRPC_USE_ABSL to use Abseil Common Libraries (C++) */ #ifndef GRPC_USE_ABSL -#define GRPC_USE_ABSL 0 +#define GRPC_USE_ABSL 1 #endif /* Get windows.h included everywhere (we need it) */ diff --git a/package.xml b/package.xml index 4edb5782712..7c8ec5556aa 100644 --- a/package.xml +++ b/package.xml @@ -870,6 +870,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/setup.py b/setup.py index dfd57a0a6d3..e950057fb28 100644 --- a/setup.py +++ b/setup.py @@ -38,6 +38,7 @@ egg_info.manifest_maker.template = 'PYTHON-MANIFEST.in' PY3 = sys.version_info.major == 3 PYTHON_STEM = os.path.join('src', 'python', 'grpcio') CORE_INCLUDE = ('include', '.',) +ABSL_INCLUDE = (os.path.join('third_party', 'abseil-cpp'),) ADDRESS_SORTING_INCLUDE = (os.path.join('third_party', 'address_sorting', 'include'),) CARES_INCLUDE = ( os.path.join('third_party', 'cares'), @@ -191,11 +192,9 @@ if EXTRA_ENV_LINK_ARGS is None: EXTRA_ENV_LINK_ARGS += ' -latomic' elif "win32" in sys.platform and sys.version_info < (3, 5): msvcr = cygwinccompiler.get_msvcr()[0] - # TODO(atash) sift through the GCC specs to see if libstdc++ can have any - # influence on the linkage outcome on MinGW for non-C++ programs. EXTRA_ENV_LINK_ARGS += ( ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr}' - ' -static'.format(msvcr=msvcr)) + ' -static -lshlwapi'.format(msvcr=msvcr)) if "linux" in sys.platform: EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy -static-libgcc' @@ -228,6 +227,7 @@ if BUILD_WITH_SYSTEM_CARES: EXTENSION_INCLUDE_DIRECTORIES = ( (PYTHON_STEM,) + CORE_INCLUDE + + ABSL_INCLUDE + ADDRESS_SORTING_INCLUDE + CARES_INCLUDE + SSL_INCLUDE + diff --git a/src/android/test/interop/app/CMakeLists.txt b/src/android/test/interop/app/CMakeLists.txt index 092995fe887..2e23a7759c5 100644 --- a/src/android/test/interop/app/CMakeLists.txt +++ b/src/android/test/interop/app/CMakeLists.txt @@ -14,6 +14,7 @@ add_subdirectory(${GRPC_SRC_DIR} ${GRPC_BUILD_DIR}) #include_directories(${GRPC_SRC_DIR}/include) include_directories(${GRPC_SRC_DIR}) +include_directories(${_gRPC_ABSL_INCLUDE_DIR}) set(GRPC_PROTO_GENS_DIR ${CMAKE_BINARY_DIR}/gens) file(MAKE_DIRECTORY ${GRPC_PROTO_GENS_DIR}) diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 238b48873fa..3b3639e55b7 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -148,7 +148,17 @@ class CallCountingHelper { // Make sure the size is exactly one cache line. uint8_t padding[GPR_CACHELINE_SIZE - 3 * sizeof(Atomic) - sizeof(Atomic)]; - } GPR_ALIGN_STRUCT(GPR_CACHELINE_SIZE); + } +#if GRPC_USE_ABSL + // TODO(soheilhy,veblush): Revist this after abseil integration. + // This has a problem when using abseil inlined_vector because it + // carries an alignment attribute properly but our allocator doesn't + // respect this. To avoid UBSAN errors, this should be removed with + // abseil inlined_vector. + ; +#else + GPR_ALIGN_STRUCT(GPR_CACHELINE_SIZE); +#endif struct CounterData { int64_t calls_started = 0; diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index e72ac60a0aa..a1b54666c6a 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -21,6 +21,20 @@ #include +// TODO(yashykt): Remove false once migration to abseil is done. +#if false && GRPC_USE_ABSL + +#include "absl/types/optional.h" + +namespace grpc_core { + +template +using Optional = absl::optional; + +} // namespace grpc_core + +#else + #include namespace grpc_core { @@ -55,4 +69,6 @@ class Optional { } /* namespace grpc_core */ +#endif + #endif /* GRPC_CORE_LIB_GPRPP_OPTIONAL_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 172d833dde1..42854c5e103 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -428,6 +428,33 @@ CORE_SOURCE_FILES = [ 'src/core/tsi/ssl_transport_security.cc', 'src/core/tsi/transport_security.cc', 'src/core/tsi/transport_security_grpc.cc', + 'third_party/abseil-cpp/absl/base/dynamic_annotations.cc', + 'third_party/abseil-cpp/absl/base/internal/cycleclock.cc', + 'third_party/abseil-cpp/absl/base/internal/raw_logging.cc', + 'third_party/abseil-cpp/absl/base/internal/spinlock.cc', + 'third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc', + 'third_party/abseil-cpp/absl/base/internal/sysinfo.cc', + 'third_party/abseil-cpp/absl/base/internal/thread_identity.cc', + 'third_party/abseil-cpp/absl/base/internal/throw_delegate.cc', + 'third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc', + 'third_party/abseil-cpp/absl/base/log_severity.cc', + 'third_party/abseil-cpp/absl/numeric/int128.cc', + 'third_party/abseil-cpp/absl/strings/ascii.cc', + 'third_party/abseil-cpp/absl/strings/charconv.cc', + 'third_party/abseil-cpp/absl/strings/escaping.cc', + 'third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc', + 'third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc', + 'third_party/abseil-cpp/absl/strings/internal/memutil.cc', + 'third_party/abseil-cpp/absl/strings/internal/ostringstream.cc', + 'third_party/abseil-cpp/absl/strings/internal/utf8.cc', + 'third_party/abseil-cpp/absl/strings/match.cc', + 'third_party/abseil-cpp/absl/strings/numbers.cc', + 'third_party/abseil-cpp/absl/strings/str_cat.cc', + 'third_party/abseil-cpp/absl/strings/str_replace.cc', + 'third_party/abseil-cpp/absl/strings/str_split.cc', + 'third_party/abseil-cpp/absl/strings/string_view.cc', + 'third_party/abseil-cpp/absl/strings/substitute.cc', + 'third_party/abseil-cpp/absl/types/bad_optional_access.cc', 'third_party/address_sorting/address_sorting.c', 'third_party/address_sorting/address_sorting_posix.c', 'third_party/address_sorting/address_sorting_windows.c', diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 303f4a88961..7c6823b352d 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -21,11 +21,11 @@ # See the License for the specific language governing permissions and # limitations under the License. - <%! - + <% import re proto_re = re.compile('(.*)\\.proto') + lib_map = {lib.name: lib for lib in libs} def proto_replace_ext(filename, ext): m = proto_re.match(filename) @@ -33,8 +33,19 @@ return filename return '${_gRPC_PROTO_GENS_DIR}/' + m.group(1) + ext - def is_absl_lib(target_name): - return target_name.startswith("absl/"); + def is_absl_lib(lib_name): + return lib_name.startswith("absl/"); + + def get_absl_dep(lib_name): + return lib_map[lib_name].cmake_target + + def list_absl_lib_files_for(lib_name): + ret = [] + lib = lib_map[lib_name] + for dep in lib.transitive_deps: + if is_absl_lib(dep) and len(lib_map[dep].src) > 0: + ret.append(get_absl_dep(dep).replace("::", "_")) + return ret def get_deps(target_dict): deps = [] @@ -55,6 +66,8 @@ for d in target_dict.get('deps', []): if d == 'benchmark': deps.append("${_gRPC_BENCHMARK_LIBRARIES}") + elif is_absl_lib(d): + deps.append(get_absl_dep(d)) else: deps.append(d) if (target_dict.build == 'test' or target_dict.build == 'private') and target_dict.language == 'c++': @@ -192,6 +205,24 @@ set(gRPC_BENCHMARK_PROVIDER "none") endif() + set(gRPC_ABSL_PROVIDER "module" CACHE STRING "Provider of absl library") + set_property(CACHE gRPC_ABSL_PROVIDER PROPERTY STRINGS "module" "package") + <% + # Collect all abseil rules used by gpr, grpc, so on. + used_abseil_rules = set() + for lib in libs: + if lib.get("baselib"): + for dep in lib.transitive_deps: + if is_absl_lib(dep): + used_abseil_rules.add(lib_map[dep].cmake_target.replace("::", "_")) + %> + set(gRPC_ABSL_USED_TARGETS + % for rule in sorted(used_abseil_rules): + ${rule} + % endfor + absl_meta + ) + set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library") if(UNIX) @@ -251,6 +282,7 @@ set(_gRPC_CORE_NOSTDCXX_FLAGS "") endif() + include(cmake/abseil-cpp.cmake) include(cmake/address_sorting.cmake) include(cmake/benchmark.cmake) include(cmake/cares.cmake) @@ -408,33 +440,26 @@ cmake_libs.append(lib) %> % for lib in cmake_libs: - % if lib.build in ["test", "private"]: + % if lib.build in ["test", "private"]: if(gRPC_BUILD_TESTS) ${cc_library(lib)} endif() - % elif lib.name in ['grpc_csharp_ext']: + % elif lib.name in ['grpc_csharp_ext']: if(gRPC_BUILD_CSHARP_EXT) ${cc_library(lib)} - % if any(proto_re.match(src) for src in lib.src): - if(gRPC_BUILD_CODEGEN) - % endif - ${cc_install(lib)} - % if any(proto_re.match(src) for src in lib.src): endif() - % endif - endif() - % else: + % else: ${cc_library(lib)} - % if not lib.build in ["tool"]: - % if any(proto_re.match(src) for src in lib.src): + % if not lib.build in ["tool"]: + % if any(proto_re.match(src) for src in lib.src): if(gRPC_BUILD_CODEGEN) - % endif + % endif ${cc_install(lib)} - % if any(proto_re.match(src) for src in lib.src): + % if any(proto_re.match(src) for src in lib.src): endif() - % endif - % endif - % endif + % endif + % endif + % endif % endfor % for tgt in targets: @@ -684,7 +709,7 @@ "gRPC platform support library" "<%text>${gRPC_CORE_VERSION}" "" - "-lgpr" + "${" ".join(("-l" + l) for l in ["gpr",] + list_absl_lib_files_for("gpr"))}" "" "gpr.pc") @@ -694,7 +719,7 @@ "high performance general RPC framework" "<%text>${gRPC_CORE_VERSION}" "gpr openssl" - "-lgrpc -laddress_sorting -lupb -lcares -lz" + "${" ".join(("-l" + l) for l in ["grpc", "address_sorting", "upb", "cares", "z"] + list_absl_lib_files_for("grpc"))}" "" "grpc.pc") @@ -704,7 +729,7 @@ "high performance general RPC framework without SSL" "<%text>${gRPC_CORE_VERSION}" "gpr" - "-lgrpc_unsecure" + "${" ".join(("-l" + l) for l in ["grpc_unsecure",] + list_absl_lib_files_for("grpc_unsecure"))}" "" "grpc_unsecure.pc") @@ -714,7 +739,7 @@ "C++ wrapper for gRPC" "<%text>${PACKAGE_VERSION}" "grpc" - "-lgrpc++" + "${" ".join(("-l" + l) for l in ["grpc++",] + list_absl_lib_files_for("grpc++"))}" "" "grpc++.pc") @@ -724,6 +749,6 @@ "C++ wrapper for gRPC without SSL" "<%text>${PACKAGE_VERSION}" "grpc_unsecure" - "-lgrpc++_unsecure" + "${" ".join(("-l" + l) for l in ["grpc++_unsecure",] + list_absl_lib_files_for("grpc++_unsecure"))}" "" "grpc++_unsecure.pc") diff --git a/templates/Makefile.template b/templates/Makefile.template index 8063bd47710..8372d00ae69 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -24,6 +24,9 @@ import re import os + def is_absl_lib(target_name): + return target_name.startswith("absl/"); + proto_re = re.compile('(.*)\\.proto') def proto_to_cc(filename): @@ -613,6 +616,9 @@ ADDRESS_SORTING_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libaddress_sorting.a CPPFLAGS := -Ithird_party/address_sorting/include $(CPPFLAGS) + GRPC_ABSEIL_DEP = $(LIBDIR)/$(CONFIG)/libgrpc_abseil.a + GRPC_ABSEIL_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libgrpc_abseil.a + UPB_DEP = $(LIBDIR)/$(CONFIG)/libupb.a UPB_MERGE_OBJS = $(LIBUPB_OBJS) UPB_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libupb.a @@ -1466,6 +1472,32 @@ % endif % endfor + # Add private ABSEIL target which contains all sources used by all baselib libraries. + <% + # Collect all abseil source and header files used by gpr, grpc, so on. + used_abseil_rules = set() + for lib in libs: + if lib.get("baselib"): + for dep in lib.transitive_deps: + if is_absl_lib(dep): + used_abseil_rules.add(dep) + used_abseil_srcs = [] + used_abseil_hdrs = [] + for lib in libs: + if lib.name in used_abseil_rules: + used_abseil_srcs.extend(lib.get("src", [])) + used_abseil_hdrs.extend(lib.get("hdr", [])) + # Create `grpc_abseil` rule with collected files. + lib_type = type(libs[0]) + grpc_abseil_lib = lib_type({ + "name": "grpc_abseil", + "build": "private", + "language": "c", + "src": sorted(used_abseil_srcs), + "hdr": sorted(used_abseil_hdrs), + }) + %> + ${makelib(grpc_abseil_lib)} # All of the test targets, and protoc plugins @@ -1531,7 +1563,7 @@ else % endif - $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) \ + $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) \ ## The else here corresponds to the if secure earlier. % else: % if lib.language == 'c++': @@ -1549,11 +1581,12 @@ % endif $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: \ - % if lib.name not in ['z', 'ares', 'address_sorting', 'upb']: + % if lib.name not in ['z', 'ares', 'address_sorting', 'upb', 'grpc_abseil']: $(ZLIB_DEP) \ $(CARES_DEP) \ $(ADDRESS_SORTING_DEP) \ $(UPB_DEP) \ + $(LIBGRPC_ABSEIL_DEP) \ % endif % endif % if lib.language == 'c++': @@ -1562,6 +1595,7 @@ $(LIB${lib.name.upper()}_OBJS) \ % if lib.get('baselib', False): $(LIBGPR_OBJS) \ + $(LIBGRPC_ABSEIL_OBJS) \ $(ZLIB_MERGE_OBJS) \ $(CARES_MERGE_OBJS) \ $(ADDRESS_SORTING_MERGE_OBJS) \ @@ -1577,6 +1611,7 @@ $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS) \ % if lib.get('baselib', False): $(LIBGPR_OBJS) \ + $(LIBGRPC_ABSEIL_OBJS) \ $(ZLIB_MERGE_OBJS) \ $(CARES_MERGE_OBJS) \ $(ADDRESS_SORTING_MERGE_OBJS) \ @@ -1603,20 +1638,22 @@ common = '$(LIB' + lib.name.upper() + '_OBJS)' link_libs = '' - lib_deps = ' $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP)' + lib_deps = ' $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)' mingw_libs = '' - mingw_lib_deps = ' $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP)' + mingw_lib_deps = ' $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)' if lib.language == 'c++': lib_deps += ' $(PROTOBUF_DEP)' mingw_lib_deps += ' $(PROTOBUF_DEP)' if lib.get('deps_linkage', None) == 'static': for dep in lib.get('deps', []): + if is_absl_lib(dep): continue lib_archive = '$(LIBDIR)/$(CONFIG)/lib' + dep + '.a' common = common + ' ' + lib_archive lib_deps = lib_deps + ' ' + lib_archive mingw_lib_deps = mingw_lib_deps + ' ' + lib_archive else: for dep in lib.get('deps', []): + if is_absl_lib(dep): continue dep_lib = None for dl in libs: if dl.name == dep: @@ -1630,7 +1667,7 @@ security = lib.get('secure', 'check') if security == True: common = common + ' $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE)' - common = common + ' $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS)' + common = common + ' $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS)' if security in [True, 'check']: for src in lib.src: @@ -1764,7 +1801,9 @@ % endif % endif % for dep in tgt.deps: + % if not is_absl_lib(dep): $(LIBDIR)/$(CONFIG)/lib${dep}.a\ + % endif % endfor % if tgt.language == "c++" or tgt.boringssl or tgt.build == 'fuzzer': diff --git a/templates/config.m4.template b/templates/config.m4.template index d5ffa0a94b6..071d29c4f57 100644 --- a/templates/config.m4.template +++ b/templates/config.m4.template @@ -10,6 +10,7 @@ PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/core/ext/upb-generated) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc) + PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/abseil-cpp) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/address_sorting/include) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/boringssl/include) PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/upb) diff --git a/templates/config.w32.template b/templates/config.w32.template index 6661bcbd707..f69cc08df65 100644 --- a/templates/config.w32.template +++ b/templates/config.w32.template @@ -31,6 +31,7 @@ "/I"+configure_module_dirname+"\\include "+ "/I"+configure_module_dirname+"\\src\\core\\ext\\upb-generated "+ "/I"+configure_module_dirname+"\\src\\php\\ext\\grpc "+ + "/I"+configure_module_dirname+"\\third_party\\abseil-cpp "+ "/I"+configure_module_dirname+"\\third_party\\address_sorting\\include "+ "/I"+configure_module_dirname+"\\third_party\\boringssl\\include "+ "/I"+configure_module_dirname+"\\third_party\\upb "+ diff --git a/test/distrib/cpp/run_distrib_test_cmake.bat b/test/distrib/cpp/run_distrib_test_cmake.bat index 48d510100e2..184d4ce6fa6 100644 --- a/test/distrib/cpp/run_distrib_test_cmake.bat +++ b/test/distrib/cpp/run_distrib_test_cmake.bat @@ -29,6 +29,13 @@ powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [Sys @rem set absolute path to OpenSSL with forward slashes set OPENSSL_DIR=%cd:\=/%/OpenSSL-Win32 +@rem Install absl +mkdir third_party\abseil-cpp\cmake\build +pushd third_party\abseil-cpp\cmake\build +cmake -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% ..\.. +cmake --build . --config Release --target install || goto :error +popd + @rem Install c-ares mkdir third_party\cares\cares\cmake\build pushd third_party\cares\cares\cmake\build @@ -64,6 +71,7 @@ cmake ^ -DZLIB_ROOT=%INSTALL_DIR% ^ -DgRPC_INSTALL=ON ^ -DgRPC_BUILD_TESTS=OFF ^ + -DgRPC_ABSL_PROVIDER=package ^ -DgRPC_CARES_PROVIDER=package ^ -DgRPC_PROTOBUF_PROVIDER=package ^ -DgRPC_SSL_PROVIDER=package ^ diff --git a/test/distrib/cpp/run_distrib_test_cmake.sh b/test/distrib/cpp/run_distrib_test_cmake.sh index 59bbda7724b..6e2fb790f19 100755 --- a/test/distrib/cpp/run_distrib_test_cmake.sh +++ b/test/distrib/cpp/run_distrib_test_cmake.sh @@ -23,6 +23,13 @@ sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sou apt-get update apt-get install -t jessie-backports -y libssl-dev +# Install absl +mkdir -p "third_party/abseil-cpp/cmake/build" +pushd "third_party/abseil-cpp/cmake/build" +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE ../.. +make -j4 install +popd + # Install c-ares # If the distribution provides a new-enough version of c-ares, # this section can be replaced with: @@ -60,6 +67,7 @@ cmake \ -DgRPC_INSTALL=ON \ -DgRPC_BUILD_TESTS=OFF \ -DgRPC_CARES_PROVIDER=package \ + -DgRPC_ABSL_PROVIDER=package \ -DgRPC_PROTOBUF_PROVIDER=package \ -DgRPC_SSL_PROVIDER=package \ -DgRPC_ZLIB_PROVIDER=package \ diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh index ee1e0e8337d..f9fa409da4f 100755 --- a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh +++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh @@ -26,7 +26,6 @@ apt-get install -t jessie-backports -y libssl-dev # To increase the confidence that gRPC installation works without depending on # too many submodules unnecessarily, just wipe out contents of most submodules # before starting the test. -rm -r third_party/abseil-cpp/* || true rm -r third_party/benchmark/* || true rm -r third_party/bloaty/* || true rm -r third_party/boringssl/* || true diff --git a/test/distrib/cpp/run_distrib_test_cmake_pkgconfig.sh b/test/distrib/cpp/run_distrib_test_cmake_pkgconfig.sh index 6f98f3e72c4..68e5391f8e5 100755 --- a/test/distrib/cpp/run_distrib_test_cmake_pkgconfig.sh +++ b/test/distrib/cpp/run_distrib_test_cmake_pkgconfig.sh @@ -23,6 +23,13 @@ sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sou apt-get update apt-get install -t jessie-backports -y libssl-dev pkg-config +# Install absl +mkdir -p "third_party/abseil-cpp/cmake/build" +pushd "third_party/abseil-cpp/cmake/build" +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE ../.. +make -j4 install +popd + # Install c-ares mkdir -p "third_party/cares/cares/cmake/build" pushd "third_party/cares/cares/cmake/build" @@ -57,6 +64,7 @@ cmake \ -DCMAKE_INSTALL_PREFIX=/usr/local/grpc \ -DgRPC_INSTALL=ON \ -DgRPC_BUILD_TESTS=OFF \ + -DgRPC_ABSL_PROVIDER=package \ -DgRPC_CARES_PROVIDER=package \ -DgRPC_PROTOBUF_PROVIDER=package \ -DgRPC_SSL_PROVIDER=package \ diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index 106d72e0653..90347b529ad 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -113,11 +113,9 @@ if EXTRA_ENV_LINK_ARGS is None: EXTRA_ENV_LINK_ARGS += ' -latomic' elif "win32" in sys.platform and sys.version_info < (3, 5): msvcr = cygwinccompiler.get_msvcr()[0] - # TODO(atash) sift through the GCC specs to see if libstdc++ can have any - # influence on the linkage outcome on MinGW for non-C++ programs. EXTRA_ENV_LINK_ARGS += ( - ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr} ' - '-static'.format(msvcr=msvcr)) + ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr}' + ' -static -lshlwapi'.format(msvcr=msvcr)) EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS) EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS) diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index b7e47920653..24598f43f02 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -25,7 +25,3 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc ${name}') cd /var/local/git/grpc bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... - -# This is a temporary build test before full absl support is done -# with https://github.com/grpc/grpc/pull/20918. -bazel build --spawn_strategy=standalone --genrule_strategy=standalone --define=GRPC_USE_ABSL=1 :grpc From e52081f9035606050e4bcb6771e859ab2132892b Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Fri, 3 Jan 2020 20:57:57 -0800 Subject: [PATCH 15/31] More pythons to be formatted --- .yapfignore | 30 + src/abseil-cpp/gen_build_yaml.py | 6 +- src/benchmark/gen_build_yaml.py | 27 +- src/boringssl/gen_build_yaml.py | 198 ++--- src/c-ares/gen_build_yaml.py | 228 ++--- src/objective-c/change-comments.py | 121 ++- src/proto/gen_build_yaml.py | 97 ++- src/upb/gen_build_yaml.py | 54 +- src/zlib/gen_build_yaml.py | 58 +- test/core/bad_client/gen_build_yaml.py | 67 +- test/core/bad_ssl/gen_build_yaml.py | 91 +- ..._client_examples_of_bad_closing_streams.py | 20 +- test/core/end2end/gen_build_yaml.py | 805 ++++++++++-------- test/core/http/test_server.py | 47 +- test/cpp/naming/gen_build_yaml.py | 258 +++--- .../manual_run_resolver_component_test.py | 18 +- test/cpp/naming/utils/dns_resolver.py | 61 +- test/cpp/naming/utils/dns_server.py | 241 +++--- .../run_dns_server_for_lb_interop_tests.py | 61 +- test/cpp/naming/utils/tcp_connect.py | 34 +- test/cpp/qps/gen_build_yaml.py | 240 ++++-- .../qps/json_run_localhost_scenario_gen.py | 5 +- test/cpp/qps/qps_json_driver_scenario_gen.py | 5 +- test/http2_test/http2_base_server.py | 367 ++++---- test/http2_test/http2_server_health_check.py | 26 +- test/http2_test/http2_test_server.py | 142 +-- test/http2_test/test_data_frame_padding.py | 104 ++- test/http2_test/test_goaway.py | 80 +- test/http2_test/test_max_streams.py | 54 +- test/http2_test/test_ping.py | 63 +- test/http2_test/test_rst_after_data.py | 39 +- test/http2_test/test_rst_after_header.py | 25 +- test/http2_test/test_rst_during_data.py | 42 +- tools/distrib/yapf_code.sh | 27 +- 34 files changed, 2059 insertions(+), 1682 deletions(-) diff --git a/.yapfignore b/.yapfignore index f709719f92f..8601c86da48 100644 --- a/.yapfignore +++ b/.yapfignore @@ -3,3 +3,33 @@ # no need to format protoc generated files *_pb2*.py + +# no need to format build-yaml generated files +*.gen.py + +# generated files from a template +*test/cpp/naming/resolver_component_tests_runner.py + +# No BUILD, .bzl files +*BUILD +*.bzl +*.bazelrc + +# No other languages +*.bat +*.c +*.c++ +*.cc +*.css +*.go +*.h +*.html +*.json +*.md +*.objc +*.php +*.proto +*.rb +*.sh +*.xml +*.yaml diff --git a/src/abseil-cpp/gen_build_yaml.py b/src/abseil-cpp/gen_build_yaml.py index 9f11e77b216..8a4657f0b3c 100755 --- a/src/abseil-cpp/gen_build_yaml.py +++ b/src/abseil-cpp/gen_build_yaml.py @@ -17,10 +17,10 @@ import os import yaml -BUILDS_YAML_PATH = os.path.join( - os.path.dirname(os.path.abspath(__file__)), 'preprocessed_builds.yaml') +BUILDS_YAML_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'preprocessed_builds.yaml') with open(BUILDS_YAML_PATH) as f: - builds = yaml.load(f) + builds = yaml.load(f) for build in builds: build['build'] = 'private' diff --git a/src/benchmark/gen_build_yaml.py b/src/benchmark/gen_build_yaml.py index 35c9244e6fa..6d9079bb8b6 100755 --- a/src/benchmark/gen_build_yaml.py +++ b/src/benchmark/gen_build_yaml.py @@ -20,20 +20,27 @@ import sys import glob import yaml -os.chdir(os.path.dirname(sys.argv[0])+'/../..') +os.chdir(os.path.dirname(sys.argv[0]) + '/../..') out = {} out['libs'] = [{ - 'name': 'benchmark', - 'build': 'private', - 'language': 'c++', - 'secure': False, - 'defaults': 'benchmark', - 'src': sorted(glob.glob('third_party/benchmark/src/*.cc')), - 'headers': sorted( - glob.glob('third_party/benchmark/src/*.h') + - glob.glob('third_party/benchmark/include/benchmark/*.h')), + 'name': + 'benchmark', + 'build': + 'private', + 'language': + 'c++', + 'secure': + False, + 'defaults': + 'benchmark', + 'src': + sorted(glob.glob('third_party/benchmark/src/*.cc')), + 'headers': + sorted( + glob.glob('third_party/benchmark/src/*.h') + + glob.glob('third_party/benchmark/include/benchmark/*.h')), }] print(yaml.dump(out)) diff --git a/src/boringssl/gen_build_yaml.py b/src/boringssl/gen_build_yaml.py index 3b259c32c5d..990835ed660 100755 --- a/src/boringssl/gen_build_yaml.py +++ b/src/boringssl/gen_build_yaml.py @@ -21,122 +21,124 @@ import yaml sys.dont_write_bytecode = True -boring_ssl_root = os.path.abspath(os.path.join( - os.path.dirname(sys.argv[0]), - '../../third_party/boringssl')) +boring_ssl_root = os.path.abspath( + os.path.join(os.path.dirname(sys.argv[0]), '../../third_party/boringssl')) sys.path.append(os.path.join(boring_ssl_root, 'util')) try: - import generate_build_files + import generate_build_files except ImportError: - print(yaml.dump({})) - sys.exit() + print(yaml.dump({})) + sys.exit() + def map_dir(filename): - if filename[0:4] == 'src/': - return 'third_party/boringssl/' + filename[4:] - else: - return 'src/boringssl/' + filename + if filename[0:4] == 'src/': + return 'third_party/boringssl/' + filename[4:] + else: + return 'src/boringssl/' + filename + def map_testarg(arg): - if '/' in arg: - return 'third_party/boringssl/' + arg - else: - return arg + if '/' in arg: + return 'third_party/boringssl/' + arg + else: + return arg + class Grpc(object): - yaml = None - - def WriteFiles(self, files, asm_outputs): - test_binaries = ['ssl_test', 'crypto_test'] - - self.yaml = { - '#': 'generated with tools/buildgen/gen_boring_ssl_build_yaml.py', - 'raw_boringssl_build_output_for_debugging': { - 'files': files, - 'asm_outputs': asm_outputs, - }, - 'libs': [ - { - 'name': 'boringssl', - 'build': 'private', - 'language': 'c', - 'secure': False, - 'src': sorted( - map_dir(f) - for f in files['ssl'] + files['crypto'] - ), - 'headers': sorted( - map_dir(f) - # We want to include files['fips_fragments'], but not build them as objects. - # See https://boringssl-review.googlesource.com/c/boringssl/+/16946 - for f in files['ssl_headers'] + files['ssl_internal_headers'] + files['crypto_headers'] + files['crypto_internal_headers'] + files['fips_fragments'] - ), - 'boringssl': True, - 'defaults': 'boringssl', - }, - { - 'name': 'boringssl_test_util', - 'build': 'private', - 'language': 'c++', - 'secure': False, - 'boringssl': True, - 'defaults': 'boringssl', - 'src': [ - map_dir(f) - for f in sorted(files['test_support']) + yaml = None + + def WriteFiles(self, files, asm_outputs): + test_binaries = ['ssl_test', 'crypto_test'] + + self.yaml = { + '#': + 'generated with tools/buildgen/gen_boring_ssl_build_yaml.py', + 'raw_boringssl_build_output_for_debugging': { + 'files': files, + 'asm_outputs': asm_outputs, + }, + 'libs': [ + { + 'name': + 'boringssl', + 'build': + 'private', + 'language': + 'c', + 'secure': + False, + 'src': + sorted( + map_dir(f) for f in files['ssl'] + files['crypto']), + 'headers': + sorted( + map_dir(f) + # We want to include files['fips_fragments'], but not build them as objects. + # See https://boringssl-review.googlesource.com/c/boringssl/+/16946 + for f in files['ssl_headers'] + + files['ssl_internal_headers'] + + files['crypto_headers'] + + files['crypto_internal_headers'] + + files['fips_fragments']), + 'boringssl': + True, + 'defaults': + 'boringssl', + }, + { + 'name': 'boringssl_test_util', + 'build': 'private', + 'language': 'c++', + 'secure': False, + 'boringssl': True, + 'defaults': 'boringssl', + 'src': [map_dir(f) for f in sorted(files['test_support'])], + } ], - } - ], - 'targets': [ - { - 'name': 'boringssl_%s' % test, - 'build': 'test', - 'run': False, - 'secure': False, - 'language': 'c++', - 'src': sorted(map_dir(f) for f in files[test]), - 'vs_proj_dir': 'test/boringssl', - 'boringssl': True, - 'defaults': 'boringssl', - 'deps': [ - 'boringssl_test_util', - 'boringssl', - ] - } - for test in test_binaries - ], - 'tests': [ - { - 'name': 'boringssl_%s' % test, - 'args': [], - 'exclude_configs': ['asan', 'ubsan'], - 'ci_platforms': ['linux', 'mac', 'posix', 'windows'], - 'platforms': ['linux', 'mac', 'posix', 'windows'], - 'flaky': False, - 'gtest': True, - 'language': 'c++', - 'boringssl': True, - 'defaults': 'boringssl', - 'cpu_cost': 1.0 - } - for test in test_binaries - ] - } + 'targets': [{ + 'name': 'boringssl_%s' % test, + 'build': 'test', + 'run': False, + 'secure': False, + 'language': 'c++', + 'src': sorted(map_dir(f) for f in files[test]), + 'vs_proj_dir': 'test/boringssl', + 'boringssl': True, + 'defaults': 'boringssl', + 'deps': [ + 'boringssl_test_util', + 'boringssl', + ] + } for test in test_binaries], + 'tests': [{ + 'name': 'boringssl_%s' % test, + 'args': [], + 'exclude_configs': ['asan', 'ubsan'], + 'ci_platforms': ['linux', 'mac', 'posix', 'windows'], + 'platforms': ['linux', 'mac', 'posix', 'windows'], + 'flaky': False, + 'gtest': True, + 'language': 'c++', + 'boringssl': True, + 'defaults': 'boringssl', + 'cpu_cost': 1.0 + } for test in test_binaries] + } os.chdir(os.path.dirname(sys.argv[0])) os.mkdir('src') try: - for f in os.listdir(boring_ssl_root): - os.symlink(os.path.join(boring_ssl_root, f), - os.path.join('src', f)) + for f in os.listdir(boring_ssl_root): + os.symlink(os.path.join(boring_ssl_root, f), os.path.join('src', f)) - g = Grpc() - generate_build_files.main([g]) + g = Grpc() + generate_build_files.main([g]) - print(yaml.dump(g.yaml)) + print(yaml.dump(g.yaml)) finally: - shutil.rmtree('src') + shutil.rmtree('src') diff --git a/src/c-ares/gen_build_yaml.py b/src/c-ares/gen_build_yaml.py index fe2ecb462c3..27903d35716 100755 --- a/src/c-ares/gen_build_yaml.py +++ b/src/c-ares/gen_build_yaml.py @@ -19,124 +19,130 @@ import os import sys import yaml -os.chdir(os.path.dirname(sys.argv[0])+'/../..') +os.chdir(os.path.dirname(sys.argv[0]) + '/../..') out = {} try: - def gen_ares_build(x): - subprocess.call("third_party/cares/cares/buildconf", shell=True) - subprocess.call("third_party/cares/cares/configure", shell=True) - def config_platform(x): - if 'darwin' in sys.platform: - return 'src/cares/cares/config_darwin/ares_config.h' - if 'freebsd' in sys.platform: - return 'src/cares/cares/config_freebsd/ares_config.h' - if 'linux' in sys.platform: - return 'src/cares/cares/config_linux/ares_config.h' - if 'openbsd' in sys.platform: - return 'src/cares/cares/config_openbsd/ares_config.h' - if not os.path.isfile('third_party/cares/cares/ares_config.h'): - gen_ares_build(x) - return 'third_party/cares/cares/ares_config.h' + def gen_ares_build(x): + subprocess.call("third_party/cares/cares/buildconf", shell=True) + subprocess.call("third_party/cares/cares/configure", shell=True) - def ares_build(x): - if os.path.isfile('src/cares/cares/ares_build.h'): - return 'src/cares/cares/ares_build.h' - if not os.path.isfile('third_party/cares/cares/ares_build.h'): - gen_ares_build(x) - return 'third_party/cares/cares/ares_build.h' + def config_platform(x): + if 'darwin' in sys.platform: + return 'src/cares/cares/config_darwin/ares_config.h' + if 'freebsd' in sys.platform: + return 'src/cares/cares/config_freebsd/ares_config.h' + if 'linux' in sys.platform: + return 'src/cares/cares/config_linux/ares_config.h' + if 'openbsd' in sys.platform: + return 'src/cares/cares/config_openbsd/ares_config.h' + if not os.path.isfile('third_party/cares/cares/ares_config.h'): + gen_ares_build(x) + return 'third_party/cares/cares/ares_config.h' - out['libs'] = [{ - 'name': 'ares', - 'defaults': 'ares', - 'build': 'private', - 'language': 'c', - 'secure': False, - 'src': [ - "third_party/cares/cares/ares__close_sockets.c", - "third_party/cares/cares/ares__get_hostent.c", - "third_party/cares/cares/ares__read_line.c", - "third_party/cares/cares/ares__timeval.c", - "third_party/cares/cares/ares_cancel.c", - "third_party/cares/cares/ares_create_query.c", - "third_party/cares/cares/ares_data.c", - "third_party/cares/cares/ares_destroy.c", - "third_party/cares/cares/ares_expand_name.c", - "third_party/cares/cares/ares_expand_string.c", - "third_party/cares/cares/ares_fds.c", - "third_party/cares/cares/ares_free_hostent.c", - "third_party/cares/cares/ares_free_string.c", - "third_party/cares/cares/ares_getenv.c", - "third_party/cares/cares/ares_gethostbyaddr.c", - "third_party/cares/cares/ares_gethostbyname.c", - "third_party/cares/cares/ares_getnameinfo.c", - "third_party/cares/cares/ares_getopt.c", - "third_party/cares/cares/ares_getsock.c", - "third_party/cares/cares/ares_init.c", - "third_party/cares/cares/ares_library_init.c", - "third_party/cares/cares/ares_llist.c", - "third_party/cares/cares/ares_mkquery.c", - "third_party/cares/cares/ares_nowarn.c", - "third_party/cares/cares/ares_options.c", - "third_party/cares/cares/ares_parse_a_reply.c", - "third_party/cares/cares/ares_parse_aaaa_reply.c", - "third_party/cares/cares/ares_parse_mx_reply.c", - "third_party/cares/cares/ares_parse_naptr_reply.c", - "third_party/cares/cares/ares_parse_ns_reply.c", - "third_party/cares/cares/ares_parse_ptr_reply.c", - "third_party/cares/cares/ares_parse_soa_reply.c", - "third_party/cares/cares/ares_parse_srv_reply.c", - "third_party/cares/cares/ares_parse_txt_reply.c", - "third_party/cares/cares/ares_platform.c", - "third_party/cares/cares/ares_process.c", - "third_party/cares/cares/ares_query.c", - "third_party/cares/cares/ares_search.c", - "third_party/cares/cares/ares_send.c", - "third_party/cares/cares/ares_strcasecmp.c", - "third_party/cares/cares/ares_strdup.c", - "third_party/cares/cares/ares_strerror.c", - "third_party/cares/cares/ares_strsplit.c", - "third_party/cares/cares/ares_timeout.c", - "third_party/cares/cares/ares_version.c", - "third_party/cares/cares/ares_writev.c", - "third_party/cares/cares/bitncmp.c", - "third_party/cares/cares/inet_net_pton.c", - "third_party/cares/cares/inet_ntop.c", - "third_party/cares/cares/windows_port.c", - ], - 'headers': [ - "third_party/cares/cares/ares.h", - "third_party/cares/cares/ares_data.h", - "third_party/cares/cares/ares_dns.h", - "third_party/cares/cares/ares_getenv.h", - "third_party/cares/cares/ares_getopt.h", - "third_party/cares/cares/ares_inet_net_pton.h", - "third_party/cares/cares/ares_iphlpapi.h", - "third_party/cares/cares/ares_ipv6.h", - "third_party/cares/cares/ares_library_init.h", - "third_party/cares/cares/ares_llist.h", - "third_party/cares/cares/ares_nowarn.h", - "third_party/cares/cares/ares_platform.h", - "third_party/cares/cares/ares_private.h", - "third_party/cares/cares/ares_rules.h", - "third_party/cares/cares/ares_setup.h", - "third_party/cares/cares/ares_strcasecmp.h", - "third_party/cares/cares/ares_strdup.h", - "third_party/cares/cares/ares_strsplit.h", - "third_party/cares/cares/ares_version.h", - "third_party/cares/cares/bitncmp.h", - "third_party/cares/cares/config-win32.h", - "third_party/cares/cares/setup_once.h", - "third_party/cares/ares_build.h", - "third_party/cares/config_darwin/ares_config.h", - "third_party/cares/config_freebsd/ares_config.h", - "third_party/cares/config_linux/ares_config.h", - "third_party/cares/config_openbsd/ares_config.h" - ], - }] + def ares_build(x): + if os.path.isfile('src/cares/cares/ares_build.h'): + return 'src/cares/cares/ares_build.h' + if not os.path.isfile('third_party/cares/cares/ares_build.h'): + gen_ares_build(x) + return 'third_party/cares/cares/ares_build.h' + + out['libs'] = [{ + 'name': + 'ares', + 'defaults': + 'ares', + 'build': + 'private', + 'language': + 'c', + 'secure': + False, + 'src': [ + "third_party/cares/cares/ares__close_sockets.c", + "third_party/cares/cares/ares__get_hostent.c", + "third_party/cares/cares/ares__read_line.c", + "third_party/cares/cares/ares__timeval.c", + "third_party/cares/cares/ares_cancel.c", + "third_party/cares/cares/ares_create_query.c", + "third_party/cares/cares/ares_data.c", + "third_party/cares/cares/ares_destroy.c", + "third_party/cares/cares/ares_expand_name.c", + "third_party/cares/cares/ares_expand_string.c", + "third_party/cares/cares/ares_fds.c", + "third_party/cares/cares/ares_free_hostent.c", + "third_party/cares/cares/ares_free_string.c", + "third_party/cares/cares/ares_getenv.c", + "third_party/cares/cares/ares_gethostbyaddr.c", + "third_party/cares/cares/ares_gethostbyname.c", + "third_party/cares/cares/ares_getnameinfo.c", + "third_party/cares/cares/ares_getopt.c", + "third_party/cares/cares/ares_getsock.c", + "third_party/cares/cares/ares_init.c", + "third_party/cares/cares/ares_library_init.c", + "third_party/cares/cares/ares_llist.c", + "third_party/cares/cares/ares_mkquery.c", + "third_party/cares/cares/ares_nowarn.c", + "third_party/cares/cares/ares_options.c", + "third_party/cares/cares/ares_parse_a_reply.c", + "third_party/cares/cares/ares_parse_aaaa_reply.c", + "third_party/cares/cares/ares_parse_mx_reply.c", + "third_party/cares/cares/ares_parse_naptr_reply.c", + "third_party/cares/cares/ares_parse_ns_reply.c", + "third_party/cares/cares/ares_parse_ptr_reply.c", + "third_party/cares/cares/ares_parse_soa_reply.c", + "third_party/cares/cares/ares_parse_srv_reply.c", + "third_party/cares/cares/ares_parse_txt_reply.c", + "third_party/cares/cares/ares_platform.c", + "third_party/cares/cares/ares_process.c", + "third_party/cares/cares/ares_query.c", + "third_party/cares/cares/ares_search.c", + "third_party/cares/cares/ares_send.c", + "third_party/cares/cares/ares_strcasecmp.c", + "third_party/cares/cares/ares_strdup.c", + "third_party/cares/cares/ares_strerror.c", + "third_party/cares/cares/ares_strsplit.c", + "third_party/cares/cares/ares_timeout.c", + "third_party/cares/cares/ares_version.c", + "third_party/cares/cares/ares_writev.c", + "third_party/cares/cares/bitncmp.c", + "third_party/cares/cares/inet_net_pton.c", + "third_party/cares/cares/inet_ntop.c", + "third_party/cares/cares/windows_port.c", + ], + 'headers': [ + "third_party/cares/cares/ares.h", + "third_party/cares/cares/ares_data.h", + "third_party/cares/cares/ares_dns.h", + "third_party/cares/cares/ares_getenv.h", + "third_party/cares/cares/ares_getopt.h", + "third_party/cares/cares/ares_inet_net_pton.h", + "third_party/cares/cares/ares_iphlpapi.h", + "third_party/cares/cares/ares_ipv6.h", + "third_party/cares/cares/ares_library_init.h", + "third_party/cares/cares/ares_llist.h", + "third_party/cares/cares/ares_nowarn.h", + "third_party/cares/cares/ares_platform.h", + "third_party/cares/cares/ares_private.h", + "third_party/cares/cares/ares_rules.h", + "third_party/cares/cares/ares_setup.h", + "third_party/cares/cares/ares_strcasecmp.h", + "third_party/cares/cares/ares_strdup.h", + "third_party/cares/cares/ares_strsplit.h", + "third_party/cares/cares/ares_version.h", + "third_party/cares/cares/bitncmp.h", + "third_party/cares/cares/config-win32.h", + "third_party/cares/cares/setup_once.h", + "third_party/cares/ares_build.h", + "third_party/cares/config_darwin/ares_config.h", + "third_party/cares/config_freebsd/ares_config.h", + "third_party/cares/config_linux/ares_config.h", + "third_party/cares/config_openbsd/ares_config.h" + ], + }] except: - pass + pass print yaml.dump(out) diff --git a/src/objective-c/change-comments.py b/src/objective-c/change-comments.py index 4de8a336889..82645a419f5 100755 --- a/src/objective-c/change-comments.py +++ b/src/objective-c/change-comments.py @@ -12,102 +12,95 @@ # 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. - """Change comments style of source files from // to /** */""" import re import sys - if len(sys.argv) < 2: - print("Please provide at least one source file name as argument.") - sys.exit() + print("Please provide at least one source file name as argument.") + sys.exit() for file_name in sys.argv[1:]: - print("Modifying format of {file} comments in place...".format( - file=file_name, - )) - - - # Input - - with open(file_name, "r") as input_file: - lines = input_file.readlines() - - def peek(): - return lines[0] - - def read_line(): - return lines.pop(0) + print("Modifying format of {file} comments in place...".format( + file=file_name,)) - def more_input_available(): - return lines + # Input + with open(file_name, "r") as input_file: + lines = input_file.readlines() - # Output + def peek(): + return lines[0] - output_lines = [] + def read_line(): + return lines.pop(0) - def write(line): - output_lines.append(line) + def more_input_available(): + return lines - def flush_output(): - with open(file_name, "w") as output_file: - for line in output_lines: - output_file.write(line) + # Output + output_lines = [] - # Pattern matching + def write(line): + output_lines.append(line) - comment_regex = r'^(\s*)//\s(.*)$' + def flush_output(): + with open(file_name, "w") as output_file: + for line in output_lines: + output_file.write(line) - def is_comment(line): - return re.search(comment_regex, line) + # Pattern matching - def isnt_comment(line): - return not is_comment(line) + comment_regex = r'^(\s*)//\s(.*)$' - def next_line(predicate): - return more_input_available() and predicate(peek()) + def is_comment(line): + return re.search(comment_regex, line) + def isnt_comment(line): + return not is_comment(line) - # Transformation + def next_line(predicate): + return more_input_available() and predicate(peek()) - def indentation_of(line): - match = re.search(comment_regex, line) - return match.group(1) + # Transformation - def content(line): - match = re.search(comment_regex, line) - return match.group(2) + def indentation_of(line): + match = re.search(comment_regex, line) + return match.group(1) - def format_as_block(comment_block): - if len(comment_block) == 0: - return [] + def content(line): + match = re.search(comment_regex, line) + return match.group(2) - indent = indentation_of(comment_block[0]) + def format_as_block(comment_block): + if len(comment_block) == 0: + return [] - if len(comment_block) == 1: - return [indent + "/** " + content(comment_block[0]) + " */\n"] + indent = indentation_of(comment_block[0]) - block = ["/**"] + [" * " + content(line) for line in comment_block] + [" */"] - return [indent + line.rstrip() + "\n" for line in block] + if len(comment_block) == 1: + return [indent + "/** " + content(comment_block[0]) + " */\n"] + block = ["/**"] + [" * " + content(line) for line in comment_block + ] + [" */"] + return [indent + line.rstrip() + "\n" for line in block] - # Main algorithm + # Main algorithm - while more_input_available(): - while next_line(isnt_comment): - write(read_line()) + while more_input_available(): + while next_line(isnt_comment): + write(read_line()) - comment_block = [] - # Get all lines in the same comment block. We could restrict the indentation - # to be the same as the first line of the block, but it's probably ok. - while (next_line(is_comment)): - comment_block.append(read_line()) + comment_block = [] + # Get all lines in the same comment block. We could restrict the indentation + # to be the same as the first line of the block, but it's probably ok. + while (next_line(is_comment)): + comment_block.append(read_line()) - for line in format_as_block(comment_block): - write(line) + for line in format_as_block(comment_block): + write(line) - flush_output() + flush_output() diff --git a/src/proto/gen_build_yaml.py b/src/proto/gen_build_yaml.py index fc1b5f7986e..3900ac25690 100755 --- a/src/proto/gen_build_yaml.py +++ b/src/proto/gen_build_yaml.py @@ -12,8 +12,6 @@ # 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. - - """Generates the appropriate build.json data for all the proto files.""" from __future__ import print_function import yaml @@ -22,56 +20,61 @@ import os import re import sys + def update_deps(key, proto_filename, deps, deps_external, is_trans, visited): - if not proto_filename in visited: - visited.append(proto_filename) - with open(proto_filename) as inp: - for line in inp: - imp = re.search(r'import "([^"]*)"', line) - if not imp: continue - imp_proto = imp.group(1) - # This indicates an external dependency, which we should handle - # differently and not traverse recursively - if imp_proto.startswith('google/'): - if key not in deps_external: - deps_external[key] = [] - deps_external[key].append(imp_proto[:-6]) - continue - # In case that the path is changed by copybara, - # revert the change to avoid file error. - if imp_proto.startswith('third_party/grpc'): - imp_proto = imp_proto[17:] - if key not in deps: deps[key] = [] - deps[key].append(imp_proto[:-6]) - if is_trans: - update_deps(key, imp_proto, deps, deps_external, is_trans, visited) + if not proto_filename in visited: + visited.append(proto_filename) + with open(proto_filename) as inp: + for line in inp: + imp = re.search(r'import "([^"]*)"', line) + if not imp: continue + imp_proto = imp.group(1) + # This indicates an external dependency, which we should handle + # differently and not traverse recursively + if imp_proto.startswith('google/'): + if key not in deps_external: + deps_external[key] = [] + deps_external[key].append(imp_proto[:-6]) + continue + # In case that the path is changed by copybara, + # revert the change to avoid file error. + if imp_proto.startswith('third_party/grpc'): + imp_proto = imp_proto[17:] + if key not in deps: deps[key] = [] + deps[key].append(imp_proto[:-6]) + if is_trans: + update_deps(key, imp_proto, deps, deps_external, is_trans, + visited) + def main(): - proto_dir = os.path.abspath(os.path.dirname(sys.argv[0])) - os.chdir(os.path.join(proto_dir, '../..')) + proto_dir = os.path.abspath(os.path.dirname(sys.argv[0])) + os.chdir(os.path.join(proto_dir, '../..')) + + deps = {} + deps_trans = {} + deps_external = {} + deps_external_trans = {} + for root, dirs, files in os.walk('src/proto'): + for f in files: + if f[-6:] != '.proto': continue + look_at = os.path.join(root, f) + deps_for = look_at[:-6] + # First level deps + update_deps(deps_for, look_at, deps, deps_external, False, []) + # Transitive deps + update_deps(deps_for, look_at, deps_trans, deps_external_trans, + True, []) - deps = {} - deps_trans = {} - deps_external = {} - deps_external_trans = {} - for root, dirs, files in os.walk('src/proto'): - for f in files: - if f[-6:] != '.proto': continue - look_at = os.path.join(root, f) - deps_for = look_at[:-6] - # First level deps - update_deps(deps_for, look_at, deps, deps_external, False, []) - # Transitive deps - update_deps(deps_for, look_at, deps_trans, deps_external_trans, True, []) + json = { + 'proto_deps': deps, + 'proto_transitive_deps': deps_trans, + 'proto_external_deps': deps_external, + 'proto_transitive_external_deps': deps_external_trans + } - json = { - 'proto_deps': deps, - 'proto_transitive_deps': deps_trans, - 'proto_external_deps': deps_external, - 'proto_transitive_external_deps': deps_external_trans - } + print(yaml.dump(json)) - print(yaml.dump(json)) if __name__ == '__main__': - main() + main() diff --git a/src/upb/gen_build_yaml.py b/src/upb/gen_build_yaml.py index f19426f451f..f7b82993986 100755 --- a/src/upb/gen_build_yaml.py +++ b/src/upb/gen_build_yaml.py @@ -25,33 +25,33 @@ import yaml out = {} try: - out['libs'] = [{ - 'name': - 'upb', - 'build': - 'all', - 'language': - 'c', - 'src': [ - "third_party/upb/upb/decode.c", - "third_party/upb/upb/encode.c", - "third_party/upb/upb/msg.c", - "third_party/upb/upb/port.c", - "third_party/upb/upb/table.c", - "third_party/upb/upb/upb.c", - ], - 'headers': [ - "third_party/upb/upb/decode.h", - "third_party/upb/upb/encode.h", - "third_party/upb/upb/generated_util.h", - "third_party/upb/upb/msg.h", - "third_party/upb/upb/port_def.inc", - "third_party/upb/upb/port_undef.inc", - "third_party/upb/upb/table.int.h", - "third_party/upb/upb/upb.h", - ], - }] + out['libs'] = [{ + 'name': + 'upb', + 'build': + 'all', + 'language': + 'c', + 'src': [ + "third_party/upb/upb/decode.c", + "third_party/upb/upb/encode.c", + "third_party/upb/upb/msg.c", + "third_party/upb/upb/port.c", + "third_party/upb/upb/table.c", + "third_party/upb/upb/upb.c", + ], + 'headers': [ + "third_party/upb/upb/decode.h", + "third_party/upb/upb/encode.h", + "third_party/upb/upb/generated_util.h", + "third_party/upb/upb/msg.h", + "third_party/upb/upb/port_def.inc", + "third_party/upb/upb/port_undef.inc", + "third_party/upb/upb/table.int.h", + "third_party/upb/upb/upb.h", + ], + }] except: - pass + pass print(yaml.dump(out)) diff --git a/src/zlib/gen_build_yaml.py b/src/zlib/gen_build_yaml.py index ee347e0b1f3..a27d8c0a359 100755 --- a/src/zlib/gen_build_yaml.py +++ b/src/zlib/gen_build_yaml.py @@ -19,35 +19,43 @@ import os import sys import yaml -os.chdir(os.path.dirname(sys.argv[0])+'/../..') +os.chdir(os.path.dirname(sys.argv[0]) + '/../..') out = {} try: - with open('third_party/zlib/CMakeLists.txt') as f: - cmake = f.read() - - def cmpath(x): - return 'third_party/zlib/%s' % x.replace('${CMAKE_CURRENT_BINARY_DIR}/', '') - - def cmvar(name): - regex = r'set\(\s*' - regex += name - regex += r'([^)]*)\)' - return [cmpath(x) for x in re.search(regex, cmake).group(1).split()] - - out['libs'] = [{ - 'name': 'z', - 'zlib': True, - 'defaults': 'zlib', - 'build': 'private', - 'language': 'c', - 'secure': False, - 'src': sorted(cmvar('ZLIB_SRCS')), - 'headers': sorted(cmvar('ZLIB_PUBLIC_HDRS') + cmvar('ZLIB_PRIVATE_HDRS')), - }] + with open('third_party/zlib/CMakeLists.txt') as f: + cmake = f.read() + + def cmpath(x): + return 'third_party/zlib/%s' % x.replace('${CMAKE_CURRENT_BINARY_DIR}/', + '') + + def cmvar(name): + regex = r'set\(\s*' + regex += name + regex += r'([^)]*)\)' + return [cmpath(x) for x in re.search(regex, cmake).group(1).split()] + + out['libs'] = [{ + 'name': + 'z', + 'zlib': + True, + 'defaults': + 'zlib', + 'build': + 'private', + 'language': + 'c', + 'secure': + False, + 'src': + sorted(cmvar('ZLIB_SRCS')), + 'headers': + sorted(cmvar('ZLIB_PUBLIC_HDRS') + cmvar('ZLIB_PRIVATE_HDRS')), + }] except: - pass + pass print yaml.dump(out) - diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index 3224dfe3877..c4f95654724 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -12,11 +12,8 @@ # 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. - - """Generates the appropriate build.json data for all the bad_client tests.""" - from __future__ import print_function import collections import yaml @@ -41,47 +38,43 @@ BAD_CLIENT_TESTS = { 'unknown_frame': default_test_options, } + def main(): - json = { - '#': 'generated with test/bad_client/gen_build_json.py', - 'libs': [ - { + json = { + '#': + 'generated with test/bad_client/gen_build_json.py', + 'libs': [{ 'name': 'bad_client_test', 'build': 'private', 'language': 'c++', - 'src': [ - 'test/core/bad_client/bad_client.cc' - ], - 'headers': [ - 'test/core/bad_client/bad_client.h' - ], + 'src': ['test/core/bad_client/bad_client.cc'], + 'headers': ['test/core/bad_client/bad_client.h'], 'vs_proj_dir': 'test/bad_client', + 'deps': ['grpc_test_util_unsecure', 'grpc_unsecure', 'gpr'] + }], + 'targets': [{ + 'name': + '%s_bad_client_test' % t, + 'cpu_cost': + BAD_CLIENT_TESTS[t].cpu_cost, + 'build': + 'test', + 'language': + 'c++', + 'secure': + False, + 'src': ['test/core/bad_client/tests/%s.cc' % t], + 'vs_proj_dir': + 'test', + 'exclude_iomgrs': ['uv'], 'deps': [ - 'grpc_test_util_unsecure', - 'grpc_unsecure', - 'gpr' + 'bad_client_test', 'grpc_test_util_unsecure', 'grpc_unsecure', + 'gpr' ] - }], - 'targets': [ - { - 'name': '%s_bad_client_test' % t, - 'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost, - 'build': 'test', - 'language': 'c++', - 'secure': False, - 'src': ['test/core/bad_client/tests/%s.cc' % t], - 'vs_proj_dir': 'test', - 'exclude_iomgrs': ['uv'], - 'deps': [ - 'bad_client_test', - 'grpc_test_util_unsecure', - 'grpc_unsecure', - 'gpr' - ] - } - for t in sorted(BAD_CLIENT_TESTS.keys())]} - print(yaml.dump(json)) + } for t in sorted(BAD_CLIENT_TESTS.keys())] + } + print(yaml.dump(json)) if __name__ == '__main__': - main() + main() diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py index 52f49bea2ad..12ec838b4e6 100755 --- a/test/core/bad_ssl/gen_build_yaml.py +++ b/test/core/bad_ssl/gen_build_yaml.py @@ -12,11 +12,8 @@ # 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. - - """Generates the appropriate build.json data for all the end2end tests.""" - import collections import yaml @@ -30,59 +27,43 @@ BAD_CLIENT_TESTS = { # 'alpn': default_test_options._replace(cpu_cost=0.1), } + def main(): - json = { - '#': 'generated with test/bad_ssl/gen_build_json.py', - 'libs': [ - { - 'name': 'bad_ssl_test_server', - 'build': 'private', - 'language': 'c', - 'src': ['test/core/bad_ssl/server_common.cc'], - 'headers': ['test/core/bad_ssl/server_common.h'], - 'vs_proj_dir': 'test', - 'platforms': ['linux', 'posix', 'mac'], - 'deps': [ - 'grpc_test_util', - 'grpc', - 'gpr' - ] - } - ], - 'targets': [ - { - 'name': 'bad_ssl_%s_server' % t, - 'build': 'test', - 'language': 'c', - 'run': False, - 'src': ['test/core/bad_ssl/servers/%s.cc' % t], - 'vs_proj_dir': 'test/bad_ssl', - 'platforms': ['linux', 'posix', 'mac'], - 'deps': [ - 'bad_ssl_test_server', - 'grpc_test_util', - 'grpc', - 'gpr' - ] - } - for t in sorted(BAD_CLIENT_TESTS.keys())] + [ - { - 'name': 'bad_ssl_%s_test' % t, - 'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost, - 'build': 'test', - 'language': 'c', - 'src': ['test/core/bad_ssl/bad_ssl_test.cc'], - 'vs_proj_dir': 'test', - 'platforms': ['linux', 'posix', 'mac'], - 'deps': [ - 'grpc_test_util', - 'grpc', - 'gpr' - ] - } - for t in sorted(BAD_CLIENT_TESTS.keys())]} - print yaml.dump(json) + json = { + '#': + 'generated with test/bad_ssl/gen_build_json.py', + 'libs': [{ + 'name': 'bad_ssl_test_server', + 'build': 'private', + 'language': 'c', + 'src': ['test/core/bad_ssl/server_common.cc'], + 'headers': ['test/core/bad_ssl/server_common.h'], + 'vs_proj_dir': 'test', + 'platforms': ['linux', 'posix', 'mac'], + 'deps': ['grpc_test_util', 'grpc', 'gpr'] + }], + 'targets': [{ + 'name': 'bad_ssl_%s_server' % t, + 'build': 'test', + 'language': 'c', + 'run': False, + 'src': ['test/core/bad_ssl/servers/%s.cc' % t], + 'vs_proj_dir': 'test/bad_ssl', + 'platforms': ['linux', 'posix', 'mac'], + 'deps': ['bad_ssl_test_server', 'grpc_test_util', 'grpc', 'gpr'] + } for t in sorted(BAD_CLIENT_TESTS.keys())] + [{ + 'name': 'bad_ssl_%s_test' % t, + 'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost, + 'build': 'test', + 'language': 'c', + 'src': ['test/core/bad_ssl/bad_ssl_test.cc'], + 'vs_proj_dir': 'test', + 'platforms': ['linux', 'posix', 'mac'], + 'deps': ['grpc_test_util', 'grpc', 'gpr'] + } for t in sorted(BAD_CLIENT_TESTS.keys())] + } + print yaml.dump(json) if __name__ == '__main__': - main() + main() diff --git a/test/core/end2end/fuzzers/generate_client_examples_of_bad_closing_streams.py b/test/core/end2end/fuzzers/generate_client_examples_of_bad_closing_streams.py index 40501a362d0..cb47cae5cc4 100755 --- a/test/core/end2end/fuzzers/generate_client_examples_of_bad_closing_streams.py +++ b/test/core/end2end/fuzzers/generate_client_examples_of_bad_closing_streams.py @@ -19,16 +19,16 @@ import sys os.chdir(os.path.dirname(sys.argv[0])) streams = { - 'server_hanging_response_1_header': ( - [0,0,0,4,0,0,0,0,0] + # settings frame - [0,0,0,1,5,0,0,0,1] # trailers - ), - 'server_hanging_response_2_header2': ( - [0,0,0,4,0,0,0,0,0] + # settings frame - [0,0,0,1,4,0,0,0,1] + # headers - [0,0,0,1,5,0,0,0,1] # trailers - ), + 'server_hanging_response_1_header': + ([0, 0, 0, 4, 0, 0, 0, 0, 0] + # settings frame + [0, 0, 0, 1, 5, 0, 0, 0, 1] # trailers + ), + 'server_hanging_response_2_header2': + ([0, 0, 0, 4, 0, 0, 0, 0, 0] + # settings frame + [0, 0, 0, 1, 4, 0, 0, 0, 1] + # headers + [0, 0, 0, 1, 5, 0, 0, 0, 1] # trailers + ), } for name, stream in streams.items(): - open('client_fuzzer_corpus/%s' % name, 'w').write(bytearray(stream)) + open('client_fuzzer_corpus/%s' % name, 'w').write(bytearray(stream)) diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 01adcf389eb..889015bed40 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -11,8 +11,6 @@ # 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. - - """Generates the appropriate build.json data for all the end2end tests.""" from __future__ import print_function @@ -21,392 +19,527 @@ import yaml import collections import hashlib - FixtureOptions = collections.namedtuple( 'FixtureOptions', - 'fullstack includes_proxy dns_resolver name_resolution secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression supports_compression is_inproc is_http2 supports_proxy_auth supports_write_buffering client_channel') + 'fullstack includes_proxy dns_resolver name_resolution secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression supports_compression is_inproc is_http2 supports_proxy_auth supports_write_buffering client_channel' +) default_unsecure_fixture_options = FixtureOptions( - True, False, True, True, False, ['windows', 'linux', 'mac', 'posix'], - True, False, [], [], True, False, True, False, True, False, True, True) + True, False, True, True, False, ['windows', 'linux', 'mac', 'posix'], True, + False, [], [], True, False, True, False, True, False, True, True) socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace( fullstack=False, dns_resolver=False, client_channel=False) default_secure_fixture_options = default_unsecure_fixture_options._replace( secure=True) uds_fixture_options = default_unsecure_fixture_options._replace( - dns_resolver=False, platforms=['linux', 'mac', 'posix'], + dns_resolver=False, + platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv']) local_fixture_options = default_secure_fixture_options._replace( - dns_resolver=False, platforms=['linux', 'mac', 'posix'], + dns_resolver=False, + platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv']) fd_unsecure_fixture_options = default_unsecure_fixture_options._replace( - dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'], - exclude_iomgrs=['uv'], client_channel=False) + dns_resolver=False, + fullstack=False, + platforms=['linux', 'mac', 'posix'], + exclude_iomgrs=['uv'], + client_channel=False) inproc_fixture_options = default_secure_fixture_options._replace( - dns_resolver=False, fullstack=False, name_resolution=False, - supports_compression=False, is_inproc=True, is_http2=False, - supports_write_buffering=False, client_channel=False) + dns_resolver=False, + fullstack=False, + name_resolution=False, + supports_compression=False, + is_inproc=True, + is_http2=False, + supports_write_buffering=False, + client_channel=False) # maps fixture name to whether it requires the security library END2END_FIXTURES = { - 'h2_compress': default_unsecure_fixture_options._replace(enables_compression=True), - 'h2_census': default_unsecure_fixture_options, - # This cmake target is disabled for now because it depends on OpenCensus, - # which is Bazel-only. - # 'h2_load_reporting': default_unsecure_fixture_options, - 'h2_fakesec': default_secure_fixture_options._replace(ci_mac=False), - 'h2_fd': fd_unsecure_fixture_options, - 'h2_full': default_unsecure_fixture_options, - 'h2_full+pipe': default_unsecure_fixture_options._replace( - platforms=['linux'], exclude_iomgrs=['uv']), - 'h2_full+trace': default_unsecure_fixture_options._replace(tracing=True), - 'h2_full+workarounds': default_unsecure_fixture_options, - 'h2_http_proxy': default_unsecure_fixture_options._replace( - ci_mac=False, exclude_iomgrs=['uv'], supports_proxy_auth=True), - 'h2_oauth2': default_secure_fixture_options._replace( - ci_mac=False, exclude_iomgrs=['uv']), - 'h2_proxy': default_unsecure_fixture_options._replace( - includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']), - 'h2_sockpair_1byte': socketpair_unsecure_fixture_options._replace( - ci_mac=False, exclude_configs=['msan'], large_writes=False, - exclude_iomgrs=['uv']), - 'h2_sockpair': socketpair_unsecure_fixture_options._replace( - ci_mac=False, exclude_iomgrs=['uv']), - 'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace( - ci_mac=False, tracing=True, large_writes=False, exclude_iomgrs=['uv']), - 'h2_ssl': default_secure_fixture_options, - 'h2_ssl_cred_reload': default_secure_fixture_options, - 'h2_tls': default_secure_fixture_options, - 'h2_local_uds': local_fixture_options, - 'h2_local_ipv4': local_fixture_options, - 'h2_local_ipv6': local_fixture_options, - 'h2_ssl_proxy': default_secure_fixture_options._replace( - includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']), - 'h2_uds': uds_fixture_options, - 'inproc': inproc_fixture_options + 'h2_compress': + default_unsecure_fixture_options._replace(enables_compression=True), + 'h2_census': + default_unsecure_fixture_options, + # This cmake target is disabled for now because it depends on OpenCensus, + # which is Bazel-only. + # 'h2_load_reporting': default_unsecure_fixture_options, + 'h2_fakesec': + default_secure_fixture_options._replace(ci_mac=False), + 'h2_fd': + fd_unsecure_fixture_options, + 'h2_full': + default_unsecure_fixture_options, + 'h2_full+pipe': + default_unsecure_fixture_options._replace(platforms=['linux'], + exclude_iomgrs=['uv']), + 'h2_full+trace': + default_unsecure_fixture_options._replace(tracing=True), + 'h2_full+workarounds': + default_unsecure_fixture_options, + 'h2_http_proxy': + default_unsecure_fixture_options._replace(ci_mac=False, + exclude_iomgrs=['uv'], + supports_proxy_auth=True), + 'h2_oauth2': + default_secure_fixture_options._replace(ci_mac=False, + exclude_iomgrs=['uv']), + 'h2_proxy': + default_unsecure_fixture_options._replace(includes_proxy=True, + ci_mac=False, + exclude_iomgrs=['uv']), + 'h2_sockpair_1byte': + socketpair_unsecure_fixture_options._replace(ci_mac=False, + exclude_configs=['msan'], + large_writes=False, + exclude_iomgrs=['uv']), + 'h2_sockpair': + socketpair_unsecure_fixture_options._replace(ci_mac=False, + exclude_iomgrs=['uv']), + 'h2_sockpair+trace': + socketpair_unsecure_fixture_options._replace(ci_mac=False, + tracing=True, + large_writes=False, + exclude_iomgrs=['uv']), + 'h2_ssl': + default_secure_fixture_options, + 'h2_ssl_cred_reload': + default_secure_fixture_options, + 'h2_tls': + default_secure_fixture_options, + 'h2_local_uds': + local_fixture_options, + 'h2_local_ipv4': + local_fixture_options, + 'h2_local_ipv6': + local_fixture_options, + 'h2_ssl_proxy': + default_secure_fixture_options._replace(includes_proxy=True, + ci_mac=False, + exclude_iomgrs=['uv']), + 'h2_uds': + uds_fixture_options, + 'inproc': + inproc_fixture_options } TestOptions = collections.namedtuple( 'TestOptions', - 'needs_fullstack needs_dns needs_names proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allows_compression needs_compression exclude_inproc needs_http2 needs_proxy_auth needs_write_buffering needs_client_channel') -default_test_options = TestOptions( - False, False, False, True, False, True, 1.0, [], False, False, True, - False, False, False, False, False, False) -connectivity_test_options = default_test_options._replace( - needs_fullstack=True) + 'needs_fullstack needs_dns needs_names proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allows_compression needs_compression exclude_inproc needs_http2 needs_proxy_auth needs_write_buffering needs_client_channel' +) +default_test_options = TestOptions(False, False, False, True, False, True, 1.0, + [], False, False, True, False, False, False, + False, False, False) +connectivity_test_options = default_test_options._replace(needs_fullstack=True) LOWCPU = 0.1 # maps test names to options END2END_TESTS = { - 'authority_not_supported': default_test_options, - 'bad_hostname': default_test_options._replace(needs_names=True), - 'bad_ping': connectivity_test_options._replace(proxyable=False), - 'binary_metadata': default_test_options._replace(cpu_cost=LOWCPU), - 'resource_quota_server': default_test_options._replace( - large_writes=True, proxyable=False, allows_compression=False), - 'call_creds': default_test_options._replace(secure=True), - 'cancel_after_accept': default_test_options._replace(cpu_cost=LOWCPU), - 'cancel_after_client_done': default_test_options._replace(cpu_cost=LOWCPU), - 'cancel_after_invoke': default_test_options._replace(cpu_cost=LOWCPU), - 'cancel_after_round_trip': default_test_options._replace(cpu_cost=LOWCPU), - 'cancel_before_invoke': default_test_options._replace(cpu_cost=LOWCPU), - 'cancel_in_a_vacuum': default_test_options._replace(cpu_cost=LOWCPU), - 'cancel_with_status': default_test_options._replace(cpu_cost=LOWCPU), - 'compressed_payload': default_test_options._replace(proxyable=False, - needs_compression=True), - 'connectivity': connectivity_test_options._replace(needs_names=True, - proxyable=False, cpu_cost=LOWCPU, exclude_iomgrs=['uv']), - 'channelz': default_test_options, - 'default_host': default_test_options._replace( - needs_fullstack=True, needs_dns=True, needs_names=True), - 'call_host_override': default_test_options._replace( - needs_fullstack=True, needs_dns=True, needs_names=True), - 'disappearing_server': connectivity_test_options._replace(flaky=True, - needs_names=True), - 'empty_batch': default_test_options._replace(cpu_cost=LOWCPU), - 'filter_causes_close': default_test_options._replace(cpu_cost=LOWCPU), - 'filter_call_init_fails': default_test_options, - 'filter_context': default_test_options, - 'filter_latency': default_test_options._replace(cpu_cost=LOWCPU), - 'filter_status_code': default_test_options._replace(cpu_cost=LOWCPU), - 'graceful_server_shutdown': default_test_options._replace( - cpu_cost=LOWCPU, exclude_inproc=True), - 'hpack_size': default_test_options._replace(proxyable=False, - traceable=False, - cpu_cost=LOWCPU), - 'high_initial_seqno': default_test_options._replace(cpu_cost=LOWCPU), - 'idempotent_request': default_test_options, - 'invoke_large_request': default_test_options, - 'keepalive_timeout': default_test_options._replace(proxyable=False, - cpu_cost=LOWCPU, - needs_http2=True), - 'large_metadata': default_test_options, - 'max_concurrent_streams': default_test_options._replace( - proxyable=False, cpu_cost=LOWCPU, exclude_inproc=True), - 'max_connection_age': default_test_options._replace(cpu_cost=LOWCPU, - exclude_inproc=True), - 'max_connection_idle': connectivity_test_options._replace( - proxyable=False, exclude_iomgrs=['uv'], cpu_cost=LOWCPU), - 'max_message_length': default_test_options._replace(cpu_cost=LOWCPU), - 'negative_deadline': default_test_options, - 'no_error_on_hotpath': default_test_options._replace(proxyable=False), - 'no_logging': default_test_options._replace(traceable=False), - 'no_op': default_test_options, - 'payload': default_test_options, + 'authority_not_supported': + default_test_options, + 'bad_hostname': + default_test_options._replace(needs_names=True), + 'bad_ping': + connectivity_test_options._replace(proxyable=False), + 'binary_metadata': + default_test_options._replace(cpu_cost=LOWCPU), + 'resource_quota_server': + default_test_options._replace(large_writes=True, + proxyable=False, + allows_compression=False), + 'call_creds': + default_test_options._replace(secure=True), + 'cancel_after_accept': + default_test_options._replace(cpu_cost=LOWCPU), + 'cancel_after_client_done': + default_test_options._replace(cpu_cost=LOWCPU), + 'cancel_after_invoke': + default_test_options._replace(cpu_cost=LOWCPU), + 'cancel_after_round_trip': + default_test_options._replace(cpu_cost=LOWCPU), + 'cancel_before_invoke': + default_test_options._replace(cpu_cost=LOWCPU), + 'cancel_in_a_vacuum': + default_test_options._replace(cpu_cost=LOWCPU), + 'cancel_with_status': + default_test_options._replace(cpu_cost=LOWCPU), + 'compressed_payload': + default_test_options._replace(proxyable=False, needs_compression=True), + 'connectivity': + connectivity_test_options._replace(needs_names=True, + proxyable=False, + cpu_cost=LOWCPU, + exclude_iomgrs=['uv']), + 'channelz': + default_test_options, + 'default_host': + default_test_options._replace(needs_fullstack=True, + needs_dns=True, + needs_names=True), + 'call_host_override': + default_test_options._replace(needs_fullstack=True, + needs_dns=True, + needs_names=True), + 'disappearing_server': + connectivity_test_options._replace(flaky=True, needs_names=True), + 'empty_batch': + default_test_options._replace(cpu_cost=LOWCPU), + 'filter_causes_close': + default_test_options._replace(cpu_cost=LOWCPU), + 'filter_call_init_fails': + default_test_options, + 'filter_context': + default_test_options, + 'filter_latency': + default_test_options._replace(cpu_cost=LOWCPU), + 'filter_status_code': + default_test_options._replace(cpu_cost=LOWCPU), + 'graceful_server_shutdown': + default_test_options._replace(cpu_cost=LOWCPU, exclude_inproc=True), + 'hpack_size': + default_test_options._replace(proxyable=False, + traceable=False, + cpu_cost=LOWCPU), + 'high_initial_seqno': + default_test_options._replace(cpu_cost=LOWCPU), + 'idempotent_request': + default_test_options, + 'invoke_large_request': + default_test_options, + 'keepalive_timeout': + default_test_options._replace(proxyable=False, + cpu_cost=LOWCPU, + needs_http2=True), + 'large_metadata': + default_test_options, + 'max_concurrent_streams': + default_test_options._replace(proxyable=False, + cpu_cost=LOWCPU, + exclude_inproc=True), + 'max_connection_age': + default_test_options._replace(cpu_cost=LOWCPU, exclude_inproc=True), + 'max_connection_idle': + connectivity_test_options._replace(proxyable=False, + exclude_iomgrs=['uv'], + cpu_cost=LOWCPU), + 'max_message_length': + default_test_options._replace(cpu_cost=LOWCPU), + 'negative_deadline': + default_test_options, + 'no_error_on_hotpath': + default_test_options._replace(proxyable=False), + 'no_logging': + default_test_options._replace(traceable=False), + 'no_op': + default_test_options, + 'payload': + default_test_options, # This cmake target is disabled for now because it depends on OpenCensus, # which is Bazel-only. # 'load_reporting_hook': default_test_options, - 'ping_pong_streaming': default_test_options._replace(cpu_cost=LOWCPU), - 'ping': connectivity_test_options._replace(proxyable=False, - cpu_cost=LOWCPU), - 'proxy_auth': default_test_options._replace(needs_proxy_auth=True), - 'registered_call': default_test_options, - 'request_with_flags': default_test_options._replace( - proxyable=False, cpu_cost=LOWCPU), - 'request_with_payload': default_test_options._replace(cpu_cost=LOWCPU), + 'ping_pong_streaming': + default_test_options._replace(cpu_cost=LOWCPU), + 'ping': + connectivity_test_options._replace(proxyable=False, cpu_cost=LOWCPU), + 'proxy_auth': + default_test_options._replace(needs_proxy_auth=True), + 'registered_call': + default_test_options, + 'request_with_flags': + default_test_options._replace(proxyable=False, cpu_cost=LOWCPU), + 'request_with_payload': + default_test_options._replace(cpu_cost=LOWCPU), # TODO(roth): Remove proxyable=False for all retry tests once we # have a way for the proxy to propagate the fact that trailing # metadata is available when initial metadata is returned. # See https://github.com/grpc/grpc/issues/14467 for context. - 'retry': default_test_options._replace(cpu_cost=LOWCPU, - needs_client_channel=True, - proxyable=False), - 'retry_cancellation': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'retry_disabled': default_test_options._replace(cpu_cost=LOWCPU, - needs_client_channel=True, - proxyable=False), - 'retry_exceeds_buffer_size_in_initial_batch': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_cancellation': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_disabled': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_exceeds_buffer_size_in_initial_batch': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), 'retry_exceeds_buffer_size_in_subsequent_batch': default_test_options._replace(cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'retry_non_retriable_status': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_non_retriable_status': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), 'retry_non_retriable_status_before_recv_trailing_metadata_started': - default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'retry_recv_initial_metadata': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'retry_recv_message': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'retry_server_pushback_delay': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'retry_server_pushback_disabled': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'retry_streaming': default_test_options._replace(cpu_cost=LOWCPU, - needs_client_channel=True, - proxyable=False), - 'retry_streaming_after_commit': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_recv_initial_metadata': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_recv_message': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_server_pushback_delay': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_server_pushback_disabled': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_streaming': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_streaming_after_commit': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), 'retry_streaming_succeeds_before_replay_finished': default_test_options._replace(cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'retry_throttled': default_test_options._replace(cpu_cost=LOWCPU, - needs_client_channel=True, - proxyable=False), - 'retry_too_many_attempts': default_test_options._replace( - cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), - 'server_finishes_request': default_test_options._replace(cpu_cost=LOWCPU), - 'shutdown_finishes_calls': default_test_options._replace(cpu_cost=LOWCPU), - 'shutdown_finishes_tags': default_test_options._replace(cpu_cost=LOWCPU), - 'simple_cacheable_request': default_test_options._replace(cpu_cost=LOWCPU), - 'stream_compression_compressed_payload': default_test_options._replace( - proxyable=False, exclude_inproc=True), - 'stream_compression_payload': default_test_options._replace( - exclude_inproc=True), - 'stream_compression_ping_pong_streaming': default_test_options._replace( - exclude_inproc=True), - 'simple_delayed_request': connectivity_test_options, - 'simple_metadata': default_test_options, - 'simple_request': default_test_options, - 'streaming_error_response': default_test_options._replace(cpu_cost=LOWCPU), - 'trailing_metadata': default_test_options, - 'workaround_cronet_compression': default_test_options, - 'write_buffering': default_test_options._replace( - cpu_cost=LOWCPU, needs_write_buffering=True), - 'write_buffering_at_end': default_test_options._replace( - cpu_cost=LOWCPU, needs_write_buffering=True), + 'retry_throttled': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_too_many_attempts': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'server_finishes_request': + default_test_options._replace(cpu_cost=LOWCPU), + 'shutdown_finishes_calls': + default_test_options._replace(cpu_cost=LOWCPU), + 'shutdown_finishes_tags': + default_test_options._replace(cpu_cost=LOWCPU), + 'simple_cacheable_request': + default_test_options._replace(cpu_cost=LOWCPU), + 'stream_compression_compressed_payload': + default_test_options._replace(proxyable=False, exclude_inproc=True), + 'stream_compression_payload': + default_test_options._replace(exclude_inproc=True), + 'stream_compression_ping_pong_streaming': + default_test_options._replace(exclude_inproc=True), + 'simple_delayed_request': + connectivity_test_options, + 'simple_metadata': + default_test_options, + 'simple_request': + default_test_options, + 'streaming_error_response': + default_test_options._replace(cpu_cost=LOWCPU), + 'trailing_metadata': + default_test_options, + 'workaround_cronet_compression': + default_test_options, + 'write_buffering': + default_test_options._replace(cpu_cost=LOWCPU, + needs_write_buffering=True), + 'write_buffering_at_end': + default_test_options._replace(cpu_cost=LOWCPU, + needs_write_buffering=True), } def compatible(f, t): - if END2END_TESTS[t].needs_fullstack: - if not END2END_FIXTURES[f].fullstack: - return False - if END2END_TESTS[t].needs_dns: - if not END2END_FIXTURES[f].dns_resolver: - return False - if END2END_TESTS[t].needs_names: - if not END2END_FIXTURES[f].name_resolution: - return False - if not END2END_TESTS[t].proxyable: - if END2END_FIXTURES[f].includes_proxy: - return False - if not END2END_TESTS[t].traceable: - if END2END_FIXTURES[f].tracing: - return False - if END2END_TESTS[t].large_writes: - if not END2END_FIXTURES[f].large_writes: - return False - if not END2END_TESTS[t].allows_compression: - if END2END_FIXTURES[f].enables_compression: - return False - if END2END_TESTS[t].needs_compression: - if not END2END_FIXTURES[f].supports_compression: - return False - if END2END_TESTS[t].exclude_inproc: - if END2END_FIXTURES[f].is_inproc: - return False - if END2END_TESTS[t].needs_http2: - if not END2END_FIXTURES[f].is_http2: - return False - if END2END_TESTS[t].needs_proxy_auth: - if not END2END_FIXTURES[f].supports_proxy_auth: - return False - if END2END_TESTS[t].needs_write_buffering: - if not END2END_FIXTURES[f].supports_write_buffering: - return False - if END2END_TESTS[t].needs_client_channel: - if not END2END_FIXTURES[f].client_channel: - return False - return True + if END2END_TESTS[t].needs_fullstack: + if not END2END_FIXTURES[f].fullstack: + return False + if END2END_TESTS[t].needs_dns: + if not END2END_FIXTURES[f].dns_resolver: + return False + if END2END_TESTS[t].needs_names: + if not END2END_FIXTURES[f].name_resolution: + return False + if not END2END_TESTS[t].proxyable: + if END2END_FIXTURES[f].includes_proxy: + return False + if not END2END_TESTS[t].traceable: + if END2END_FIXTURES[f].tracing: + return False + if END2END_TESTS[t].large_writes: + if not END2END_FIXTURES[f].large_writes: + return False + if not END2END_TESTS[t].allows_compression: + if END2END_FIXTURES[f].enables_compression: + return False + if END2END_TESTS[t].needs_compression: + if not END2END_FIXTURES[f].supports_compression: + return False + if END2END_TESTS[t].exclude_inproc: + if END2END_FIXTURES[f].is_inproc: + return False + if END2END_TESTS[t].needs_http2: + if not END2END_FIXTURES[f].is_http2: + return False + if END2END_TESTS[t].needs_proxy_auth: + if not END2END_FIXTURES[f].supports_proxy_auth: + return False + if END2END_TESTS[t].needs_write_buffering: + if not END2END_FIXTURES[f].supports_write_buffering: + return False + if END2END_TESTS[t].needs_client_channel: + if not END2END_FIXTURES[f].client_channel: + return False + return True def without(l, e): - l = l[:] - l.remove(e) - return l + l = l[:] + l.remove(e) + return l def main(): - sec_deps = [ - 'grpc_test_util', - 'grpc', - 'gpr' - ] - unsec_deps = [ - 'grpc_test_util_unsecure', - 'grpc_unsecure', - 'gpr' - ] - json = { - '#': 'generated with test/end2end/gen_build_json.py', - 'libs': [ - { - 'name': 'end2end_tests', - 'build': 'private', - 'language': 'c', - 'secure': True, - 'src': ['test/core/end2end/end2end_tests.cc', - 'test/core/end2end/end2end_test_utils.cc'] + [ - 'test/core/end2end/tests/%s.cc' % t - for t in sorted(END2END_TESTS.keys())], - 'headers': ['test/core/end2end/tests/cancel_test_helpers.h', - 'test/core/end2end/end2end_tests.h'], - 'deps': sec_deps, - 'vs_proj_dir': 'test/end2end/tests', - } - ] + [ - { - 'name': 'end2end_nosec_tests', - 'build': 'private', - 'language': 'c', - 'secure': False, - 'src': ['test/core/end2end/end2end_nosec_tests.cc', - 'test/core/end2end/end2end_test_utils.cc'] + [ - 'test/core/end2end/tests/%s.cc' % t + sec_deps = ['grpc_test_util', 'grpc', 'gpr'] + unsec_deps = ['grpc_test_util_unsecure', 'grpc_unsecure', 'gpr'] + json = { + '#': + 'generated with test/end2end/gen_build_json.py', + 'libs': [{ + 'name': + 'end2end_tests', + 'build': + 'private', + 'language': + 'c', + 'secure': + True, + 'src': [ + 'test/core/end2end/end2end_tests.cc', + 'test/core/end2end/end2end_test_utils.cc' + ] + [ + 'test/core/end2end/tests/%s.cc' % t + for t in sorted(END2END_TESTS.keys()) + ], + 'headers': [ + 'test/core/end2end/tests/cancel_test_helpers.h', + 'test/core/end2end/end2end_tests.h' + ], + 'deps': + sec_deps, + 'vs_proj_dir': + 'test/end2end/tests', + }] + [{ + 'name': + 'end2end_nosec_tests', + 'build': + 'private', + 'language': + 'c', + 'secure': + False, + 'src': [ + 'test/core/end2end/end2end_nosec_tests.cc', + 'test/core/end2end/end2end_test_utils.cc' + ] + [ + 'test/core/end2end/tests/%s.cc' % t + for t in sorted(END2END_TESTS.keys()) + if not END2END_TESTS[t].secure + ], + 'headers': [ + 'test/core/end2end/tests/cancel_test_helpers.h', + 'test/core/end2end/end2end_tests.h' + ], + 'deps': + unsec_deps, + 'vs_proj_dir': + 'test/end2end/tests', + }], + 'targets': [{ + 'name': '%s_test' % f, + 'build': 'test', + 'language': 'c', + 'run': False, + 'src': ['test/core/end2end/fixtures/%s.cc' % f], + 'platforms': END2END_FIXTURES[f].platforms, + 'ci_platforms': + (END2END_FIXTURES[f].platforms if END2END_FIXTURES[f].ci_mac + else without(END2END_FIXTURES[f].platforms, 'mac')), + 'deps': ['end2end_tests'] + sec_deps, + 'vs_proj_dir': 'test/end2end/fixtures', + } for f in sorted(END2END_FIXTURES.keys())] + [{ + 'name': '%s_nosec_test' % f, + 'build': 'test', + 'language': 'c', + 'secure': False, + 'src': ['test/core/end2end/fixtures/%s.cc' % f], + 'run': False, + 'platforms': END2END_FIXTURES[f].platforms, + 'ci_platforms': + (END2END_FIXTURES[f].platforms if END2END_FIXTURES[f].ci_mac + else without(END2END_FIXTURES[f].platforms, 'mac')), + 'deps': ['end2end_nosec_tests'] + unsec_deps, + 'vs_proj_dir': 'test/end2end/fixtures', + } for f in sorted( + END2END_FIXTURES.keys()) if not END2END_FIXTURES[f].secure], + 'tests': [{ + 'name': + '%s_test' % f, + 'args': [t], + 'exclude_configs': + END2END_FIXTURES[f].exclude_configs, + 'exclude_iomgrs': + list( + set(END2END_FIXTURES[f].exclude_iomgrs) | + set(END2END_TESTS[t].exclude_iomgrs)), + 'platforms': + END2END_FIXTURES[f].platforms, + 'ci_platforms': + (END2END_FIXTURES[f].platforms if END2END_FIXTURES[f].ci_mac + else without(END2END_FIXTURES[f].platforms, 'mac')), + 'flaky': + END2END_TESTS[t].flaky, + 'language': + 'c', + 'cpu_cost': + END2END_TESTS[t].cpu_cost, + } + for f in sorted(END2END_FIXTURES.keys()) + for t in sorted(END2END_TESTS.keys()) + if compatible(f, t)] + + [{ + 'name': + '%s_nosec_test' % f, + 'args': [t], + 'exclude_configs': + END2END_FIXTURES[f].exclude_configs, + 'exclude_iomgrs': + list( + set(END2END_FIXTURES[f].exclude_iomgrs) | + set(END2END_TESTS[t].exclude_iomgrs)), + 'platforms': + END2END_FIXTURES[f].platforms, + 'ci_platforms': + (END2END_FIXTURES[f].platforms + if END2END_FIXTURES[f].ci_mac else without( + END2END_FIXTURES[f].platforms, 'mac')), + 'flaky': + END2END_TESTS[t].flaky, + 'language': + 'c', + 'cpu_cost': + END2END_TESTS[t].cpu_cost, + } for f in sorted(END2END_FIXTURES.keys()) + if not END2END_FIXTURES[f].secure for t in sorted(END2END_TESTS.keys()) - if not END2END_TESTS[t].secure], - 'headers': ['test/core/end2end/tests/cancel_test_helpers.h', - 'test/core/end2end/end2end_tests.h'], - 'deps': unsec_deps, - 'vs_proj_dir': 'test/end2end/tests', - } - ], - 'targets': [ - { - 'name': '%s_test' % f, - 'build': 'test', - 'language': 'c', - 'run': False, - 'src': ['test/core/end2end/fixtures/%s.cc' % f], - 'platforms': END2END_FIXTURES[f].platforms, - 'ci_platforms': (END2END_FIXTURES[f].platforms - if END2END_FIXTURES[f].ci_mac else without( - END2END_FIXTURES[f].platforms, 'mac')), - 'deps': [ - 'end2end_tests' - ] + sec_deps, - 'vs_proj_dir': 'test/end2end/fixtures', - } - for f in sorted(END2END_FIXTURES.keys()) - ] + [ - { - 'name': '%s_nosec_test' % f, - 'build': 'test', - 'language': 'c', - 'secure': False, - 'src': ['test/core/end2end/fixtures/%s.cc' % f], - 'run': False, - 'platforms': END2END_FIXTURES[f].platforms, - 'ci_platforms': (END2END_FIXTURES[f].platforms - if END2END_FIXTURES[f].ci_mac else without( - END2END_FIXTURES[f].platforms, 'mac')), - 'deps': [ - 'end2end_nosec_tests' - ] + unsec_deps, - 'vs_proj_dir': 'test/end2end/fixtures', - } - for f in sorted(END2END_FIXTURES.keys()) - if not END2END_FIXTURES[f].secure - ], - 'tests': [ - { - 'name': '%s_test' % f, - 'args': [t], - 'exclude_configs': END2END_FIXTURES[f].exclude_configs, - 'exclude_iomgrs': list(set(END2END_FIXTURES[f].exclude_iomgrs) | - set(END2END_TESTS[t].exclude_iomgrs)), - 'platforms': END2END_FIXTURES[f].platforms, - 'ci_platforms': (END2END_FIXTURES[f].platforms - if END2END_FIXTURES[f].ci_mac else without( - END2END_FIXTURES[f].platforms, 'mac')), - 'flaky': END2END_TESTS[t].flaky, - 'language': 'c', - 'cpu_cost': END2END_TESTS[t].cpu_cost, - } - for f in sorted(END2END_FIXTURES.keys()) - for t in sorted(END2END_TESTS.keys()) if compatible(f, t) - ] + [ - { - 'name': '%s_nosec_test' % f, - 'args': [t], - 'exclude_configs': END2END_FIXTURES[f].exclude_configs, - 'exclude_iomgrs': list(set(END2END_FIXTURES[f].exclude_iomgrs) | - set(END2END_TESTS[t].exclude_iomgrs)), - 'platforms': END2END_FIXTURES[f].platforms, - 'ci_platforms': (END2END_FIXTURES[f].platforms - if END2END_FIXTURES[f].ci_mac else without( - END2END_FIXTURES[f].platforms, 'mac')), - 'flaky': END2END_TESTS[t].flaky, - 'language': 'c', - 'cpu_cost': END2END_TESTS[t].cpu_cost, - } - for f in sorted(END2END_FIXTURES.keys()) - if not END2END_FIXTURES[f].secure - for t in sorted(END2END_TESTS.keys()) - if compatible(f, t) and not END2END_TESTS[t].secure - ], - 'core_end2end_tests': dict( - (t, END2END_TESTS[t].secure) - for t in END2END_TESTS.keys() - ) - } - print(yaml.dump(json)) + if compatible(f, t) and not END2END_TESTS[t].secure], + 'core_end2end_tests': + dict((t, END2END_TESTS[t].secure) for t in END2END_TESTS.keys()) + } + print(yaml.dump(json)) if __name__ == '__main__': - main() + main() diff --git a/test/core/http/test_server.py b/test/core/http/test_server.py index 18a87f1a831..87f0a958d42 100755 --- a/test/core/http/test_server.py +++ b/test/core/http/test_server.py @@ -12,7 +12,6 @@ # 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. - """Server for httpcli_test""" import argparse @@ -21,8 +20,12 @@ import os import ssl import sys -_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.pem')) -_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.key')) +_PEM = os.path.abspath( + os.path.join(os.path.dirname(sys.argv[0]), '../../..', + 'src/core/tsi/test_creds/server1.pem')) +_KEY = os.path.abspath( + os.path.join(os.path.dirname(sys.argv[0]), '../../..', + 'src/core/tsi/test_creds/server1.key')) print _PEM open(_PEM).close() @@ -33,24 +36,30 @@ args = argp.parse_args() print 'server running on port %d' % args.port + class Handler(BaseHTTPServer.BaseHTTPRequestHandler): - def good(self): - self.send_response(200) - self.send_header('Content-Type', 'text/html') - self.end_headers() - self.wfile.write('Hello world!') - self.wfile.write('

This is a test

') - - def do_GET(self): - if self.path == '/get': - self.good() - - def do_POST(self): - content = self.rfile.read(int(self.headers.getheader('content-length'))) - if self.path == '/post' and content == 'hello': - self.good() + + def good(self): + self.send_response(200) + self.send_header('Content-Type', 'text/html') + self.end_headers() + self.wfile.write('Hello world!') + self.wfile.write('

This is a test

') + + def do_GET(self): + if self.path == '/get': + self.good() + + def do_POST(self): + content = self.rfile.read(int(self.headers.getheader('content-length'))) + if self.path == '/post' and content == 'hello': + self.good() + httpd = BaseHTTPServer.HTTPServer(('localhost', args.port), Handler) if args.ssl: - httpd.socket = ssl.wrap_socket(httpd.socket, certfile=_PEM, keyfile=_KEY, server_side=True) + httpd.socket = ssl.wrap_socket(httpd.socket, + certfile=_PEM, + keyfile=_KEY, + server_side=True) httpd.serve_forever() diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index 7cbf9163700..dfc84d35d05 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -12,11 +12,8 @@ # 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. - - """Generates the appropriate build.json data for all the naming tests.""" - import yaml import collections import hashlib @@ -24,128 +21,155 @@ import json _LOCAL_DNS_SERVER_ADDRESS = '127.0.0.1:15353' + def _append_zone_name(name, zone_name): - return '%s.%s' % (name, zone_name) + return '%s.%s' % (name, zone_name) + def _build_expected_addrs_cmd_arg(expected_addrs): - out = [] - for addr in expected_addrs: - out.append('%s,%s' % (addr['address'], str(addr['is_balancer']))) - return ';'.join(out) + out = [] + for addr in expected_addrs: + out.append('%s,%s' % (addr['address'], str(addr['is_balancer']))) + return ';'.join(out) + def _resolver_test_cases(resolver_component_data): - out = [] - for test_case in resolver_component_data['resolver_component_tests']: - target_name = _append_zone_name( - test_case['record_to_resolve'], - resolver_component_data['resolver_tests_common_zone_name']) - out.append({ - 'test_title': target_name, - 'arg_names_and_values': [ - ('target_name', target_name), - ('expected_addrs', - _build_expected_addrs_cmd_arg(test_case['expected_addrs'])), - ('expected_chosen_service_config', - (test_case['expected_chosen_service_config'] or '')), - ('expected_service_config_error', (test_case['expected_service_config_error'] or '')), - ('expected_lb_policy', (test_case['expected_lb_policy'] or '')), - ('enable_srv_queries', test_case['enable_srv_queries']), - ('enable_txt_queries', test_case['enable_txt_queries']), - ('inject_broken_nameserver_list', test_case['inject_broken_nameserver_list']), - ], - }) - return out + out = [] + for test_case in resolver_component_data['resolver_component_tests']: + target_name = _append_zone_name( + test_case['record_to_resolve'], + resolver_component_data['resolver_tests_common_zone_name']) + out.append({ + 'test_title': + target_name, + 'arg_names_and_values': [ + ('target_name', target_name), + ('expected_addrs', + _build_expected_addrs_cmd_arg(test_case['expected_addrs'])), + ('expected_chosen_service_config', + (test_case['expected_chosen_service_config'] or '')), + ('expected_service_config_error', + (test_case['expected_service_config_error'] or '')), + ('expected_lb_policy', (test_case['expected_lb_policy'] or '')), + ('enable_srv_queries', test_case['enable_srv_queries']), + ('enable_txt_queries', test_case['enable_txt_queries']), + ('inject_broken_nameserver_list', + test_case['inject_broken_nameserver_list']), + ], + }) + return out + def main(): - resolver_component_data = '' - with open('test/cpp/naming/resolver_test_record_groups.yaml') as f: - resolver_component_data = yaml.load(f) + resolver_component_data = '' + with open('test/cpp/naming/resolver_test_record_groups.yaml') as f: + resolver_component_data = yaml.load(f) + + json = { + 'resolver_tests_common_zone_name': + resolver_component_data['resolver_tests_common_zone_name'], + 'resolver_component_test_cases': + _resolver_test_cases(resolver_component_data), + 'targets': [{ + 'name': + 'resolver_component_test' + unsecure_build_config_suffix, + 'build': + 'test', + 'language': + 'c++', + 'gtest': + False, + 'run': + False, + 'src': ['test/cpp/naming/resolver_component_test.cc'], + 'platforms': ['linux', 'posix', 'mac', 'windows'], + 'deps': [ + 'dns_test_util', + 'grpc++_test_util' + unsecure_build_config_suffix, + 'grpc_test_util' + unsecure_build_config_suffix, + 'grpc++' + unsecure_build_config_suffix, + 'grpc' + unsecure_build_config_suffix, + 'gpr', + 'grpc++_test_config', + ], + } for unsecure_build_config_suffix in ['_unsecure', '']] + [{ + 'name': + 'resolver_component_tests_runner_invoker' + + unsecure_build_config_suffix, + 'build': + 'test', + 'language': + 'c++', + 'gtest': + False, + 'run': + True, + 'src': + ['test/cpp/naming/resolver_component_tests_runner_invoker.cc'], + 'platforms': ['linux', 'posix', 'mac'], + 'deps': [ + 'grpc++_test_util', + 'grpc_test_util', + 'grpc++', + 'grpc', + 'gpr', + 'grpc++_test_config', + ], + 'args': [ + '--test_bin_name=resolver_component_test%s' % + unsecure_build_config_suffix, + '--running_under_bazel=false', + ], + } for unsecure_build_config_suffix in ['_unsecure', '']] + [{ + 'name': + 'address_sorting_test' + unsecure_build_config_suffix, + 'build': + 'test', + 'language': + 'c++', + 'gtest': + True, + 'run': + True, + 'src': ['test/cpp/naming/address_sorting_test.cc'], + 'platforms': ['linux', 'posix', 'mac', 'windows'], + 'deps': [ + 'grpc++_test_util' + unsecure_build_config_suffix, + 'grpc_test_util' + unsecure_build_config_suffix, + 'grpc++' + unsecure_build_config_suffix, + 'grpc' + unsecure_build_config_suffix, + 'gpr', + 'grpc++_test_config', + ], + } for unsecure_build_config_suffix in ['_unsecure', '']] + [ + { + 'name': + 'cancel_ares_query_test', + 'build': + 'test', + 'language': + 'c++', + 'gtest': + True, + 'run': + True, + 'src': ['test/cpp/naming/cancel_ares_query_test.cc'], + 'platforms': ['linux', 'posix', 'mac', 'windows'], + 'deps': [ + 'dns_test_util', + 'grpc++_test_util', + 'grpc_test_util', + 'grpc++', + 'grpc', + 'gpr', + 'grpc++_test_config', + ], + }, + ] + } - json = { - 'resolver_tests_common_zone_name': resolver_component_data['resolver_tests_common_zone_name'], - 'resolver_component_test_cases': _resolver_test_cases(resolver_component_data), - 'targets': [ - { - 'name': 'resolver_component_test' + unsecure_build_config_suffix, - 'build': 'test', - 'language': 'c++', - 'gtest': False, - 'run': False, - 'src': ['test/cpp/naming/resolver_component_test.cc'], - 'platforms': ['linux', 'posix', 'mac', 'windows'], - 'deps': [ - 'dns_test_util', - 'grpc++_test_util' + unsecure_build_config_suffix, - 'grpc_test_util' + unsecure_build_config_suffix, - 'grpc++' + unsecure_build_config_suffix, - 'grpc' + unsecure_build_config_suffix, - 'gpr', - 'grpc++_test_config', - ], - } for unsecure_build_config_suffix in ['_unsecure', ''] - ] + [ - { - 'name': 'resolver_component_tests_runner_invoker' + unsecure_build_config_suffix, - 'build': 'test', - 'language': 'c++', - 'gtest': False, - 'run': True, - 'src': ['test/cpp/naming/resolver_component_tests_runner_invoker.cc'], - 'platforms': ['linux', 'posix', 'mac'], - 'deps': [ - 'grpc++_test_util', - 'grpc_test_util', - 'grpc++', - 'grpc', - 'gpr', - 'grpc++_test_config', - ], - 'args': [ - '--test_bin_name=resolver_component_test%s' % unsecure_build_config_suffix, - '--running_under_bazel=false', - ], - } for unsecure_build_config_suffix in ['_unsecure', ''] - ] + [ - { - 'name': 'address_sorting_test' + unsecure_build_config_suffix, - 'build': 'test', - 'language': 'c++', - 'gtest': True, - 'run': True, - 'src': ['test/cpp/naming/address_sorting_test.cc'], - 'platforms': ['linux', 'posix', 'mac', 'windows'], - 'deps': [ - 'grpc++_test_util' + unsecure_build_config_suffix, - 'grpc_test_util' + unsecure_build_config_suffix, - 'grpc++' + unsecure_build_config_suffix, - 'grpc' + unsecure_build_config_suffix, - 'gpr', - 'grpc++_test_config', - ], - } for unsecure_build_config_suffix in ['_unsecure', ''] - ] + [ - { - 'name': 'cancel_ares_query_test', - 'build': 'test', - 'language': 'c++', - 'gtest': True, - 'run': True, - 'src': ['test/cpp/naming/cancel_ares_query_test.cc'], - 'platforms': ['linux', 'posix', 'mac', 'windows'], - 'deps': [ - 'dns_test_util', - 'grpc++_test_util', - 'grpc_test_util', - 'grpc++', - 'grpc', - 'gpr', - 'grpc++_test_config', - ], - }, - ] - } + print(yaml.dump(json)) - print(yaml.dump(json)) if __name__ == '__main__': - main() + main() diff --git a/test/cpp/naming/manual_run_resolver_component_test.py b/test/cpp/naming/manual_run_resolver_component_test.py index fb2157741a0..fc6812bf591 100644 --- a/test/cpp/naming/manual_run_resolver_component_test.py +++ b/test/cpp/naming/manual_run_resolver_component_test.py @@ -27,10 +27,16 @@ _DNS_SERVER_PORT = 15353 subprocess.call([ sys.executable, 'test\\cpp\\naming\\resolver_component_tests_runner.py', - '--test_bin_path', 'cmake\\build\\%s\\resolver_component_test.exe' % _MSBUILD_CONFIG, - '--dns_server_bin_path', 'test\\cpp\\naming\\utils\\dns_server.py', - '--records_config_path', 'test\\cpp\\naming\\resolver_test_record_groups.yaml', - '--dns_server_port', str(_DNS_SERVER_PORT), - '--dns_resolver_bin_path', 'test\\cpp\\naming\\utils\\dns_resolver.py', - '--tcp_connect_bin_path', 'test\\cpp\\naming\\utils\\tcp_connect.py', + '--test_bin_path', + 'cmake\\build\\%s\\resolver_component_test.exe' % _MSBUILD_CONFIG, + '--dns_server_bin_path', + 'test\\cpp\\naming\\utils\\dns_server.py', + '--records_config_path', + 'test\\cpp\\naming\\resolver_test_record_groups.yaml', + '--dns_server_port', + str(_DNS_SERVER_PORT), + '--dns_resolver_bin_path', + 'test\\cpp\\naming\\utils\\dns_resolver.py', + '--tcp_connect_bin_path', + 'test\\cpp\\naming\\utils\\tcp_connect.py', ]) diff --git a/test/cpp/naming/utils/dns_resolver.py b/test/cpp/naming/utils/dns_resolver.py index 74f4ca23517..53f2301ca6e 100755 --- a/test/cpp/naming/utils/dns_resolver.py +++ b/test/cpp/naming/utils/dns_resolver.py @@ -12,7 +12,6 @@ # 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. - """Makes DNS queries for A records to specified servers""" import argparse @@ -24,27 +23,43 @@ import twisted.internet.reactor as reactor def main(): - argp = argparse.ArgumentParser(description='Make DNS queries for A records') - argp.add_argument('-s', '--server_host', default='127.0.0.1', type=str, - help='Host for DNS server to listen on for TCP and UDP.') - argp.add_argument('-p', '--server_port', default=53, type=int, - help='Port that the DNS server is listening on.') - argp.add_argument('-n', '--qname', default=None, type=str, - help=('Name of the record to query for. ')) - argp.add_argument('-t', '--timeout', default=1, type=int, - help=('Force process exit after this number of seconds.')) - args = argp.parse_args() - def OnResolverResultAvailable(result): - answers, authority, additional = result - for a in answers: - print(a.payload) - def BeginQuery(reactor, qname): - servers = [(args.server_host, args.server_port)] - resolver = client.Resolver(servers=servers) - deferred_result = resolver.lookupAddress(args.qname) - deferred_result.addCallback(OnResolverResultAvailable) - return deferred_result - task.react(BeginQuery, [args.qname]) + argp = argparse.ArgumentParser(description='Make DNS queries for A records') + argp.add_argument('-s', + '--server_host', + default='127.0.0.1', + type=str, + help='Host for DNS server to listen on for TCP and UDP.') + argp.add_argument('-p', + '--server_port', + default=53, + type=int, + help='Port that the DNS server is listening on.') + argp.add_argument('-n', + '--qname', + default=None, + type=str, + help=('Name of the record to query for. ')) + argp.add_argument('-t', + '--timeout', + default=1, + type=int, + help=('Force process exit after this number of seconds.')) + args = argp.parse_args() + + def OnResolverResultAvailable(result): + answers, authority, additional = result + for a in answers: + print(a.payload) + + def BeginQuery(reactor, qname): + servers = [(args.server_host, args.server_port)] + resolver = client.Resolver(servers=servers) + deferred_result = resolver.lookupAddress(args.qname) + deferred_result.addCallback(OnResolverResultAvailable) + return deferred_result + + task.react(BeginQuery, [args.qname]) + if __name__ == '__main__': - main() + main() diff --git a/test/cpp/naming/utils/dns_server.py b/test/cpp/naming/utils/dns_server.py index bf11d14c30c..6b13e68ee45 100755 --- a/test/cpp/naming/utils/dns_server.py +++ b/test/cpp/naming/utils/dns_server.py @@ -12,7 +12,6 @@ # 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. - """Starts a local DNS server for use in tests""" import argparse @@ -37,124 +36,148 @@ from twisted.names import client, server, common, authority, dns import argparse import platform -_SERVER_HEALTH_CHECK_RECORD_NAME = 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp' # missing end '.' for twisted syntax +_SERVER_HEALTH_CHECK_RECORD_NAME = 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp' # missing end '.' for twisted syntax _SERVER_HEALTH_CHECK_RECORD_DATA = '123.123.123.123' + class NoFileAuthority(authority.FileAuthority): - def __init__(self, soa, records): - # skip FileAuthority - common.ResolverBase.__init__(self) - self.soa = soa - self.records = records + + def __init__(self, soa, records): + # skip FileAuthority + common.ResolverBase.__init__(self) + self.soa = soa + self.records = records + def start_local_dns_server(args): - all_records = {} - def _push_record(name, r): - print('pushing record: |%s|' % name) - if all_records.get(name) is not None: - all_records[name].append(r) - return - all_records[name] = [r] - - def _maybe_split_up_txt_data(name, txt_data, r_ttl): - start = 0 - txt_data_list = [] - while len(txt_data[start:]) > 0: - next_read = len(txt_data[start:]) - if next_read > 255: - next_read = 255 - txt_data_list.append(txt_data[start:start+next_read]) - start += next_read - _push_record(name, dns.Record_TXT(*txt_data_list, ttl=r_ttl)) - - with open(args.records_config_path) as config: - test_records_config = yaml.load(config) - common_zone_name = test_records_config['resolver_tests_common_zone_name'] - for group in test_records_config['resolver_component_tests']: - for name in group['records'].keys(): - for record in group['records'][name]: - r_type = record['type'] - r_data = record['data'] - r_ttl = int(record['TTL']) - record_full_name = '%s.%s' % (name, common_zone_name) - assert record_full_name[-1] == '.' - record_full_name = record_full_name[:-1] - if r_type == 'A': - _push_record(record_full_name, dns.Record_A(r_data, ttl=r_ttl)) - if r_type == 'AAAA': - _push_record(record_full_name, dns.Record_AAAA(r_data, ttl=r_ttl)) - if r_type == 'SRV': - p, w, port, target = r_data.split(' ') - p = int(p) - w = int(w) - port = int(port) - target_full_name = '%s.%s' % (target, common_zone_name) - r_data = '%s %s %s %s' % (p, w, port, target_full_name) - _push_record(record_full_name, dns.Record_SRV(p, w, port, target_full_name, ttl=r_ttl)) - if r_type == 'TXT': - _maybe_split_up_txt_data(record_full_name, r_data, r_ttl) - # Add an optional IPv4 record is specified - if args.add_a_record: - extra_host, extra_host_ipv4 = args.add_a_record.split(':') - _push_record(extra_host, dns.Record_A(extra_host_ipv4, ttl=0)) - # Server health check record - _push_record(_SERVER_HEALTH_CHECK_RECORD_NAME, dns.Record_A(_SERVER_HEALTH_CHECK_RECORD_DATA, ttl=0)) - soa_record = dns.Record_SOA(mname = common_zone_name) - test_domain_com = NoFileAuthority( - soa = (common_zone_name, soa_record), - records = all_records, - ) - server = twisted.names.server.DNSServerFactory( - authorities=[test_domain_com], verbose=2) - server.noisy = 2 - twisted.internet.reactor.listenTCP(args.port, server) - dns_proto = twisted.names.dns.DNSDatagramProtocol(server) - dns_proto.noisy = 2 - twisted.internet.reactor.listenUDP(args.port, dns_proto) - print('starting local dns server on 127.0.0.1:%s' % args.port) - print('starting twisted.internet.reactor') - twisted.internet.reactor.suggestThreadPoolSize(1) - twisted.internet.reactor.run() + all_records = {} + + def _push_record(name, r): + print('pushing record: |%s|' % name) + if all_records.get(name) is not None: + all_records[name].append(r) + return + all_records[name] = [r] + + def _maybe_split_up_txt_data(name, txt_data, r_ttl): + start = 0 + txt_data_list = [] + while len(txt_data[start:]) > 0: + next_read = len(txt_data[start:]) + if next_read > 255: + next_read = 255 + txt_data_list.append(txt_data[start:start + next_read]) + start += next_read + _push_record(name, dns.Record_TXT(*txt_data_list, ttl=r_ttl)) + + with open(args.records_config_path) as config: + test_records_config = yaml.load(config) + common_zone_name = test_records_config['resolver_tests_common_zone_name'] + for group in test_records_config['resolver_component_tests']: + for name in group['records'].keys(): + for record in group['records'][name]: + r_type = record['type'] + r_data = record['data'] + r_ttl = int(record['TTL']) + record_full_name = '%s.%s' % (name, common_zone_name) + assert record_full_name[-1] == '.' + record_full_name = record_full_name[:-1] + if r_type == 'A': + _push_record(record_full_name, + dns.Record_A(r_data, ttl=r_ttl)) + if r_type == 'AAAA': + _push_record(record_full_name, + dns.Record_AAAA(r_data, ttl=r_ttl)) + if r_type == 'SRV': + p, w, port, target = r_data.split(' ') + p = int(p) + w = int(w) + port = int(port) + target_full_name = '%s.%s' % (target, common_zone_name) + r_data = '%s %s %s %s' % (p, w, port, target_full_name) + _push_record( + record_full_name, + dns.Record_SRV(p, w, port, target_full_name, ttl=r_ttl)) + if r_type == 'TXT': + _maybe_split_up_txt_data(record_full_name, r_data, r_ttl) + # Add an optional IPv4 record is specified + if args.add_a_record: + extra_host, extra_host_ipv4 = args.add_a_record.split(':') + _push_record(extra_host, dns.Record_A(extra_host_ipv4, ttl=0)) + # Server health check record + _push_record(_SERVER_HEALTH_CHECK_RECORD_NAME, + dns.Record_A(_SERVER_HEALTH_CHECK_RECORD_DATA, ttl=0)) + soa_record = dns.Record_SOA(mname=common_zone_name) + test_domain_com = NoFileAuthority( + soa=(common_zone_name, soa_record), + records=all_records, + ) + server = twisted.names.server.DNSServerFactory( + authorities=[test_domain_com], verbose=2) + server.noisy = 2 + twisted.internet.reactor.listenTCP(args.port, server) + dns_proto = twisted.names.dns.DNSDatagramProtocol(server) + dns_proto.noisy = 2 + twisted.internet.reactor.listenUDP(args.port, dns_proto) + print('starting local dns server on 127.0.0.1:%s' % args.port) + print('starting twisted.internet.reactor') + twisted.internet.reactor.suggestThreadPoolSize(1) + twisted.internet.reactor.run() + def _quit_on_signal(signum, _frame): - print('Received SIGNAL %d. Quitting with exit code 0' % signum) - twisted.internet.reactor.stop() - sys.stdout.flush() - sys.exit(0) + print('Received SIGNAL %d. Quitting with exit code 0' % signum) + twisted.internet.reactor.stop() + sys.stdout.flush() + sys.exit(0) + def flush_stdout_loop(): - num_timeouts_so_far = 0 - sleep_time = 1 - # Prevent zombies. Tests that use this server are short-lived. - max_timeouts = 60 * 10 - while num_timeouts_so_far < max_timeouts: - sys.stdout.flush() - time.sleep(sleep_time) - num_timeouts_so_far += 1 - print('Process timeout reached, or cancelled. Exitting 0.') - os.kill(os.getpid(), signal.SIGTERM) + num_timeouts_so_far = 0 + sleep_time = 1 + # Prevent zombies. Tests that use this server are short-lived. + max_timeouts = 60 * 10 + while num_timeouts_so_far < max_timeouts: + sys.stdout.flush() + time.sleep(sleep_time) + num_timeouts_so_far += 1 + print('Process timeout reached, or cancelled. Exitting 0.') + os.kill(os.getpid(), signal.SIGTERM) + def main(): - argp = argparse.ArgumentParser(description='Local DNS Server for resolver tests') - argp.add_argument('-p', '--port', default=None, type=int, - help='Port for DNS server to listen on for TCP and UDP.') - argp.add_argument('-r', '--records_config_path', default=None, type=str, - help=('Directory of resolver_test_record_groups.yaml file. ' - 'Defaults to path needed when the test is invoked as part ' - 'of run_tests.py.')) - argp.add_argument('--add_a_record', default=None, type=str, - help=('Add an A record via the command line. Useful for when we ' - 'need to serve a one-off A record that is under a ' - 'different domain then the rest the records configured in ' - '--records_config_path (which all need to be under the ' - 'same domain). Format: :')) - args = argp.parse_args() - signal.signal(signal.SIGTERM, _quit_on_signal) - signal.signal(signal.SIGINT, _quit_on_signal) - output_flush_thread = threading.Thread(target=flush_stdout_loop) - output_flush_thread.setDaemon(True) - output_flush_thread.start() - start_local_dns_server(args) + argp = argparse.ArgumentParser( + description='Local DNS Server for resolver tests') + argp.add_argument('-p', + '--port', + default=None, + type=int, + help='Port for DNS server to listen on for TCP and UDP.') + argp.add_argument( + '-r', + '--records_config_path', + default=None, + type=str, + help=('Directory of resolver_test_record_groups.yaml file. ' + 'Defaults to path needed when the test is invoked as part ' + 'of run_tests.py.')) + argp.add_argument( + '--add_a_record', + default=None, + type=str, + help=('Add an A record via the command line. Useful for when we ' + 'need to serve a one-off A record that is under a ' + 'different domain then the rest the records configured in ' + '--records_config_path (which all need to be under the ' + 'same domain). Format: :')) + args = argp.parse_args() + signal.signal(signal.SIGTERM, _quit_on_signal) + signal.signal(signal.SIGINT, _quit_on_signal) + output_flush_thread = threading.Thread(target=flush_stdout_loop) + output_flush_thread.setDaemon(True) + output_flush_thread.start() + start_local_dns_server(args) + if __name__ == '__main__': - main() + main() diff --git a/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py b/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py index 97171e21da8..217af5c0eb0 100755 --- a/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py +++ b/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py @@ -13,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - import argparse import subprocess import os @@ -23,16 +22,28 @@ import time import signal import yaml -argp = argparse.ArgumentParser(description='Runs a DNS server for LB interop tests') -argp.add_argument('-l', '--grpclb_ips', default=None, type=str, +argp = argparse.ArgumentParser( + description='Runs a DNS server for LB interop tests') +argp.add_argument('-l', + '--grpclb_ips', + default=None, + type=str, help='Comma-separated list of IP addresses of balancers') -argp.add_argument('-f', '--fallback_ips', default=None, type=str, - help='Comma-separated list of IP addresses of fallback servers') -argp.add_argument('-c', '--cause_no_error_no_data_for_balancer_a_record', - default=False, action='store_const', const=True, - help=('Used for testing the case in which the grpclb ' - 'balancer A record lookup results in a DNS NOERROR response ' - 'but with no ANSWER section i.e. no addresses')) +argp.add_argument( + '-f', + '--fallback_ips', + default=None, + type=str, + help='Comma-separated list of IP addresses of fallback servers') +argp.add_argument( + '-c', + '--cause_no_error_no_data_for_balancer_a_record', + default=False, + action='store_const', + const=True, + help=('Used for testing the case in which the grpclb ' + 'balancer A record lookup results in a DNS NOERROR response ' + 'but with no ANSWER section i.e. no addresses')) args = argp.parse_args() balancer_records = [] @@ -55,26 +66,22 @@ if fallback_ips[0]: }) records_config_yaml = { 'resolver_tests_common_zone_name': - 'test.google.fr.', + 'test.google.fr.', 'resolver_component_tests': [{ 'records': { - '_grpclb._tcp.server': [ - { - 'TTL': '2100', - 'data': '0 0 12000 balancer', - 'type': 'SRV' - }, - ], - 'balancer': - balancer_records, - 'server': - fallback_records, + '_grpclb._tcp.server': [{ + 'TTL': '2100', + 'data': '0 0 12000 balancer', + 'type': 'SRV' + },], + 'balancer': balancer_records, + 'server': fallback_records, } }] } if args.cause_no_error_no_data_for_balancer_a_record: - balancer_records = records_config_yaml[ - 'resolver_component_tests'][0]['records']['balancer'] + balancer_records = records_config_yaml['resolver_component_tests'][0][ + 'records']['balancer'] assert not balancer_records # Insert a TXT record at the balancer.test.google.fr. domain. # This TXT record won't actually be resolved or used by gRPC clients; @@ -103,7 +110,9 @@ with open(records_config_path, 'r') as records_config_generated: # TODO(apolcyn): should metadata.google.internal always resolve # to 169.254.169.254? subprocess.check_output([ - '/var/local/git/grpc/test/cpp/naming/utils/dns_server.py', '--port=53', - '--records_config_path', records_config_path, + '/var/local/git/grpc/test/cpp/naming/utils/dns_server.py', + '--port=53', + '--records_config_path', + records_config_path, '--add_a_record=metadata.google.internal:169.254.169.254', ]) diff --git a/test/cpp/naming/utils/tcp_connect.py b/test/cpp/naming/utils/tcp_connect.py index f3ad5891fdb..5f7273f4a97 100755 --- a/test/cpp/naming/utils/tcp_connect.py +++ b/test/cpp/naming/utils/tcp_connect.py @@ -12,7 +12,6 @@ # 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. - """Opens a TCP connection to a specified server and then exits.""" import argparse @@ -23,16 +22,27 @@ import sys def main(): - argp = argparse.ArgumentParser(description='Open a TCP handshake to a server') - argp.add_argument('-s', '--server_host', default=None, type=str, - help='Server host name or IP.') - argp.add_argument('-p', '--server_port', default=0, type=int, - help='Port that the server is listening on.') - argp.add_argument('-t', '--timeout', default=1, type=int, - help='Force process exit after this number of seconds.') - args = argp.parse_args() - socket.create_connection([args.server_host, args.server_port], - timeout=args.timeout) + argp = argparse.ArgumentParser( + description='Open a TCP handshake to a server') + argp.add_argument('-s', + '--server_host', + default=None, + type=str, + help='Server host name or IP.') + argp.add_argument('-p', + '--server_port', + default=0, + type=int, + help='Port that the server is listening on.') + argp.add_argument('-t', + '--timeout', + default=1, + type=int, + help='Force process exit after this number of seconds.') + args = argp.parse_args() + socket.create_connection([args.server_host, args.server_port], + timeout=args.timeout) + if __name__ == '__main__': - main() + main() diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index 8ca0dc6a620..b69d8dbc932 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -22,113 +22,171 @@ import sys import os import yaml -run_tests_root = os.path.abspath(os.path.join( - os.path.dirname(sys.argv[0]), - '../../../tools/run_tests')) +run_tests_root = os.path.abspath( + os.path.join(os.path.dirname(sys.argv[0]), '../../../tools/run_tests')) sys.path.append(run_tests_root) import performance.scenario_config as scenario_config -configs_from_yaml = yaml.load(open(os.path.join(os.path.dirname(sys.argv[0]), '../../../build.yaml')))['configs'].keys() +configs_from_yaml = yaml.load( + open(os.path.join(os.path.dirname(sys.argv[0]), + '../../../build.yaml')))['configs'].keys() + def mutate_scenario(scenario_json, is_tsan): - # tweak parameters to get fast test times - scenario_json = dict(scenario_json) - scenario_json['warmup_seconds'] = 0 - scenario_json['benchmark_seconds'] = 1 - outstanding_rpcs_divisor = 1 - if is_tsan and ( - scenario_json['client_config']['client_type'] == 'SYNC_CLIENT' or - scenario_json['server_config']['server_type'] == 'SYNC_SERVER'): - outstanding_rpcs_divisor = 10 - scenario_json['client_config']['outstanding_rpcs_per_channel'] = max(1, - int(scenario_json['client_config']['outstanding_rpcs_per_channel'] / outstanding_rpcs_divisor)) - return scenario_json + # tweak parameters to get fast test times + scenario_json = dict(scenario_json) + scenario_json['warmup_seconds'] = 0 + scenario_json['benchmark_seconds'] = 1 + outstanding_rpcs_divisor = 1 + if is_tsan and ( + scenario_json['client_config']['client_type'] == 'SYNC_CLIENT' or + scenario_json['server_config']['server_type'] == 'SYNC_SERVER'): + outstanding_rpcs_divisor = 10 + scenario_json['client_config']['outstanding_rpcs_per_channel'] = max( + 1, + int(scenario_json['client_config']['outstanding_rpcs_per_channel'] / + outstanding_rpcs_divisor)) + return scenario_json + def _scenario_json_string(scenario_json, is_tsan): - scenarios_json = {'scenarios': [scenario_config.remove_nonproto_fields(mutate_scenario(scenario_json, is_tsan))]} - return json.dumps(scenarios_json) + scenarios_json = { + 'scenarios': [ + scenario_config.remove_nonproto_fields( + mutate_scenario(scenario_json, is_tsan)) + ] + } + return json.dumps(scenarios_json) + def threads_required(scenario_json, where, is_tsan): - scenario_json = mutate_scenario(scenario_json, is_tsan) - if scenario_json['%s_config' % where]['%s_type' % where] == 'ASYNC_%s' % where.upper(): - return scenario_json['%s_config' % where].get('async_%s_threads' % where, 0) - return scenario_json['client_config']['outstanding_rpcs_per_channel'] * scenario_json['client_config']['client_channels'] + scenario_json = mutate_scenario(scenario_json, is_tsan) + if scenario_json['%s_config' % where]['%s_type' % + where] == 'ASYNC_%s' % where.upper(): + return scenario_json['%s_config' % where].get( + 'async_%s_threads' % where, 0) + return scenario_json['client_config'][ + 'outstanding_rpcs_per_channel'] * scenario_json['client_config'][ + 'client_channels'] + def guess_cpu(scenario_json, is_tsan): - client = threads_required(scenario_json, 'client', is_tsan) - server = threads_required(scenario_json, 'server', is_tsan) - # make an arbitrary guess if set to auto-detect - # about the size of the jenkins instances we have for unit tests - if client == 0 or server == 0: return 'capacity' - return (scenario_json['num_clients'] * client + - scenario_json['num_servers'] * server) + client = threads_required(scenario_json, 'client', is_tsan) + server = threads_required(scenario_json, 'server', is_tsan) + # make an arbitrary guess if set to auto-detect + # about the size of the jenkins instances we have for unit tests + if client == 0 or server == 0: return 'capacity' + return (scenario_json['num_clients'] * client + + scenario_json['num_servers'] * server) + def maybe_exclude_gcov(scenario_json): - if scenario_json['client_config']['client_channels'] > 100: - return ['gcov'] - return [] + if scenario_json['client_config']['client_channels'] > 100: + return ['gcov'] + return [] + def generate_yaml(): - return { - 'tests': [ - { - 'name': 'json_run_localhost', - 'shortname': 'json_run_localhost:%s' % scenario_json['name'], - 'args': ['--scenarios_json', _scenario_json_string(scenario_json, False)], - 'ci_platforms': ['linux'], - 'platforms': ['linux'], - 'flaky': False, - 'language': 'c++', - 'boringssl': True, - 'defaults': 'boringssl', - 'cpu_cost': guess_cpu(scenario_json, False), - 'exclude_configs': ['tsan', 'asan'] + maybe_exclude_gcov(scenario_json), - 'timeout_seconds': 2*60, - 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), - 'auto_timeout_scaling': False - } - for scenario_json in scenario_config.CXXLanguage().scenarios() - if 'scalable' in scenario_json.get('CATEGORIES', []) - ] + [ - { - 'name': 'qps_json_driver', - 'shortname': 'qps_json_driver:inproc_%s' % scenario_json['name'], - 'args': ['--run_inproc', '--scenarios_json', _scenario_json_string(scenario_json, False)], - 'ci_platforms': ['linux'], - 'platforms': ['linux'], - 'flaky': False, - 'language': 'c++', - 'boringssl': True, - 'defaults': 'boringssl', - 'cpu_cost': guess_cpu(scenario_json, False), - 'exclude_configs': ['tsan', 'asan'], - 'timeout_seconds': 6*60, - 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []) - } - for scenario_json in scenario_config.CXXLanguage().scenarios() - if 'inproc' in scenario_json.get('CATEGORIES', []) - ] + [ - { - 'name': 'json_run_localhost', - 'shortname': 'json_run_localhost:%s_low_thread_count' % scenario_json['name'], - 'args': ['--scenarios_json', _scenario_json_string(scenario_json, True)], - 'ci_platforms': ['linux'], - 'platforms': ['linux'], - 'flaky': False, - 'language': 'c++', - 'boringssl': True, - 'defaults': 'boringssl', - 'cpu_cost': guess_cpu(scenario_json, True), - 'exclude_configs': sorted(c for c in configs_from_yaml if c not in ('tsan', 'asan')), - 'timeout_seconds': 10*60, - 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), - 'auto_timeout_scaling': False - } - for scenario_json in scenario_config.CXXLanguage().scenarios() - if 'scalable' in scenario_json.get('CATEGORIES', []) - ] - } + return { + 'tests': + [{ + 'name': + 'json_run_localhost', + 'shortname': + 'json_run_localhost:%s' % scenario_json['name'], + 'args': [ + '--scenarios_json', + _scenario_json_string(scenario_json, False) + ], + 'ci_platforms': ['linux'], + 'platforms': ['linux'], + 'flaky': + False, + 'language': + 'c++', + 'boringssl': + True, + 'defaults': + 'boringssl', + 'cpu_cost': + guess_cpu(scenario_json, False), + 'exclude_configs': ['tsan', 'asan'] + + maybe_exclude_gcov(scenario_json), + 'timeout_seconds': + 2 * 60, + 'excluded_poll_engines': + scenario_json.get('EXCLUDED_POLL_ENGINES', []), + 'auto_timeout_scaling': + False + } + for scenario_json in scenario_config.CXXLanguage().scenarios() + if 'scalable' in scenario_json.get('CATEGORIES', [])] + + [{ + 'name': + 'qps_json_driver', + 'shortname': + 'qps_json_driver:inproc_%s' % scenario_json['name'], + 'args': [ + '--run_inproc', '--scenarios_json', + _scenario_json_string(scenario_json, False) + ], + 'ci_platforms': ['linux'], + 'platforms': ['linux'], + 'flaky': + False, + 'language': + 'c++', + 'boringssl': + True, + 'defaults': + 'boringssl', + 'cpu_cost': + guess_cpu(scenario_json, False), + 'exclude_configs': ['tsan', 'asan'], + 'timeout_seconds': + 6 * 60, + 'excluded_poll_engines': + scenario_json.get('EXCLUDED_POLL_ENGINES', []) + } + for scenario_json in scenario_config.CXXLanguage().scenarios() + if 'inproc' in scenario_json.get('CATEGORIES', [])] + + [{ + 'name': + 'json_run_localhost', + 'shortname': + 'json_run_localhost:%s_low_thread_count' % + scenario_json['name'], + 'args': [ + '--scenarios_json', + _scenario_json_string(scenario_json, True) + ], + 'ci_platforms': ['linux'], + 'platforms': ['linux'], + 'flaky': + False, + 'language': + 'c++', + 'boringssl': + True, + 'defaults': + 'boringssl', + 'cpu_cost': + guess_cpu(scenario_json, True), + 'exclude_configs': + sorted(c + for c in configs_from_yaml + if c not in ('tsan', 'asan')), + 'timeout_seconds': + 10 * 60, + 'excluded_poll_engines': + scenario_json.get('EXCLUDED_POLL_ENGINES', []), + 'auto_timeout_scaling': + False + } + for scenario_json in scenario_config.CXXLanguage().scenarios() + if 'scalable' in scenario_json.get('CATEGORIES', [])] + } print(yaml.dump(generate_yaml())) diff --git a/test/cpp/qps/json_run_localhost_scenario_gen.py b/test/cpp/qps/json_run_localhost_scenario_gen.py index ab14f0e4a51..8fe6848bdfb 100755 --- a/test/cpp/qps/json_run_localhost_scenario_gen.py +++ b/test/cpp/qps/json_run_localhost_scenario_gen.py @@ -17,6 +17,7 @@ import gen_build_yaml as gen import json + def generate_args(): all_scenario_set = gen.generate_yaml() all_scenario_set = all_scenario_set['tests'] @@ -34,6 +35,8 @@ def generate_args(): serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') with open('json_run_localhost_scenarios.bzl', 'wb') as f: f.write('"""Scenarios run on localhost."""\n\n') - f.write('JSON_RUN_LOCALHOST_SCENARIOS = ' + serialized_scenarios_str + '\n') + f.write('JSON_RUN_LOCALHOST_SCENARIOS = ' + serialized_scenarios_str + + '\n') + generate_args() diff --git a/test/cpp/qps/qps_json_driver_scenario_gen.py b/test/cpp/qps/qps_json_driver_scenario_gen.py index 2b66c69d8ad..01970a96b1d 100755 --- a/test/cpp/qps/qps_json_driver_scenario_gen.py +++ b/test/cpp/qps/qps_json_driver_scenario_gen.py @@ -17,6 +17,7 @@ import gen_build_yaml as gen import json + def generate_args(): all_scenario_set = gen.generate_yaml() all_scenario_set = all_scenario_set['tests'] @@ -34,6 +35,8 @@ def generate_args(): serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') with open('qps_json_driver_scenarios.bzl', 'w') as f: f.write('"""Scenarios of qps driver."""\n\n') - f.write('QPS_JSON_DRIVER_SCENARIOS = ' + serialized_scenarios_str + '\n') + f.write('QPS_JSON_DRIVER_SCENARIOS = ' + serialized_scenarios_str + + '\n') + generate_args() diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py index 6b55b8963db..44884692bf1 100644 --- a/test/http2_test/http2_base_server.py +++ b/test/http2_test/http2_base_server.py @@ -26,173 +26,204 @@ _READ_CHUNK_SIZE = 16384 _GRPC_HEADER_SIZE = 5 _MIN_SETTINGS_MAX_FRAME_SIZE = 16384 + class H2ProtocolBaseServer(twisted.internet.protocol.Protocol): - def __init__(self): - self._conn = h2.connection.H2Connection(client_side=False) - self._recv_buffer = {} - self._handlers = {} - self._handlers['ConnectionMade'] = self.on_connection_made_default - self._handlers['DataReceived'] = self.on_data_received_default - self._handlers['WindowUpdated'] = self.on_window_update_default - self._handlers['RequestReceived'] = self.on_request_received_default - self._handlers['SendDone'] = self.on_send_done_default - self._handlers['ConnectionLost'] = self.on_connection_lost - self._handlers['PingAcknowledged'] = self.on_ping_acknowledged_default - self._stream_status = {} - self._send_remaining = {} - self._outstanding_pings = 0 - - def set_handlers(self, handlers): - self._handlers = handlers - - def connectionMade(self): - self._handlers['ConnectionMade']() - - def connectionLost(self, reason): - self._handlers['ConnectionLost'](reason) - - def on_connection_made_default(self): - logging.info('Connection Made') - self._conn.initiate_connection() - self.transport.setTcpNoDelay(True) - self.transport.write(self._conn.data_to_send()) - - def on_connection_lost(self, reason): - logging.info('Disconnected %s' % reason) - - def dataReceived(self, data): - try: - events = self._conn.receive_data(data) - except h2.exceptions.ProtocolError: - # this try/except block catches exceptions due to race between sending - # GOAWAY and processing a response in flight. - return - if self._conn.data_to_send: - self.transport.write(self._conn.data_to_send()) - for event in events: - if isinstance(event, h2.events.RequestReceived) and self._handlers.has_key('RequestReceived'): - logging.info('RequestReceived Event for stream: %d' % event.stream_id) - self._handlers['RequestReceived'](event) - elif isinstance(event, h2.events.DataReceived) and self._handlers.has_key('DataReceived'): - logging.info('DataReceived Event for stream: %d' % event.stream_id) - self._handlers['DataReceived'](event) - elif isinstance(event, h2.events.WindowUpdated) and self._handlers.has_key('WindowUpdated'): - logging.info('WindowUpdated Event for stream: %d' % event.stream_id) - self._handlers['WindowUpdated'](event) - elif isinstance(event, h2.events.PingAcknowledged) and self._handlers.has_key('PingAcknowledged'): - logging.info('PingAcknowledged Event') - self._handlers['PingAcknowledged'](event) - self.transport.write(self._conn.data_to_send()) - - def on_ping_acknowledged_default(self, event): - logging.info('ping acknowledged') - self._outstanding_pings -= 1 - - def on_data_received_default(self, event): - self._conn.acknowledge_received_data(len(event.data), event.stream_id) - self._recv_buffer[event.stream_id] += event.data - - def on_request_received_default(self, event): - self._recv_buffer[event.stream_id] = '' - self._stream_id = event.stream_id - self._stream_status[event.stream_id] = True - self._conn.send_headers( - stream_id=event.stream_id, - headers=[ - (':status', '200'), - ('content-type', 'application/grpc'), - ('grpc-encoding', 'identity'), - ('grpc-accept-encoding', 'identity,deflate,gzip'), - ], - ) - self.transport.write(self._conn.data_to_send()) - - def on_window_update_default(self, _, pad_length=None, read_chunk_size=_READ_CHUNK_SIZE): - # try to resume sending on all active streams (update might be for connection) - for stream_id in self._send_remaining: - self.default_send(stream_id, pad_length=pad_length, read_chunk_size=read_chunk_size) - - def send_reset_stream(self): - self._conn.reset_stream(self._stream_id) - self.transport.write(self._conn.data_to_send()) - - def setup_send(self, data_to_send, stream_id, pad_length=None, read_chunk_size=_READ_CHUNK_SIZE): - logging.info('Setting up data to send for stream_id: %d' % stream_id) - self._send_remaining[stream_id] = len(data_to_send) - self._send_offset = 0 - self._data_to_send = data_to_send - self.default_send(stream_id, pad_length=pad_length, read_chunk_size=read_chunk_size) - - def default_send(self, stream_id, pad_length=None, read_chunk_size=_READ_CHUNK_SIZE): - if not self._send_remaining.has_key(stream_id): - # not setup to send data yet - return - - while self._send_remaining[stream_id] > 0: - lfcw = self._conn.local_flow_control_window(stream_id) - padding_bytes = pad_length + 1 if pad_length is not None else 0 - if lfcw - padding_bytes <= 0: - logging.info('Stream %d. lfcw: %d. padding bytes: %d. not enough quota yet' % (stream_id, lfcw, padding_bytes)) - break - chunk_size = min(lfcw - padding_bytes, read_chunk_size) - bytes_to_send = min(chunk_size, self._send_remaining[stream_id]) - logging.info('flow_control_window = %d. sending [%d:%d] stream_id %d. includes %d total padding bytes' % - (lfcw, self._send_offset, self._send_offset + bytes_to_send + padding_bytes, - stream_id, padding_bytes)) - # The receiver might allow sending frames larger than the http2 minimum - # max frame size (16384), but this test should never send more than 16384 - # for simplicity (which is always legal). - if bytes_to_send + padding_bytes > _MIN_SETTINGS_MAX_FRAME_SIZE: - raise ValueError("overload: sending %d" % (bytes_to_send + padding_bytes)) - data = self._data_to_send[self._send_offset : self._send_offset + bytes_to_send] - try: - self._conn.send_data(stream_id, data, end_stream=False, pad_length=pad_length) - except h2.exceptions.ProtocolError: - logging.info('Stream %d is closed' % stream_id) - break - self._send_remaining[stream_id] -= bytes_to_send - self._send_offset += bytes_to_send - if self._send_remaining[stream_id] == 0: - self._handlers['SendDone'](stream_id) - - def default_ping(self): - logging.info('sending ping') - self._outstanding_pings += 1 - self._conn.ping(b'\x00'*8) - self.transport.write(self._conn.data_to_send()) - - def on_send_done_default(self, stream_id): - if self._stream_status[stream_id]: - self._stream_status[stream_id] = False - self.default_send_trailer(stream_id) - else: - logging.error('Stream %d is already closed' % stream_id) - - def default_send_trailer(self, stream_id): - logging.info('Sending trailer for stream id %d' % stream_id) - self._conn.send_headers(stream_id, - headers=[ ('grpc-status', '0') ], - end_stream=True - ) - self.transport.write(self._conn.data_to_send()) - - @staticmethod - def default_response_data(response_size): - sresp = messages_pb2.SimpleResponse() - sresp.payload.body = b'\x00'*response_size - serialized_resp_proto = sresp.SerializeToString() - response_data = b'\x00' + struct.pack('i', len(serialized_resp_proto))[::-1] + serialized_resp_proto - return response_data - - def parse_received_data(self, stream_id): - """ returns a grpc framed string of bytes containing response proto of the size + + def __init__(self): + self._conn = h2.connection.H2Connection(client_side=False) + self._recv_buffer = {} + self._handlers = {} + self._handlers['ConnectionMade'] = self.on_connection_made_default + self._handlers['DataReceived'] = self.on_data_received_default + self._handlers['WindowUpdated'] = self.on_window_update_default + self._handlers['RequestReceived'] = self.on_request_received_default + self._handlers['SendDone'] = self.on_send_done_default + self._handlers['ConnectionLost'] = self.on_connection_lost + self._handlers['PingAcknowledged'] = self.on_ping_acknowledged_default + self._stream_status = {} + self._send_remaining = {} + self._outstanding_pings = 0 + + def set_handlers(self, handlers): + self._handlers = handlers + + def connectionMade(self): + self._handlers['ConnectionMade']() + + def connectionLost(self, reason): + self._handlers['ConnectionLost'](reason) + + def on_connection_made_default(self): + logging.info('Connection Made') + self._conn.initiate_connection() + self.transport.setTcpNoDelay(True) + self.transport.write(self._conn.data_to_send()) + + def on_connection_lost(self, reason): + logging.info('Disconnected %s' % reason) + + def dataReceived(self, data): + try: + events = self._conn.receive_data(data) + except h2.exceptions.ProtocolError: + # this try/except block catches exceptions due to race between sending + # GOAWAY and processing a response in flight. + return + if self._conn.data_to_send: + self.transport.write(self._conn.data_to_send()) + for event in events: + if isinstance(event, h2.events.RequestReceived + ) and self._handlers.has_key('RequestReceived'): + logging.info('RequestReceived Event for stream: %d' % + event.stream_id) + self._handlers['RequestReceived'](event) + elif isinstance(event, h2.events.DataReceived + ) and self._handlers.has_key('DataReceived'): + logging.info('DataReceived Event for stream: %d' % + event.stream_id) + self._handlers['DataReceived'](event) + elif isinstance(event, h2.events.WindowUpdated + ) and self._handlers.has_key('WindowUpdated'): + logging.info('WindowUpdated Event for stream: %d' % + event.stream_id) + self._handlers['WindowUpdated'](event) + elif isinstance(event, h2.events.PingAcknowledged + ) and self._handlers.has_key('PingAcknowledged'): + logging.info('PingAcknowledged Event') + self._handlers['PingAcknowledged'](event) + self.transport.write(self._conn.data_to_send()) + + def on_ping_acknowledged_default(self, event): + logging.info('ping acknowledged') + self._outstanding_pings -= 1 + + def on_data_received_default(self, event): + self._conn.acknowledge_received_data(len(event.data), event.stream_id) + self._recv_buffer[event.stream_id] += event.data + + def on_request_received_default(self, event): + self._recv_buffer[event.stream_id] = '' + self._stream_id = event.stream_id + self._stream_status[event.stream_id] = True + self._conn.send_headers( + stream_id=event.stream_id, + headers=[ + (':status', '200'), + ('content-type', 'application/grpc'), + ('grpc-encoding', 'identity'), + ('grpc-accept-encoding', 'identity,deflate,gzip'), + ], + ) + self.transport.write(self._conn.data_to_send()) + + def on_window_update_default(self, + _, + pad_length=None, + read_chunk_size=_READ_CHUNK_SIZE): + # try to resume sending on all active streams (update might be for connection) + for stream_id in self._send_remaining: + self.default_send(stream_id, + pad_length=pad_length, + read_chunk_size=read_chunk_size) + + def send_reset_stream(self): + self._conn.reset_stream(self._stream_id) + self.transport.write(self._conn.data_to_send()) + + def setup_send(self, + data_to_send, + stream_id, + pad_length=None, + read_chunk_size=_READ_CHUNK_SIZE): + logging.info('Setting up data to send for stream_id: %d' % stream_id) + self._send_remaining[stream_id] = len(data_to_send) + self._send_offset = 0 + self._data_to_send = data_to_send + self.default_send(stream_id, + pad_length=pad_length, + read_chunk_size=read_chunk_size) + + def default_send(self, + stream_id, + pad_length=None, + read_chunk_size=_READ_CHUNK_SIZE): + if not self._send_remaining.has_key(stream_id): + # not setup to send data yet + return + + while self._send_remaining[stream_id] > 0: + lfcw = self._conn.local_flow_control_window(stream_id) + padding_bytes = pad_length + 1 if pad_length is not None else 0 + if lfcw - padding_bytes <= 0: + logging.info( + 'Stream %d. lfcw: %d. padding bytes: %d. not enough quota yet' + % (stream_id, lfcw, padding_bytes)) + break + chunk_size = min(lfcw - padding_bytes, read_chunk_size) + bytes_to_send = min(chunk_size, self._send_remaining[stream_id]) + logging.info( + 'flow_control_window = %d. sending [%d:%d] stream_id %d. includes %d total padding bytes' + % (lfcw, self._send_offset, self._send_offset + bytes_to_send + + padding_bytes, stream_id, padding_bytes)) + # The receiver might allow sending frames larger than the http2 minimum + # max frame size (16384), but this test should never send more than 16384 + # for simplicity (which is always legal). + if bytes_to_send + padding_bytes > _MIN_SETTINGS_MAX_FRAME_SIZE: + raise ValueError("overload: sending %d" % + (bytes_to_send + padding_bytes)) + data = self._data_to_send[self._send_offset:self._send_offset + + bytes_to_send] + try: + self._conn.send_data(stream_id, + data, + end_stream=False, + pad_length=pad_length) + except h2.exceptions.ProtocolError: + logging.info('Stream %d is closed' % stream_id) + break + self._send_remaining[stream_id] -= bytes_to_send + self._send_offset += bytes_to_send + if self._send_remaining[stream_id] == 0: + self._handlers['SendDone'](stream_id) + + def default_ping(self): + logging.info('sending ping') + self._outstanding_pings += 1 + self._conn.ping(b'\x00' * 8) + self.transport.write(self._conn.data_to_send()) + + def on_send_done_default(self, stream_id): + if self._stream_status[stream_id]: + self._stream_status[stream_id] = False + self.default_send_trailer(stream_id) + else: + logging.error('Stream %d is already closed' % stream_id) + + def default_send_trailer(self, stream_id): + logging.info('Sending trailer for stream id %d' % stream_id) + self._conn.send_headers(stream_id, + headers=[('grpc-status', '0')], + end_stream=True) + self.transport.write(self._conn.data_to_send()) + + @staticmethod + def default_response_data(response_size): + sresp = messages_pb2.SimpleResponse() + sresp.payload.body = b'\x00' * response_size + serialized_resp_proto = sresp.SerializeToString() + response_data = b'\x00' + struct.pack( + 'i', len(serialized_resp_proto))[::-1] + serialized_resp_proto + return response_data + + def parse_received_data(self, stream_id): + """ returns a grpc framed string of bytes containing response proto of the size asked in request """ - recv_buffer = self._recv_buffer[stream_id] - grpc_msg_size = struct.unpack('i',recv_buffer[1:5][::-1])[0] - if len(recv_buffer) != _GRPC_HEADER_SIZE + grpc_msg_size: - return None - req_proto_str = recv_buffer[5:5+grpc_msg_size] - sr = messages_pb2.SimpleRequest() - sr.ParseFromString(req_proto_str) - logging.info('Parsed simple request for stream %d' % stream_id) - return sr + recv_buffer = self._recv_buffer[stream_id] + grpc_msg_size = struct.unpack('i', recv_buffer[1:5][::-1])[0] + if len(recv_buffer) != _GRPC_HEADER_SIZE + grpc_msg_size: + return None + req_proto_str = recv_buffer[5:5 + grpc_msg_size] + sr = messages_pb2.SimpleRequest() + sr.ParseFromString(req_proto_str) + logging.info('Parsed simple request for stream %d' % stream_id) + return sr diff --git a/test/http2_test/http2_server_health_check.py b/test/http2_test/http2_server_health_check.py index 5117c1aaaa2..d5ac49f3e56 100644 --- a/test/http2_test/http2_server_health_check.py +++ b/test/http2_test/http2_server_health_check.py @@ -19,16 +19,16 @@ import sys # Utility to healthcheck the http2 server. Used when starting the server to # verify that the server is live before tests begin. if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--server_host', type=str, default='localhost') - parser.add_argument('--server_port', type=int, default=8080) - args = parser.parse_args() - server_host = args.server_host - server_port = args.server_port - conn = hyper.HTTP20Connection('%s:%d' % (server_host, server_port)) - conn.request('POST', '/grpc.testing.TestService/UnaryCall') - resp = conn.get_response() - if resp.headers.get('grpc-encoding') is None: - sys.exit(1) - else: - sys.exit(0) + parser = argparse.ArgumentParser() + parser.add_argument('--server_host', type=str, default='localhost') + parser.add_argument('--server_port', type=int, default=8080) + args = parser.parse_args() + server_host = args.server_host + server_port = args.server_port + conn = hyper.HTTP20Connection('%s:%d' % (server_host, server_port)) + conn.request('POST', '/grpc.testing.TestService/UnaryCall') + resp = conn.get_response() + if resp.headers.get('grpc-encoding') is None: + sys.exit(1) + else: + sys.exit(0) diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py index 083597f2fff..5946895ee88 100644 --- a/test/http2_test/http2_test_server.py +++ b/test/http2_test/http2_test_server.py @@ -11,7 +11,6 @@ # 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. - """HTTP2 Test Server""" import argparse @@ -32,83 +31,94 @@ import test_rst_during_data import test_data_frame_padding _TEST_CASE_MAPPING = { - 'rst_after_header': test_rst_after_header.TestcaseRstStreamAfterHeader, - 'rst_after_data': test_rst_after_data.TestcaseRstStreamAfterData, - 'rst_during_data': test_rst_during_data.TestcaseRstStreamDuringData, - 'goaway': test_goaway.TestcaseGoaway, - 'ping': test_ping.TestcasePing, - 'max_streams': test_max_streams.TestcaseSettingsMaxStreams, - - # Positive tests below: - 'data_frame_padding': test_data_frame_padding.TestDataFramePadding, - 'no_df_padding_sanity_test': test_data_frame_padding.TestDataFramePadding, + 'rst_after_header': test_rst_after_header.TestcaseRstStreamAfterHeader, + 'rst_after_data': test_rst_after_data.TestcaseRstStreamAfterData, + 'rst_during_data': test_rst_during_data.TestcaseRstStreamDuringData, + 'goaway': test_goaway.TestcaseGoaway, + 'ping': test_ping.TestcasePing, + 'max_streams': test_max_streams.TestcaseSettingsMaxStreams, + + # Positive tests below: + 'data_frame_padding': test_data_frame_padding.TestDataFramePadding, + 'no_df_padding_sanity_test': test_data_frame_padding.TestDataFramePadding, } _exit_code = 0 + class H2Factory(twisted.internet.protocol.Factory): - def __init__(self, testcase): - logging.info('Creating H2Factory for new connection (%s)', testcase) - self._num_streams = 0 - self._testcase = testcase - - def buildProtocol(self, addr): - self._num_streams += 1 - logging.info('New Connection: %d' % self._num_streams) - if not _TEST_CASE_MAPPING.has_key(self._testcase): - logging.error('Unknown test case: %s' % self._testcase) - assert(0) - else: - t = _TEST_CASE_MAPPING[self._testcase] - - if self._testcase == 'goaway': - return t(self._num_streams).get_base_server() - elif self._testcase == 'no_df_padding_sanity_test': - return t(use_padding=False).get_base_server() - else: - return t().get_base_server() + + def __init__(self, testcase): + logging.info('Creating H2Factory for new connection (%s)', testcase) + self._num_streams = 0 + self._testcase = testcase + + def buildProtocol(self, addr): + self._num_streams += 1 + logging.info('New Connection: %d' % self._num_streams) + if not _TEST_CASE_MAPPING.has_key(self._testcase): + logging.error('Unknown test case: %s' % self._testcase) + assert (0) + else: + t = _TEST_CASE_MAPPING[self._testcase] + + if self._testcase == 'goaway': + return t(self._num_streams).get_base_server() + elif self._testcase == 'no_df_padding_sanity_test': + return t(use_padding=False).get_base_server() + else: + return t().get_base_server() + def parse_arguments(): - parser = argparse.ArgumentParser() - parser.add_argument('--base_port', type=int, default=8080, - help='base port to run the servers (default: 8080). One test server is ' - 'started on each incrementing port, beginning with base_port, in the ' - 'following order: data_frame_padding,goaway,max_streams,' - 'no_df_padding_sanity_test,ping,rst_after_data,rst_after_header,' - 'rst_during_data' - ) - return parser.parse_args() + parser = argparse.ArgumentParser() + parser.add_argument( + '--base_port', + type=int, + default=8080, + help='base port to run the servers (default: 8080). One test server is ' + 'started on each incrementing port, beginning with base_port, in the ' + 'following order: data_frame_padding,goaway,max_streams,' + 'no_df_padding_sanity_test,ping,rst_after_data,rst_after_header,' + 'rst_during_data') + return parser.parse_args() + def listen(endpoint, test_case): - deferred = endpoint.listen(H2Factory(test_case)) - def listen_error(reason): - # If listening fails, we stop the reactor and exit the program - # with exit code 1. - global _exit_code - _exit_code = 1 - logging.error('Listening failed: %s' % reason.value) - twisted.internet.reactor.stop() - deferred.addErrback(listen_error) + deferred = endpoint.listen(H2Factory(test_case)) + + def listen_error(reason): + # If listening fails, we stop the reactor and exit the program + # with exit code 1. + global _exit_code + _exit_code = 1 + logging.error('Listening failed: %s' % reason.value) + twisted.internet.reactor.stop() + + deferred.addErrback(listen_error) + def start_test_servers(base_port): - """ Start one server per test case on incrementing port numbers + """ Start one server per test case on incrementing port numbers beginning with base_port """ - index = 0 - for test_case in sorted(_TEST_CASE_MAPPING.keys()): - portnum = base_port + index - logging.warning('serving on port %d : %s'%(portnum, test_case)) - endpoint = twisted.internet.endpoints.TCP4ServerEndpoint( - twisted.internet.reactor, portnum, backlog=128) - # Wait until the reactor is running before calling endpoint.listen(). - twisted.internet.reactor.callWhenRunning(listen, endpoint, test_case) + index = 0 + for test_case in sorted(_TEST_CASE_MAPPING.keys()): + portnum = base_port + index + logging.warning('serving on port %d : %s' % (portnum, test_case)) + endpoint = twisted.internet.endpoints.TCP4ServerEndpoint( + twisted.internet.reactor, portnum, backlog=128) + # Wait until the reactor is running before calling endpoint.listen(). + twisted.internet.reactor.callWhenRunning(listen, endpoint, test_case) + + index += 1 - index += 1 if __name__ == '__main__': - logging.basicConfig( - format='%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s', - level=logging.INFO) - args = parse_arguments() - start_test_servers(args.base_port) - twisted.internet.reactor.run() - sys.exit(_exit_code) + logging.basicConfig( + format= + '%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s', + level=logging.INFO) + args = parse_arguments() + start_test_servers(args.base_port) + twisted.internet.reactor.run() + sys.exit(_exit_code) diff --git a/test/http2_test/test_data_frame_padding.py b/test/http2_test/test_data_frame_padding.py index 013b006ed11..d6758690764 100644 --- a/test/http2_test/test_data_frame_padding.py +++ b/test/http2_test/test_data_frame_padding.py @@ -21,59 +21,73 @@ import messages_pb2 _LARGE_PADDING_LENGTH = 255 _SMALL_READ_CHUNK_SIZE = 5 + class TestDataFramePadding(object): - """ + """ In response to an incoming request, this test sends headers, followed by data, followed by a reset stream frame. Client asserts that the RPC failed. Client needs to deliver the complete message to the application layer. """ - def __init__(self, use_padding=True): - self._base_server = http2_base_server.H2ProtocolBaseServer() - self._base_server._handlers['DataReceived'] = self.on_data_received - self._base_server._handlers['WindowUpdated'] = self.on_window_update - self._base_server._handlers['RequestReceived'] = self.on_request_received - # _total_updates maps stream ids to total flow control updates received - self._total_updates = {} - # zero window updates so far for connection window (stream id '0') - self._total_updates[0] = 0 - self._read_chunk_size = _SMALL_READ_CHUNK_SIZE + def __init__(self, use_padding=True): + self._base_server = http2_base_server.H2ProtocolBaseServer() + self._base_server._handlers['DataReceived'] = self.on_data_received + self._base_server._handlers['WindowUpdated'] = self.on_window_update + self._base_server._handlers[ + 'RequestReceived'] = self.on_request_received + + # _total_updates maps stream ids to total flow control updates received + self._total_updates = {} + # zero window updates so far for connection window (stream id '0') + self._total_updates[0] = 0 + self._read_chunk_size = _SMALL_READ_CHUNK_SIZE - if use_padding: - self._pad_length = _LARGE_PADDING_LENGTH - else: - self._pad_length = None + if use_padding: + self._pad_length = _LARGE_PADDING_LENGTH + else: + self._pad_length = None - def get_base_server(self): - return self._base_server + def get_base_server(self): + return self._base_server - def on_data_received(self, event): - logging.info('on data received. Stream id: %d. Data length: %d' % (event.stream_id, len(event.data))) - self._base_server.on_data_received_default(event) - if len(event.data) == 0: - return - sr = self._base_server.parse_received_data(event.stream_id) - stream_bytes = '' - # Check if full grpc msg has been read into the recv buffer yet - if sr: - response_data = self._base_server.default_response_data(sr.response_size) - logging.info('Stream id: %d. total resp size: %d' % (event.stream_id, len(response_data))) - # Begin sending the response. Add ``self._pad_length`` padding to each - # data frame and split the whole message into data frames each carrying - # only self._read_chunk_size of data. - # The purpose is to have the majority of the data frame response bytes - # be padding bytes, since ``self._pad_length`` >> ``self._read_chunk_size``. - self._base_server.setup_send(response_data , event.stream_id, pad_length=self._pad_length, read_chunk_size=self._read_chunk_size) + def on_data_received(self, event): + logging.info('on data received. Stream id: %d. Data length: %d' % + (event.stream_id, len(event.data))) + self._base_server.on_data_received_default(event) + if len(event.data) == 0: + return + sr = self._base_server.parse_received_data(event.stream_id) + stream_bytes = '' + # Check if full grpc msg has been read into the recv buffer yet + if sr: + response_data = self._base_server.default_response_data( + sr.response_size) + logging.info('Stream id: %d. total resp size: %d' % + (event.stream_id, len(response_data))) + # Begin sending the response. Add ``self._pad_length`` padding to each + # data frame and split the whole message into data frames each carrying + # only self._read_chunk_size of data. + # The purpose is to have the majority of the data frame response bytes + # be padding bytes, since ``self._pad_length`` >> ``self._read_chunk_size``. + self._base_server.setup_send(response_data, + event.stream_id, + pad_length=self._pad_length, + read_chunk_size=self._read_chunk_size) - def on_request_received(self, event): - self._base_server.on_request_received_default(event) - logging.info('on request received. Stream id: %s.' % event.stream_id) - self._total_updates[event.stream_id] = 0 + def on_request_received(self, event): + self._base_server.on_request_received_default(event) + logging.info('on request received. Stream id: %s.' % event.stream_id) + self._total_updates[event.stream_id] = 0 - # Log debug info and try to resume sending on all currently active streams. - def on_window_update(self, event): - logging.info('on window update. Stream id: %s. Delta: %s' % (event.stream_id, event.delta)) - self._total_updates[event.stream_id] += event.delta - total = self._total_updates[event.stream_id] - logging.info('... - total updates for stream %d : %d' % (event.stream_id, total)) - self._base_server.on_window_update_default(event, pad_length=self._pad_length, read_chunk_size=self._read_chunk_size) + # Log debug info and try to resume sending on all currently active streams. + def on_window_update(self, event): + logging.info('on window update. Stream id: %s. Delta: %s' % + (event.stream_id, event.delta)) + self._total_updates[event.stream_id] += event.delta + total = self._total_updates[event.stream_id] + logging.info('... - total updates for stream %d : %d' % + (event.stream_id, total)) + self._base_server.on_window_update_default( + event, + pad_length=self._pad_length, + read_chunk_size=self._read_chunk_size) diff --git a/test/http2_test/test_goaway.py b/test/http2_test/test_goaway.py index 472fcbbee7e..8e9664c95d5 100644 --- a/test/http2_test/test_goaway.py +++ b/test/http2_test/test_goaway.py @@ -17,46 +17,52 @@ import time import http2_base_server + class TestcaseGoaway(object): - """ + """ This test does the following: Process incoming request normally, i.e. send headers, data and trailers. Then send a GOAWAY frame with the stream id of the processed request. It checks that the next request is made on a different TCP connection. """ - def __init__(self, iteration): - self._base_server = http2_base_server.H2ProtocolBaseServer() - self._base_server._handlers['RequestReceived'] = self.on_request_received - self._base_server._handlers['DataReceived'] = self.on_data_received - self._base_server._handlers['SendDone'] = self.on_send_done - self._base_server._handlers['ConnectionLost'] = self.on_connection_lost - self._ready_to_send = False - self._iteration = iteration - - def get_base_server(self): - return self._base_server - - def on_connection_lost(self, reason): - logging.info('Disconnect received. Count %d' % self._iteration) - # _iteration == 2 => Two different connections have been used. - if self._iteration == 2: - self._base_server.on_connection_lost(reason) - - def on_send_done(self, stream_id): - self._base_server.on_send_done_default(stream_id) - logging.info('Sending GOAWAY for stream %d:' % stream_id) - self._base_server._conn.close_connection(error_code=0, additional_data=None, last_stream_id=stream_id) - self._base_server._stream_status[stream_id] = False - - def on_request_received(self, event): - self._ready_to_send = False - self._base_server.on_request_received_default(event) - - def on_data_received(self, event): - self._base_server.on_data_received_default(event) - sr = self._base_server.parse_received_data(event.stream_id) - if sr: - logging.info('Creating response size = %s' % sr.response_size) - response_data = self._base_server.default_response_data(sr.response_size) - self._ready_to_send = True - self._base_server.setup_send(response_data, event.stream_id) + + def __init__(self, iteration): + self._base_server = http2_base_server.H2ProtocolBaseServer() + self._base_server._handlers[ + 'RequestReceived'] = self.on_request_received + self._base_server._handlers['DataReceived'] = self.on_data_received + self._base_server._handlers['SendDone'] = self.on_send_done + self._base_server._handlers['ConnectionLost'] = self.on_connection_lost + self._ready_to_send = False + self._iteration = iteration + + def get_base_server(self): + return self._base_server + + def on_connection_lost(self, reason): + logging.info('Disconnect received. Count %d' % self._iteration) + # _iteration == 2 => Two different connections have been used. + if self._iteration == 2: + self._base_server.on_connection_lost(reason) + + def on_send_done(self, stream_id): + self._base_server.on_send_done_default(stream_id) + logging.info('Sending GOAWAY for stream %d:' % stream_id) + self._base_server._conn.close_connection(error_code=0, + additional_data=None, + last_stream_id=stream_id) + self._base_server._stream_status[stream_id] = False + + def on_request_received(self, event): + self._ready_to_send = False + self._base_server.on_request_received_default(event) + + def on_data_received(self, event): + self._base_server.on_data_received_default(event) + sr = self._base_server.parse_received_data(event.stream_id) + if sr: + logging.info('Creating response size = %s' % sr.response_size) + response_data = self._base_server.default_response_data( + sr.response_size) + self._ready_to_send = True + self._base_server.setup_send(response_data, event.stream_id) diff --git a/test/http2_test/test_max_streams.py b/test/http2_test/test_max_streams.py index 7af2e28fdd6..401307482cd 100644 --- a/test/http2_test/test_max_streams.py +++ b/test/http2_test/test_max_streams.py @@ -17,32 +17,36 @@ import logging import http2_base_server + class TestcaseSettingsMaxStreams(object): - """ + """ This test sets MAX_CONCURRENT_STREAMS to 1 and asserts that at any point only 1 stream is active. """ - def __init__(self): - self._base_server = http2_base_server.H2ProtocolBaseServer() - self._base_server._handlers['DataReceived'] = self.on_data_received - self._base_server._handlers['ConnectionMade'] = self.on_connection_made - - def get_base_server(self): - return self._base_server - - def on_connection_made(self): - logging.info('Connection Made') - self._base_server._conn.initiate_connection() - self._base_server._conn.update_settings( - {hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1}) - self._base_server.transport.setTcpNoDelay(True) - self._base_server.transport.write(self._base_server._conn.data_to_send()) - - def on_data_received(self, event): - self._base_server.on_data_received_default(event) - sr = self._base_server.parse_received_data(event.stream_id) - if sr: - logging.info('Creating response of size = %s' % sr.response_size) - response_data = self._base_server.default_response_data(sr.response_size) - self._base_server.setup_send(response_data, event.stream_id) - # TODO (makdharma): Add assertion to check number of live streams + + def __init__(self): + self._base_server = http2_base_server.H2ProtocolBaseServer() + self._base_server._handlers['DataReceived'] = self.on_data_received + self._base_server._handlers['ConnectionMade'] = self.on_connection_made + + def get_base_server(self): + return self._base_server + + def on_connection_made(self): + logging.info('Connection Made') + self._base_server._conn.initiate_connection() + self._base_server._conn.update_settings( + {hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1}) + self._base_server.transport.setTcpNoDelay(True) + self._base_server.transport.write( + self._base_server._conn.data_to_send()) + + def on_data_received(self, event): + self._base_server.on_data_received_default(event) + sr = self._base_server.parse_received_data(event.stream_id) + if sr: + logging.info('Creating response of size = %s' % sr.response_size) + response_data = self._base_server.default_response_data( + sr.response_size) + self._base_server.setup_send(response_data, event.stream_id) + # TODO (makdharma): Add assertion to check number of live streams diff --git a/test/http2_test/test_ping.py b/test/http2_test/test_ping.py index 8f6b8a1b840..4bf1d6c4067 100644 --- a/test/http2_test/test_ping.py +++ b/test/http2_test/test_ping.py @@ -16,37 +16,42 @@ import logging import http2_base_server + class TestcasePing(object): - """ + """ This test injects PING frames before and after header and data. Keeps count of outstanding ping response and asserts when the count is non-zero at the end of the test. """ - def __init__(self): - self._base_server = http2_base_server.H2ProtocolBaseServer() - self._base_server._handlers['RequestReceived'] = self.on_request_received - self._base_server._handlers['DataReceived'] = self.on_data_received - self._base_server._handlers['ConnectionLost'] = self.on_connection_lost - - def get_base_server(self): - return self._base_server - - def on_request_received(self, event): - self._base_server.default_ping() - self._base_server.on_request_received_default(event) - self._base_server.default_ping() - - def on_data_received(self, event): - self._base_server.on_data_received_default(event) - sr = self._base_server.parse_received_data(event.stream_id) - if sr: - logging.info('Creating response size = %s' % sr.response_size) - response_data = self._base_server.default_response_data(sr.response_size) - self._base_server.default_ping() - self._base_server.setup_send(response_data, event.stream_id) - self._base_server.default_ping() - - def on_connection_lost(self, reason): - logging.info('Disconnect received. Ping Count %d' % self._base_server._outstanding_pings) - assert(self._base_server._outstanding_pings == 0) - self._base_server.on_connection_lost(reason) + + def __init__(self): + self._base_server = http2_base_server.H2ProtocolBaseServer() + self._base_server._handlers[ + 'RequestReceived'] = self.on_request_received + self._base_server._handlers['DataReceived'] = self.on_data_received + self._base_server._handlers['ConnectionLost'] = self.on_connection_lost + + def get_base_server(self): + return self._base_server + + def on_request_received(self, event): + self._base_server.default_ping() + self._base_server.on_request_received_default(event) + self._base_server.default_ping() + + def on_data_received(self, event): + self._base_server.on_data_received_default(event) + sr = self._base_server.parse_received_data(event.stream_id) + if sr: + logging.info('Creating response size = %s' % sr.response_size) + response_data = self._base_server.default_response_data( + sr.response_size) + self._base_server.default_ping() + self._base_server.setup_send(response_data, event.stream_id) + self._base_server.default_ping() + + def on_connection_lost(self, reason): + logging.info('Disconnect received. Ping Count %d' % + self._base_server._outstanding_pings) + assert (self._base_server._outstanding_pings == 0) + self._base_server.on_connection_lost(reason) diff --git a/test/http2_test/test_rst_after_data.py b/test/http2_test/test_rst_after_data.py index 8059226b2a9..c867dc7a440 100644 --- a/test/http2_test/test_rst_after_data.py +++ b/test/http2_test/test_rst_after_data.py @@ -14,29 +14,32 @@ import http2_base_server + class TestcaseRstStreamAfterData(object): - """ + """ In response to an incoming request, this test sends headers, followed by data, followed by a reset stream frame. Client asserts that the RPC failed. Client needs to deliver the complete message to the application layer. """ - def __init__(self): - self._base_server = http2_base_server.H2ProtocolBaseServer() - self._base_server._handlers['DataReceived'] = self.on_data_received - self._base_server._handlers['SendDone'] = self.on_send_done - def get_base_server(self): - return self._base_server + def __init__(self): + self._base_server = http2_base_server.H2ProtocolBaseServer() + self._base_server._handlers['DataReceived'] = self.on_data_received + self._base_server._handlers['SendDone'] = self.on_send_done + + def get_base_server(self): + return self._base_server - def on_data_received(self, event): - self._base_server.on_data_received_default(event) - sr = self._base_server.parse_received_data(event.stream_id) - if sr: - response_data = self._base_server.default_response_data(sr.response_size) - self._ready_to_send = True - self._base_server.setup_send(response_data, event.stream_id) - # send reset stream + def on_data_received(self, event): + self._base_server.on_data_received_default(event) + sr = self._base_server.parse_received_data(event.stream_id) + if sr: + response_data = self._base_server.default_response_data( + sr.response_size) + self._ready_to_send = True + self._base_server.setup_send(response_data, event.stream_id) + # send reset stream - def on_send_done(self, stream_id): - self._base_server.send_reset_stream() - self._base_server._stream_status[stream_id] = False + def on_send_done(self, stream_id): + self._base_server.send_reset_stream() + self._base_server._stream_status[stream_id] = False diff --git a/test/http2_test/test_rst_after_header.py b/test/http2_test/test_rst_after_header.py index c69078f547f..1e2ddcbd4cf 100644 --- a/test/http2_test/test_rst_after_header.py +++ b/test/http2_test/test_rst_after_header.py @@ -14,20 +14,23 @@ import http2_base_server + class TestcaseRstStreamAfterHeader(object): - """ + """ In response to an incoming request, this test sends headers, followed by a reset stream frame. Client asserts that the RPC failed. """ - def __init__(self): - self._base_server = http2_base_server.H2ProtocolBaseServer() - self._base_server._handlers['RequestReceived'] = self.on_request_received - def get_base_server(self): - return self._base_server + def __init__(self): + self._base_server = http2_base_server.H2ProtocolBaseServer() + self._base_server._handlers[ + 'RequestReceived'] = self.on_request_received + + def get_base_server(self): + return self._base_server - def on_request_received(self, event): - # send initial headers - self._base_server.on_request_received_default(event) - # send reset stream - self._base_server.send_reset_stream() + def on_request_received(self, event): + # send initial headers + self._base_server.on_request_received_default(event) + # send reset stream + self._base_server.send_reset_stream() diff --git a/test/http2_test/test_rst_during_data.py b/test/http2_test/test_rst_during_data.py index 0c61f07eb71..c34954e4f69 100644 --- a/test/http2_test/test_rst_during_data.py +++ b/test/http2_test/test_rst_during_data.py @@ -14,30 +14,34 @@ import http2_base_server + class TestcaseRstStreamDuringData(object): - """ + """ In response to an incoming request, this test sends headers, followed by some data, followed by a reset stream frame. Client asserts that the RPC failed and does not deliver the message to the application. """ - def __init__(self): - self._base_server = http2_base_server.H2ProtocolBaseServer() - self._base_server._handlers['DataReceived'] = self.on_data_received - self._base_server._handlers['SendDone'] = self.on_send_done - def get_base_server(self): - return self._base_server + def __init__(self): + self._base_server = http2_base_server.H2ProtocolBaseServer() + self._base_server._handlers['DataReceived'] = self.on_data_received + self._base_server._handlers['SendDone'] = self.on_send_done + + def get_base_server(self): + return self._base_server - def on_data_received(self, event): - self._base_server.on_data_received_default(event) - sr = self._base_server.parse_received_data(event.stream_id) - if sr: - response_data = self._base_server.default_response_data(sr.response_size) - self._ready_to_send = True - response_len = len(response_data) - truncated_response_data = response_data[0:response_len/2] - self._base_server.setup_send(truncated_response_data, event.stream_id) + def on_data_received(self, event): + self._base_server.on_data_received_default(event) + sr = self._base_server.parse_received_data(event.stream_id) + if sr: + response_data = self._base_server.default_response_data( + sr.response_size) + self._ready_to_send = True + response_len = len(response_data) + truncated_response_data = response_data[0:response_len / 2] + self._base_server.setup_send(truncated_response_data, + event.stream_id) - def on_send_done(self, stream_id): - self._base_server.send_reset_stream() - self._base_server._stream_status[stream_id] = False + def on_send_done(self, stream_id): + self._base_server.send_reset_stream() + self._base_server._stream_status[stream_id] = False diff --git a/tools/distrib/yapf_code.sh b/tools/distrib/yapf_code.sh index 947384ec6d2..c377e3d7f98 100755 --- a/tools/distrib/yapf_code.sh +++ b/tools/distrib/yapf_code.sh @@ -19,8 +19,9 @@ set -ex cd "$(dirname "${0}")/../.." DIRS=( - 'examples/python' - 'src/python' + 'examples' + 'src' + 'test' 'tools' ) @@ -32,24 +33,4 @@ PYTHON=${VIRTUALENV}/bin/python "$PYTHON" -m pip install --upgrade futures "$PYTHON" -m pip install yapf==0.28.0 -yapf() { - $PYTHON -m yapf -i -r --style=setup.cfg "${1}" -} - -if [[ -z "${TEST}" ]]; then - for dir in "${DIRS[@]}"; do - yapf "${dir}" - done -else - ok=yes - for dir in "${DIRS[@]}"; do - tempdir=$(mktemp -d) - cp -RT "${dir}" "${tempdir}" - yapf "${tempdir}" - diff -x '*.pyc' -ru "${dir}" "${tempdir}" || ok=no - rm -rf "${tempdir}" - done - if [[ ${ok} == no ]]; then - false - fi -fi +$PYTHON -m yapf --diff --recursive --style=setup.cfg "${DIRS[@]}" From db11b94f255ac15596f4feee77485a443d74859e Mon Sep 17 00:00:00 2001 From: Akshay Kumar Date: Sun, 8 Dec 2019 12:08:52 -0800 Subject: [PATCH 16/31] FullChainExperimental-01-200103 --- grpc.def | 1 + include/grpc/grpc_security.h | 14 +++++ include/grpc/grpc_security_constants.h | 12 +++++ .../grpcpp/security/tls_credentials_options.h | 9 ++++ .../tls/grpc_tls_credentials_options.cc | 20 +++++++ .../tls/grpc_tls_credentials_options.h | 8 +++ .../security/security_connector/ssl_utils.cc | 24 +++++++++ .../security/security_connector/ssl_utils.h | 6 +++ .../tls/tls_security_connector.cc | 37 +++++++++---- .../tls/tls_security_connector.h | 2 +- src/core/tsi/ssl_transport_security.cc | 44 +++++++++++++-- src/core/tsi/ssl_transport_security.h | 15 +++++- src/core/tsi/transport_security_interface.h | 11 ++++ src/cpp/common/tls_credentials_options.cc | 14 +++++ test/core/security/security_connector_test.cc | 54 ++++++++++++++++--- .../security/tls_security_connector_test.cc | 20 +++---- test/core/tsi/ssl_transport_security_test.cc | 32 +++++++++++ test/cpp/client/credentials_test.cc | 8 +-- 18 files changed, 295 insertions(+), 36 deletions(-) diff --git a/grpc.def b/grpc.def index ff68b965eb2..2f753b29939 100644 --- a/grpc.def +++ b/grpc.def @@ -136,6 +136,7 @@ EXPORTS grpc_local_server_credentials_create grpc_tls_credentials_options_create grpc_tls_credentials_options_set_cert_request_type + grpc_tls_credentials_options_set_server_verification_option grpc_tls_credentials_options_set_key_materials_config grpc_tls_credentials_options_set_credential_reload_config grpc_tls_credentials_options_set_server_authorization_check_config diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 164c6dacdb0..31496e96e74 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -731,6 +731,19 @@ GRPCAPI int grpc_tls_credentials_options_set_cert_request_type( grpc_tls_credentials_options* options, grpc_ssl_client_certificate_request_type type); +/** Set grpc_tls_server_verification_option field in credentials options + with the provided server_verification_option. options should not be NULL. + This should be called only on the client side. + If grpc_tls_server_verification_option is not + GRPC_TLS_SERVER_VERIFICATION, use of a customer server + authorization check (grpc_tls_server_authorization_check_config) + will be mandatory. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_server_verification_option( + grpc_tls_credentials_options* options, + grpc_tls_server_verification_option server_verification_option); + /** Set grpc_tls_key_materials_config field in credentials options with the provided config struct whose ownership is transferred. Both parameters should not be NULL. @@ -902,6 +915,7 @@ struct grpc_tls_server_authorization_check_arg { int success; const char* target_name; const char* peer_cert; + const char* peer_cert_full_chain; grpc_status_code status; const char* error_details; grpc_tls_server_authorization_check_config* config; diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index 13d6e9ff8e0..63900e41cb3 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -29,6 +29,7 @@ extern "C" { #define GRPC_X509_CN_PROPERTY_NAME "x509_common_name" #define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name" #define GRPC_X509_PEM_CERT_PROPERTY_NAME "x509_pem_cert" +#define GRPC_X509_PEM_CERT_CHAIN_PROPERTY_NAME "x509_pem_cert_chain" #define GRPC_SSL_SESSION_REUSED_PROPERTY "ssl_session_reused" /** Environment variable that points to the default SSL roots file. This file @@ -114,6 +115,17 @@ typedef enum { GRPC_SECURITY_MAX = GRPC_PRIVACY_AND_INTEGRITY, } grpc_security_level; +typedef enum { + /** Default option: performs server certificate verification and hostname + verification */ + GRPC_TLS_SERVER_VERIFICATION, + /** Performs server certificate verification, but skips hostname verification + */ + GRPC_TLS_SKIP_HOSTNAME_VERIFICATION, + /** Skips both server certificate and hostname verification */ + GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION +} grpc_tls_server_verification_option; + /** * Type of local connections for which local channel/server credentials will be * applied. It supports UDS and local TCP connections. diff --git a/include/grpcpp/security/tls_credentials_options.h b/include/grpcpp/security/tls_credentials_options.h index 3e9b037ec25..b5bb7c78b7f 100644 --- a/include/grpcpp/security/tls_credentials_options.h +++ b/include/grpcpp/security/tls_credentials_options.h @@ -193,6 +193,7 @@ class TlsServerAuthorizationCheckArg { int success() const; grpc::string target_name() const; grpc::string peer_cert() const; + grpc::string peer_cert_full_chain() const; grpc_status_code status() const; grpc::string error_details() const; @@ -206,6 +207,7 @@ class TlsServerAuthorizationCheckArg { void set_success(int success); void set_target_name(const grpc::string& target_name); void set_peer_cert(const grpc::string& peer_cert); + void set_peer_cert_full_chain(const grpc::string& peer_cert_full_chain); void set_status(grpc_status_code status); void set_error_details(const grpc::string& error_details); @@ -287,6 +289,7 @@ class TlsCredentialsOptions { public: TlsCredentialsOptions( grpc_ssl_client_certificate_request_type cert_request_type, + grpc_tls_server_verification_option server_verification_option, std::shared_ptr key_materials_config, std::shared_ptr credential_reload_config, std::shared_ptr @@ -297,6 +300,9 @@ class TlsCredentialsOptions { grpc_ssl_client_certificate_request_type cert_request_type() const { return cert_request_type_; } + grpc_tls_server_verification_option server_verification_option() const { + return server_verification_option_; + } std::shared_ptr key_materials_config() const { return key_materials_config_; } @@ -317,6 +323,9 @@ class TlsCredentialsOptions { * goes unused when creating channel credentials, and the user can set it to * GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE. **/ grpc_ssl_client_certificate_request_type cert_request_type_; + /** The server_verification_option_ flag is only relevant when the + * TlsCredentialsOptions are used to instantiate client credentials; **/ + grpc_tls_server_verification_option server_verification_option_; std::shared_ptr key_materials_config_; std::shared_ptr credential_reload_config_; std::shared_ptr diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc index 199a15b6354..937dfacfa79 100644 --- a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc @@ -92,6 +92,26 @@ int grpc_tls_credentials_options_set_cert_request_type( return 1; } +int grpc_tls_credentials_options_set_server_verification_option( + grpc_tls_credentials_options* options, + grpc_tls_server_verification_option server_verification_option) { + if (options == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_server_verification_option()"); + return 0; + } + if (server_verification_option != GRPC_TLS_SERVER_VERIFICATION && + options->server_authorization_check_config() == nullptr) { + gpr_log(GPR_ERROR, + "server_authorization_check_config needs to be specified when" + "server_verification_option is not GRPC_TLS_SERVER_VERIFICATION"); + return 0; + } + options->set_server_verification_option(server_verification_option); + return 1; +} + int grpc_tls_credentials_options_set_key_materials_config( grpc_tls_credentials_options* options, grpc_tls_key_materials_config* config) { diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h index a7f99822121..ca82a294928 100644 --- a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h @@ -234,6 +234,9 @@ struct grpc_tls_credentials_options grpc_ssl_client_certificate_request_type cert_request_type() const { return cert_request_type_; } + grpc_tls_server_verification_option server_verification_option() const { + return server_verification_option_; + } grpc_tls_key_materials_config* key_materials_config() const { return key_materials_config_.get(); } @@ -250,6 +253,10 @@ struct grpc_tls_credentials_options const grpc_ssl_client_certificate_request_type type) { cert_request_type_ = type; } + void set_server_verification_option( + const grpc_tls_server_verification_option server_verification_option) { + server_verification_option_ = server_verification_option; + } void set_key_materials_config( grpc_core::RefCountedPtr config) { key_materials_config_ = std::move(config); @@ -266,6 +273,7 @@ struct grpc_tls_credentials_options private: grpc_ssl_client_certificate_request_type cert_request_type_; + grpc_tls_server_verification_option server_verification_option_; grpc_core::RefCountedPtr key_materials_config_; grpc_core::RefCountedPtr credential_reload_config_; diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index f4bb70bef8d..e34c66b35d6 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -108,6 +108,20 @@ grpc_get_tsi_client_certificate_request_type( } } +tsi_server_verification_option grpc_get_tsi_server_verification_option( + grpc_tls_server_verification_option server_verification_option) { + switch (server_verification_option) { + case GRPC_TLS_SERVER_VERIFICATION: + return TSI_SERVER_VERIFICATION; + case GRPC_TLS_SKIP_HOSTNAME_VERIFICATION: + return TSI_SKIP_HOSTNAME_VERIFICATION; + case GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION: + return TSI_SKIP_ALL_SERVER_VERIFICATION; + default: + return TSI_SERVER_VERIFICATION; + } +} + grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) { #if TSI_OPENSSL_ALPN_SUPPORT /* Check the ALPN if ALPN is supported. */ @@ -225,6 +239,10 @@ grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( grpc_auth_context_add_property(ctx.get(), GRPC_X509_PEM_CERT_PROPERTY_NAME, prop->value.data, prop->value.length); + } else if (strcmp(prop->name, TSI_X509_PEM_CERT_CHAIN_PROPERTY) == 0) { + grpc_auth_context_add_property(ctx.get(), + GRPC_X509_PEM_CERT_CHAIN_PROPERTY_NAME, + prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) { grpc_auth_context_add_property(ctx.get(), GRPC_SSL_SESSION_REUSED_PROPERTY, @@ -272,6 +290,10 @@ tsi_peer grpc_shallow_peer_from_ssl_auth_context( } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) { add_shallow_auth_property_to_peer(&peer, prop, TSI_X509_PEM_CERT_PROPERTY); + } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_CHAIN_PROPERTY_NAME) == + 0) { + add_shallow_auth_property_to_peer(&peer, prop, + TSI_X509_PEM_CERT_CHAIN_PROPERTY); } } } @@ -284,6 +306,7 @@ void grpc_shallow_peer_destruct(tsi_peer* peer) { grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( tsi_ssl_pem_key_cert_pair* pem_key_cert_pair, const char* pem_root_certs, + tsi_server_verification_option server_verification_option, tsi_ssl_session_cache* ssl_session_cache, tsi_ssl_client_handshaker_factory** handshaker_factory) { const char* root_certs; @@ -314,6 +337,7 @@ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( } options.cipher_suites = grpc_get_ssl_cipher_suites(); options.session_cache = ssl_session_cache; + options.server_verification_option = server_verification_option; const tsi_result result = tsi_create_ssl_client_handshaker_factory_with_options(&options, handshaker_factory); diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 6ee2c3c7248..e6370db9768 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -68,12 +68,18 @@ tsi_client_certificate_request_type grpc_get_tsi_client_certificate_request_type( grpc_ssl_client_certificate_request_type grpc_request_type); +/* Map from grpc_tls_server_verification_option to + * tsi_server_verification_option. */ +tsi_server_verification_option grpc_get_tsi_server_verification_option( + grpc_tls_server_verification_option server_verification_option); + /* Return an array of strings containing alpn protocols. */ const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols); /* Initialize TSI SSL server/client handshaker factory. */ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( tsi_ssl_pem_key_cert_pair* key_cert_pair, const char* pem_root_certs, + tsi_server_verification_option server_verification_option, tsi_ssl_session_cache* ssl_session_cache, tsi_ssl_client_handshaker_factory** handshaker_factory); diff --git a/src/core/lib/security/security_connector/tls/tls_security_connector.cc b/src/core/lib/security/security_connector/tls/tls_security_connector.cc index 62948eff57a..205f1dda7ff 100644 --- a/src/core/lib/security/security_connector/tls/tls_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/tls_security_connector.cc @@ -66,12 +66,13 @@ tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair( grpc_status_code TlsFetchKeyMaterials( const grpc_core::RefCountedPtr& key_materials_config, - const grpc_tls_credentials_options& options, + const grpc_tls_credentials_options& options, bool server_config, grpc_ssl_certificate_config_reload_status* reload_status) { GPR_ASSERT(key_materials_config != nullptr); bool is_key_materials_empty = key_materials_config->pem_key_cert_pair_list().empty(); - if (options.credential_reload_config() == nullptr && is_key_materials_empty) { + if (options.credential_reload_config() == nullptr && is_key_materials_empty && + server_config) { gpr_log(GPR_ERROR, "Either credential reload config or key materials should be " "provisioned."); @@ -190,9 +191,8 @@ void TlsChannelSecurityConnector::check_peer( error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Cannot check peer: missing pem cert property."); } else { - char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); + char* peer_pem = static_cast(gpr_zalloc(p->value.length + 1)); memcpy(peer_pem, p->value.data, p->value.length); - peer_pem[p->value.length] = '\0'; GPR_ASSERT(check_arg_ != nullptr); check_arg_->peer_cert = check_arg_->peer_cert == nullptr ? gpr_strdup(peer_pem) @@ -202,6 +202,18 @@ void TlsChannelSecurityConnector::check_peer( : check_arg_->target_name; on_peer_checked_ = on_peer_checked; gpr_free(peer_pem); + const tsi_peer_property* chain = tsi_peer_get_property_by_name( + &peer, TSI_X509_PEM_CERT_CHAIN_PROPERTY); + if (chain != nullptr) { + char* peer_pem_chain = + static_cast(gpr_zalloc(chain->value.length + 1)); + memcpy(peer_pem_chain, chain->value.data, chain->value.length); + check_arg_->peer_cert_full_chain = + check_arg_->peer_cert_full_chain == nullptr + ? gpr_strdup(peer_pem_chain) + : check_arg_->peer_cert_full_chain; + gpr_free(peer_pem_chain); + } int callback_status = config->Schedule(check_arg_); /* Server authorization check is handled asynchronously. */ if (callback_status) { @@ -272,16 +284,21 @@ TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector( grpc_security_status TlsChannelSecurityConnector::ReplaceHandshakerFactory( tsi_ssl_session_cache* ssl_session_cache) { + const TlsCredentials* creds = + static_cast(channel_creds()); + tsi_server_verification_option server_verification_option = + grpc_get_tsi_server_verification_option( + creds->options().server_verification_option()); /* Free the client handshaker factory if exists. */ if (client_handshaker_factory_) { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); } - GPR_ASSERT(!key_materials_config_->pem_key_cert_pair_list().empty()); tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = ConvertToTsiPemKeyCertPair( key_materials_config_->pem_key_cert_pair_list()); grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init( pem_key_cert_pair, key_materials_config_->pem_root_certs(), - ssl_session_cache, &client_handshaker_factory_); + server_verification_option, ssl_session_cache, + &client_handshaker_factory_); /* Free memory. */ grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1); return status; @@ -305,7 +322,7 @@ grpc_security_status TlsChannelSecurityConnector::InitializeHandshakerFactory( } grpc_ssl_certificate_config_reload_status reload_status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; - if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), + if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), false, &reload_status) != GRPC_STATUS_OK) { /* Raise an error if key materials are not populated. */ return GRPC_SECURITY_ERROR; @@ -319,7 +336,7 @@ grpc_security_status TlsChannelSecurityConnector::RefreshHandshakerFactory() { static_cast(channel_creds()); grpc_ssl_certificate_config_reload_status reload_status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; - if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), + if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), false, &reload_status) != GRPC_STATUS_OK) { return GRPC_SECURITY_ERROR; } @@ -507,7 +524,7 @@ grpc_security_status TlsServerSecurityConnector::InitializeHandshakerFactory() { } grpc_ssl_certificate_config_reload_status reload_status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; - if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), + if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), true, &reload_status) != GRPC_STATUS_OK) { /* Raise an error if key materials are not populated. */ return GRPC_SECURITY_ERROR; @@ -521,7 +538,7 @@ grpc_security_status TlsServerSecurityConnector::RefreshHandshakerFactory() { static_cast(server_creds()); grpc_ssl_certificate_config_reload_status reload_status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; - if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), + if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), true, &reload_status) != GRPC_STATUS_OK) { return GRPC_SECURITY_ERROR; } diff --git a/src/core/lib/security/security_connector/tls/tls_security_connector.h b/src/core/lib/security/security_connector/tls/tls_security_connector.h index c669c6b9b75..825ffe7b1f7 100644 --- a/src/core/lib/security/security_connector/tls/tls_security_connector.h +++ b/src/core/lib/security/security_connector/tls/tls_security_connector.h @@ -148,7 +148,7 @@ class TlsServerSecurityConnector final : public grpc_server_security_connector { grpc_status_code TlsFetchKeyMaterials( const grpc_core::RefCountedPtr& key_materials_config, - const grpc_tls_credentials_options& options, + const grpc_tls_credentials_options& options, bool server_config, grpc_ssl_certificate_config_reload_status* status); } // namespace grpc_core diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 8b6d9f39dd4..2063ef0dfc9 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -35,6 +35,7 @@ #include #endif +#include #include #include #include @@ -1024,6 +1025,29 @@ static void tsi_ssl_handshaker_factory_init( gpr_ref_init(&factory->refcount, 1); } +/* Gets the X509 cert chain in PEM format as a tsi_peer_property. */ +tsi_result tsi_ssl_get_cert_chain_contents(STACK_OF(X509) * peer_chain, + tsi_peer_property* property) { + BIO* bio = BIO_new(BIO_s_mem()); + for (int i = 0; i < sk_X509_num(peer_chain); i++) { + if (!PEM_write_bio_X509(bio, sk_X509_value(peer_chain, i))) { + BIO_free(bio); + return TSI_INTERNAL_ERROR; + } + } + char* contents; + long len = BIO_get_mem_data(bio, &contents); + if (len <= 0) { + BIO_free(bio); + return TSI_INTERNAL_ERROR; + } + tsi_result result = tsi_construct_string_peer_property( + TSI_X509_PEM_CERT_CHAIN_PROPERTY, (const char*)contents, + static_cast(len), property); + BIO_free(bio); + return result; +} + /* --- tsi_handshaker_result methods implementation. ---*/ static tsi_result ssl_handshaker_result_extract_peer( const tsi_handshaker_result* self, tsi_peer* peer) { @@ -1032,7 +1056,6 @@ static tsi_result ssl_handshaker_result_extract_peer( unsigned int alpn_selected_len; const tsi_ssl_handshaker_result* impl = reinterpret_cast(self); - // TODO(yihuazhang): Return a full certificate chain as a peer property. X509* peer_cert = SSL_get_peer_certificate(impl->ssl); if (peer_cert != nullptr) { result = peer_from_x509(peer_cert, 1, peer); @@ -1047,10 +1070,14 @@ static tsi_result ssl_handshaker_result_extract_peer( SSL_get0_next_proto_negotiated(impl->ssl, &alpn_selected, &alpn_selected_len); } - + // When called on the client side, the stack also contains the + // peer's certificate; When called on the server side, + // the peer's certificate is not present in the stack + STACK_OF(X509)* peer_chain = SSL_get_peer_cert_chain(impl->ssl); // 1 is for session reused property. size_t new_property_count = peer->property_count + 1; if (alpn_selected != nullptr) new_property_count++; + if (peer_chain != nullptr) new_property_count++; tsi_peer_property* new_properties = static_cast( gpr_zalloc(sizeof(*new_properties) * new_property_count)); for (size_t i = 0; i < peer->property_count; i++) { @@ -1058,7 +1085,12 @@ static tsi_result ssl_handshaker_result_extract_peer( } if (peer->properties != nullptr) gpr_free(peer->properties); peer->properties = new_properties; - + // Add peer chain if available + if (peer_chain != nullptr) { + result = tsi_ssl_get_cert_chain_contents( + peer_chain, &peer->properties[peer->property_count]); + if (result == TSI_OK) peer->property_count++; + } if (alpn_selected != nullptr) { result = tsi_construct_string_peer_property( TSI_SSL_ALPN_SELECTED_PROTOCOL, @@ -1733,7 +1765,11 @@ tsi_result tsi_create_ssl_client_handshaker_factory_with_options( tsi_ssl_handshaker_factory_unref(&impl->base); return result; } - SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, nullptr); + if (options->server_verification_option == TSI_SKIP_ALL_SERVER_VERIFICATION) { + SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NullVerifyCallback); + } else { + SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, nullptr); + } /* TODO(jboeuf): Add revocation verification. */ *factory = impl; diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index dba711088a3..c5daba01779 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -20,6 +20,9 @@ #define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H #include +extern "C" { +#include +} #include "src/core/lib/gprpp/string_view.h" #include "src/core/tsi/transport_security_interface.h" @@ -35,6 +38,8 @@ #define TSI_X509_PEM_CERT_PROPERTY "x509_pem_cert" +#define TSI_X509_PEM_CERT_CHAIN_PROPERTY "x509_pem_cert_chain" + #define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol" /* --- tsi_ssl_root_certs_store object --- @@ -142,6 +147,9 @@ struct tsi_ssl_client_handshaker_options { /* ssl_session_cache is a cache for reusable client-side sessions. */ tsi_ssl_session_cache* session_cache; + /* Server verification option */ + tsi_server_verification_option server_verification_option; + tsi_ssl_client_handshaker_options() : pem_key_cert_pair(nullptr), pem_root_certs(nullptr), @@ -149,7 +157,8 @@ struct tsi_ssl_client_handshaker_options { cipher_suites(nullptr), alpn_protocols(nullptr), num_alpn_protocols(0), - session_cache(nullptr) {} + session_cache(nullptr), + server_verification_option(TSI_SERVER_VERIFICATION) {} }; /* Creates a client handshaker factory. @@ -336,4 +345,8 @@ const tsi_ssl_handshaker_factory_vtable* tsi_ssl_handshaker_factory_swap_vtable( tsi_result tsi_ssl_extract_x509_subject_names_from_pem_cert( const char* pem_cert, tsi_peer* peer); +/* Exposed for testing only. */ +tsi_result tsi_ssl_get_cert_chain_contents(STACK_OF(X509) * peer_chain, + tsi_peer_property* property); + #endif /* GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H */ diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index 7a0cdc3453a..6d597e4bdf7 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -55,6 +55,17 @@ typedef enum { TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY, } tsi_client_certificate_request_type; +typedef enum { + /** Default option: performs server certificate verification and hostname + verification */ + TSI_SERVER_VERIFICATION, + /** Performs server certificate verification, but skips hostname verification + */ + TSI_SKIP_HOSTNAME_VERIFICATION, + /** Skips both server certificate and hostname verification */ + TSI_SKIP_ALL_SERVER_VERIFICATION, +} tsi_server_verification_option; + const char* tsi_result_to_string(tsi_result result); /* --- tsi tracing --- */ diff --git a/src/cpp/common/tls_credentials_options.cc b/src/cpp/common/tls_credentials_options.cc index 60d6a23fee1..d5692c6effd 100644 --- a/src/cpp/common/tls_credentials_options.cc +++ b/src/cpp/common/tls_credentials_options.cc @@ -186,6 +186,11 @@ grpc::string TlsServerAuthorizationCheckArg::peer_cert() const { return cpp_peer_cert; } +grpc::string TlsServerAuthorizationCheckArg::peer_cert_full_chain() const { + grpc::string cpp_peer_cert_full_chain(c_arg_->peer_cert_full_chain); + return cpp_peer_cert_full_chain; +} + grpc_status_code TlsServerAuthorizationCheckArg::status() const { return c_arg_->status; } @@ -213,6 +218,11 @@ void TlsServerAuthorizationCheckArg::set_peer_cert( c_arg_->peer_cert = gpr_strdup(peer_cert.c_str()); } +void TlsServerAuthorizationCheckArg::set_peer_cert_full_chain( + const grpc::string& peer_cert_full_chain) { + c_arg_->peer_cert_full_chain = gpr_strdup(peer_cert_full_chain.c_str()); +} + void TlsServerAuthorizationCheckArg::set_status(grpc_status_code status) { c_arg_->status = status; } @@ -247,11 +257,13 @@ TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() {} /** gRPC TLS credential options API implementation **/ TlsCredentialsOptions::TlsCredentialsOptions( grpc_ssl_client_certificate_request_type cert_request_type, + grpc_tls_server_verification_option server_verification_option, std::shared_ptr key_materials_config, std::shared_ptr credential_reload_config, std::shared_ptr server_authorization_check_config) : cert_request_type_(cert_request_type), + server_verification_option_(server_verification_option), key_materials_config_(std::move(key_materials_config)), credential_reload_config_(std::move(credential_reload_config)), server_authorization_check_config_( @@ -272,6 +284,8 @@ TlsCredentialsOptions::TlsCredentialsOptions( grpc_tls_credentials_options_set_server_authorization_check_config( c_credentials_options_, server_authorization_check_config_->c_config()); } + grpc_tls_credentials_options_set_server_verification_option( + c_credentials_options_, server_verification_option); } TlsCredentialsOptions::~TlsCredentialsOptions() {} diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index a1404a05688..1a0e9ee9c4b 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -176,12 +176,34 @@ static int check_x509_pem_cert(const grpc_auth_context* ctx, return 1; } +static int check_x509_pem_cert_chain(const grpc_auth_context* ctx, + const char* expected_pem_cert_chain) { + grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( + ctx, GRPC_X509_PEM_CERT_CHAIN_PROPERTY_NAME); + const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it); + if (prop == nullptr) { + gpr_log(GPR_ERROR, "Pem certificate chain property not found."); + return 0; + } + if (strncmp(prop->value, expected_pem_cert_chain, prop->value_length) != 0) { + gpr_log(GPR_ERROR, "Expected pem cert chain %s and got %s", + expected_pem_cert_chain, prop->value); + return 0; + } + if (grpc_auth_property_iterator_next(&it) != nullptr) { + gpr_log(GPR_ERROR, "Expected only one property for pem cert chain."); + return 0; + } + return 1; +} + static void test_cn_only_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; const char* expected_cn = "cn1"; const char* expected_pem_cert = "pem_cert1"; - GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK); + const char* expected_pem_cert_chain = "pem_cert1_chain"; + GPR_ASSERT(tsi_construct_peer(4, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); @@ -191,6 +213,9 @@ static void test_cn_only_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[2]) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_X509_PEM_CERT_CHAIN_PROPERTY, expected_pem_cert_chain, + &peer.properties[3]) == TSI_OK); grpc_core::RefCountedPtr ctx = grpc_ssl_peer_to_auth_context(&peer, GRPC_SSL_TRANSPORT_SECURITY_TYPE); GPR_ASSERT(ctx != nullptr); @@ -200,6 +225,7 @@ static void test_cn_only_ssl_peer_to_auth_context(void) { GPR_ASSERT(check_transport_security_type(ctx.get())); GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); + GPR_ASSERT(check_x509_pem_cert_chain(ctx.get(), expected_pem_cert_chain)); rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); @@ -215,7 +241,8 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { const char* expected_cn = "cn1"; const char* expected_san = "san1"; const char* expected_pem_cert = "pem_cert1"; - GPR_ASSERT(tsi_construct_peer(4, &peer) == TSI_OK); + const char* expected_pem_cert_chain = "pem_cert1_chain"; + GPR_ASSERT(tsi_construct_peer(5, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); @@ -228,6 +255,9 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[3]) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_X509_PEM_CERT_CHAIN_PROPERTY, expected_pem_cert_chain, + &peer.properties[4]) == TSI_OK); grpc_core::RefCountedPtr ctx = grpc_ssl_peer_to_auth_context(&peer, GRPC_SSL_TRANSPORT_SECURITY_TYPE); @@ -238,6 +268,7 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { GPR_ASSERT(check_transport_security_type(ctx.get())); GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); + GPR_ASSERT(check_x509_pem_cert_chain(ctx.get(), expected_pem_cert_chain)); rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); @@ -253,8 +284,9 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { const char* expected_cn = "cn1"; const char* expected_sans[] = {"san1", "san2", "san3"}; const char* expected_pem_cert = "pem_cert1"; + const char* expected_pem_cert_chain = "pem_cert1_chain"; size_t i; - GPR_ASSERT(tsi_construct_peer(3 + GPR_ARRAY_SIZE(expected_sans), &peer) == + GPR_ASSERT(tsi_construct_peer(4 + GPR_ARRAY_SIZE(expected_sans), &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, @@ -265,10 +297,13 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[2]) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_X509_PEM_CERT_CHAIN_PROPERTY, expected_pem_cert_chain, + &peer.properties[3]) == TSI_OK); for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, - expected_sans[i], &peer.properties[3 + i]) == TSI_OK); + expected_sans[i], &peer.properties[4 + i]) == TSI_OK); } grpc_core::RefCountedPtr ctx = grpc_ssl_peer_to_auth_context(&peer, GRPC_SSL_TRANSPORT_SECURITY_TYPE); @@ -279,6 +314,7 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { GPR_ASSERT(check_transport_security_type(ctx.get())); GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); + GPR_ASSERT(check_x509_pem_cert_chain(ctx.get(), expected_pem_cert_chain)); rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); @@ -294,9 +330,10 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( tsi_peer rpeer; const char* expected_cn = "cn1"; const char* expected_pem_cert = "pem_cert1"; + const char* expected_pem_cert_chain = "pem_cert1_chain"; const char* expected_sans[] = {"san1", "san2", "san3"}; size_t i; - GPR_ASSERT(tsi_construct_peer(5 + GPR_ARRAY_SIZE(expected_sans), &peer) == + GPR_ASSERT(tsi_construct_peer(6 + GPR_ARRAY_SIZE(expected_sans), &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, @@ -311,10 +348,13 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[4]) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_X509_PEM_CERT_CHAIN_PROPERTY, expected_pem_cert_chain, + &peer.properties[5]) == TSI_OK); for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, - expected_sans[i], &peer.properties[5 + i]) == TSI_OK); + expected_sans[i], &peer.properties[6 + i]) == TSI_OK); } grpc_core::RefCountedPtr ctx = grpc_ssl_peer_to_auth_context(&peer, GRPC_SSL_TRANSPORT_SECURITY_TYPE); @@ -325,6 +365,7 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( GPR_ASSERT(check_transport_security_type(ctx.get())); GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); + GPR_ASSERT(check_x509_pem_cert_chain(ctx.get(), expected_pem_cert_chain)); rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); @@ -476,7 +517,6 @@ static void test_peer_alpn_check(void) { int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); - test_unauthenticated_ssl_peer(); test_cn_only_ssl_peer_to_auth_context(); test_cn_and_one_san_ssl_peer_to_auth_context(); diff --git a/test/core/security/tls_security_connector_test.cc b/test/core/security/tls_security_connector_test.cc index bab6575a19e..475157e37be 100644 --- a/test/core/security/tls_security_connector_test.cc +++ b/test/core/security/tls_security_connector_test.cc @@ -118,7 +118,7 @@ class TlsSecurityConnectorTest : public ::testing::Test { TEST_F(TlsSecurityConnectorTest, NoKeysAndConfig) { grpc_ssl_certificate_config_reload_status reload_status; grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_FAILED_PRECONDITION); options_->Unref(); } @@ -127,7 +127,7 @@ TEST_F(TlsSecurityConnectorTest, NoKeySuccessReload) { grpc_ssl_certificate_config_reload_status reload_status; SetOptions(SUCCESS); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_OK); EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); options_->Unref(); @@ -137,7 +137,7 @@ TEST_F(TlsSecurityConnectorTest, NoKeyFailReload) { grpc_ssl_certificate_config_reload_status reload_status; SetOptions(FAIL); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_INTERNAL); EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); options_->Unref(); @@ -148,7 +148,7 @@ TEST_F(TlsSecurityConnectorTest, NoKeyAsyncReload) { GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; SetOptions(ASYNC); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_UNIMPLEMENTED); EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); options_->Unref(); @@ -159,7 +159,7 @@ TEST_F(TlsSecurityConnectorTest, NoKeyUnchangedReload) { GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; SetOptions(UNCHANGED); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_OK); EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); options_->Unref(); @@ -170,7 +170,7 @@ TEST_F(TlsSecurityConnectorTest, WithKeyNoReload) { GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; SetKeyMaterialsConfig(); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_OK); options_->Unref(); } @@ -180,7 +180,7 @@ TEST_F(TlsSecurityConnectorTest, WithKeySuccessReload) { SetOptions(SUCCESS); SetKeyMaterialsConfig(); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_OK); EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); options_->Unref(); @@ -191,7 +191,7 @@ TEST_F(TlsSecurityConnectorTest, WithKeyFailReload) { SetOptions(FAIL); SetKeyMaterialsConfig(); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_OK); EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); options_->Unref(); @@ -203,7 +203,7 @@ TEST_F(TlsSecurityConnectorTest, WithKeyAsyncReload) { SetOptions(ASYNC); SetKeyMaterialsConfig(); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_OK); EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); options_->Unref(); @@ -215,7 +215,7 @@ TEST_F(TlsSecurityConnectorTest, WithKeyUnchangedReload) { SetOptions(UNCHANGED); SetKeyMaterialsConfig(); grpc_status_code status = - TlsFetchKeyMaterials(config_, *options_, &reload_status); + TlsFetchKeyMaterials(config_, *options_, true, &reload_status); EXPECT_EQ(status, GRPC_STATUS_OK); EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); options_->Unref(); diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 8a5dd6e4a0a..3f85bb1e88d 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -35,6 +35,7 @@ extern "C" { #include +#include } #define SSL_TSI_TEST_ALPN1 "foo" @@ -855,6 +856,36 @@ void ssl_tsi_test_extract_x509_subject_names() { tsi_peer_destruct(&peer); } +void ssl_tsi_test_extract_cert_chain() { + gpr_log(GPR_INFO, "ssl_tsi_test_extract_cert_chain"); + char* cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server1.pem"); + char* ca = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "ca.pem"); + char* chain = static_cast( + gpr_zalloc(sizeof(char) * (strlen(cert) + strlen(ca) + 1))); + memcpy(chain, cert, strlen(cert)); + memcpy(chain + strlen(cert), ca, strlen(ca)); + STACK_OF(X509)* cert_chain = sk_X509_new_null(); + GPR_ASSERT(cert_chain != nullptr); + BIO* bio = BIO_new_mem_buf(chain, strlen(chain)); + GPR_ASSERT(bio != nullptr); + STACK_OF(X509_INFO)* certInfos = + PEM_X509_INFO_read_bio(bio, nullptr, nullptr, nullptr); + GPR_ASSERT(certInfos != nullptr); + for (int i = 0; i < sk_X509_INFO_num(certInfos); i++) { + X509_INFO* certInfo = sk_X509_INFO_value(certInfos, i); + if (certInfo->x509 != nullptr) { + GPR_ASSERT(sk_X509_push(cert_chain, certInfo->x509) != 0); + X509_up_ref(certInfo->x509); + } + } + tsi_peer_property chain_property; + GPR_ASSERT(tsi_ssl_get_cert_chain_contents(cert_chain, &chain_property) == + TSI_OK); + GPR_ASSERT(memcmp(chain, chain_property.value.data, + chain_property.value.length) == 0); + gpr_free(chain); +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); @@ -881,6 +912,7 @@ int main(int argc, char** argv) { ssl_tsi_test_handshaker_factory_internals(); ssl_tsi_test_duplicate_root_certificates(); ssl_tsi_test_extract_x509_subject_names(); + ssl_tsi_test_extract_cert_chain(); grpc_shutdown(); return 0; } diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index 07c428de084..3cc0ebfb8e9 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -563,7 +563,8 @@ TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) { test_server_authorization_check)); TlsCredentialsOptions options = TlsCredentialsOptions( - GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, key_materials_config, + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, + GRPC_TLS_SERVER_VERIFICATION, key_materials_config, credential_reload_config, server_authorization_check_config); grpc_tls_credentials_options* c_options = options.c_credentials_options(); EXPECT_EQ(c_options->cert_request_type(), @@ -661,8 +662,9 @@ TEST_F(CredentialsTest, LoadTlsChannelCredentials) { test_server_authorization_check)); TlsCredentialsOptions options = TlsCredentialsOptions( - GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, nullptr, - credential_reload_config, server_authorization_check_config); + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, + GRPC_TLS_SERVER_VERIFICATION, nullptr, credential_reload_config, + server_authorization_check_config); std::shared_ptr channel_credentials = grpc::experimental::TlsCredentials(options); GPR_ASSERT(channel_credentials != nullptr); From 2f0362ee3a370530db0c1611e4fe743e7d8c3c54 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Sun, 5 Jan 2020 16:27:30 -0800 Subject: [PATCH 17/31] Remove unused (and defective) constructor --- include/grpcpp/impl/codegen/callback_common.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 6b4cbdec03f..aa3bd26e1c5 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -150,11 +150,6 @@ class CallbackWithSuccessTag CallbackWithSuccessTag() : call_(nullptr) {} - CallbackWithSuccessTag(grpc_call* call, std::function f, - CompletionQueueTag* ops, bool can_inline) { - Set(call, f, ops, can_inline); - } - CallbackWithSuccessTag(const CallbackWithSuccessTag&) = delete; CallbackWithSuccessTag& operator=(const CallbackWithSuccessTag&) = delete; From b50280a61a98a4c6a834aa1b6ea7d42464be252f Mon Sep 17 00:00:00 2001 From: Akshay Kumar Date: Mon, 6 Jan 2020 09:12:21 -0800 Subject: [PATCH 18/31] FullChainExperimental-01-200106-generateprojects --- src/core/tsi/ssl_transport_security.h | 7 ++++--- test/core/surface/public_headers_must_be_c89.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index c5daba01779..2ccd15088c9 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -20,13 +20,14 @@ #define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H #include -extern "C" { -#include -} #include "src/core/lib/gprpp/string_view.h" #include "src/core/tsi/transport_security_interface.h" +extern "C" { +#include +} + /* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */ #define TSI_X509_CERTIFICATE_TYPE "X509" diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 58a2d7a4d9f..3c20e55620e 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -201,6 +201,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_local_server_credentials_create); printf("%lx", (unsigned long) grpc_tls_credentials_options_create); printf("%lx", (unsigned long) grpc_tls_credentials_options_set_cert_request_type); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_server_verification_option); printf("%lx", (unsigned long) grpc_tls_credentials_options_set_key_materials_config); printf("%lx", (unsigned long) grpc_tls_credentials_options_set_credential_reload_config); printf("%lx", (unsigned long) grpc_tls_credentials_options_set_server_authorization_check_config); From 3eadaa1aa811cc5b0ca905686c6d4b7c160b156a Mon Sep 17 00:00:00 2001 From: Akshay Kumar Date: Mon, 6 Jan 2020 11:19:40 -0800 Subject: [PATCH 19/31] FullChainExperimental-01-200106-rb --- .../security/security_connector/tls/tls_security_connector.cc | 1 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 +++ 3 files changed, 6 insertions(+) diff --git a/src/core/lib/security/security_connector/tls/tls_security_connector.cc b/src/core/lib/security/security_connector/tls/tls_security_connector.cc index 205f1dda7ff..702a6352ef3 100644 --- a/src/core/lib/security/security_connector/tls/tls_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/tls_security_connector.cc @@ -407,6 +407,7 @@ void TlsChannelSecurityConnector::ServerAuthorizationCheckArgDestroy( } gpr_free((void*)arg->target_name); gpr_free((void*)arg->peer_cert); + if (arg->peer_cert_full_chain) gpr_free((void*)arg->peer_cert_full_chain); gpr_free((void*)arg->error_details); if (arg->destroy_context != nullptr) { arg->destroy_context(arg->context); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index e75b83ba17e..4e50a5c3ea7 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -159,6 +159,7 @@ grpc_local_credentials_create_type grpc_local_credentials_create_import; grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import; grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import; grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import; +grpc_tls_credentials_options_set_server_verification_option_type grpc_tls_credentials_options_set_server_verification_option_import; grpc_tls_credentials_options_set_key_materials_config_type grpc_tls_credentials_options_set_key_materials_config_import; grpc_tls_credentials_options_set_credential_reload_config_type grpc_tls_credentials_options_set_credential_reload_config_import; grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls_credentials_options_set_server_authorization_check_config_import; @@ -430,6 +431,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_local_server_credentials_create_import = (grpc_local_server_credentials_create_type) GetProcAddress(library, "grpc_local_server_credentials_create"); grpc_tls_credentials_options_create_import = (grpc_tls_credentials_options_create_type) GetProcAddress(library, "grpc_tls_credentials_options_create"); grpc_tls_credentials_options_set_cert_request_type_import = (grpc_tls_credentials_options_set_cert_request_type_type) GetProcAddress(library, "grpc_tls_credentials_options_set_cert_request_type"); + grpc_tls_credentials_options_set_server_verification_option_import = (grpc_tls_credentials_options_set_server_verification_option_type) GetProcAddress(library, "grpc_tls_credentials_options_set_server_verification_option"); grpc_tls_credentials_options_set_key_materials_config_import = (grpc_tls_credentials_options_set_key_materials_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_key_materials_config"); grpc_tls_credentials_options_set_credential_reload_config_import = (grpc_tls_credentials_options_set_credential_reload_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_credential_reload_config"); grpc_tls_credentials_options_set_server_authorization_check_config_import = (grpc_tls_credentials_options_set_server_authorization_check_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_server_authorization_check_config"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 0205f60d06f..32aef58ee0b 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -452,6 +452,9 @@ extern grpc_tls_credentials_options_create_type grpc_tls_credentials_options_cre typedef int(*grpc_tls_credentials_options_set_cert_request_type_type)(grpc_tls_credentials_options* options, grpc_ssl_client_certificate_request_type type); extern grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import; #define grpc_tls_credentials_options_set_cert_request_type grpc_tls_credentials_options_set_cert_request_type_import +typedef int(*grpc_tls_credentials_options_set_server_verification_option_type)(grpc_tls_credentials_options* options, grpc_tls_server_verification_option server_verification_option); +extern grpc_tls_credentials_options_set_server_verification_option_type grpc_tls_credentials_options_set_server_verification_option_import; +#define grpc_tls_credentials_options_set_server_verification_option grpc_tls_credentials_options_set_server_verification_option_import typedef int(*grpc_tls_credentials_options_set_key_materials_config_type)(grpc_tls_credentials_options* options, grpc_tls_key_materials_config* config); extern grpc_tls_credentials_options_set_key_materials_config_type grpc_tls_credentials_options_set_key_materials_config_import; #define grpc_tls_credentials_options_set_key_materials_config grpc_tls_credentials_options_set_key_materials_config_import From 5c4e28583068dcceeb56917e4d86a2cf43c13b03 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 6 Jan 2020 11:54:57 -0800 Subject: [PATCH 20/31] Use "raise_for_status" --- src/python/grpcio/grpc/experimental/aio/_call.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index 36f07ce4d92..f04c6cdd761 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -218,7 +218,7 @@ class Call(_base_call.Call): self._status.set_result(status) self._code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE[status.code()] - async def _raise_if_not_ok(self) -> None: + async def _raise_for_status(self) -> None: if self._locally_cancelled: raise asyncio.CancelledError() await self._status @@ -296,7 +296,7 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): self.cancel() # Raises here if RPC failed or cancelled - await self._raise_if_not_ok() + await self._raise_for_status() return _common.deserialize(serialized_response, self._response_deserializer) @@ -436,14 +436,14 @@ class UnaryStreamCall(Call, _base_call.UnaryStreamCall): async def read(self) -> ResponseType: if self._status.done(): - await self._raise_if_not_ok() + await self._raise_for_status() raise asyncio.InvalidStateError(_RPC_ALREADY_FINISHED_DETAILS) response_message = await self._read() if response_message is None: # If the read operation failed, Core should explain why. - await self._raise_if_not_ok() + await self._raise_for_status() # If no exception raised, there is something wrong internally. assert False, 'Read operation failed with StatusCode.OK' else: From ad83e0b77af206adbecf6a6b7100520306aabef1 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 6 Jan 2020 12:50:24 -0800 Subject: [PATCH 21/31] Clarify the set_trailing_metadata docstring --- src/python/grpcio/grpc/__init__.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 93a10644bf5..3688ac82600 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -1162,7 +1162,13 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): @abc.abstractmethod def set_trailing_metadata(self, trailing_metadata): - """Sends the trailing metadata for the RPC. + """Sets the trailing metadata for the RPC. + + Sets the trailing metadata to be sent upon completion of the RPC. + + If this method is invoked multiple times throughout the lifetime of an + RPC, the value supplied in the final invocation will be the value sent + over the wire. This method need not be called by implementations if they have no metadata to add to what the gRPC runtime will transmit. From ef376e35d77b04d8108613f5d4cdbe06c9d66ebc Mon Sep 17 00:00:00 2001 From: Akshay Kumar Date: Mon, 6 Jan 2020 13:43:14 -0800 Subject: [PATCH 22/31] FullChainExperimental-01-200106-ssl_transport_security_test --- test/core/tsi/ssl_transport_security_test.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 3f85bb1e88d..37ad7025912 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -883,7 +883,12 @@ void ssl_tsi_test_extract_cert_chain() { TSI_OK); GPR_ASSERT(memcmp(chain, chain_property.value.data, chain_property.value.length) == 0); + BIO_free(bio); gpr_free(chain); + gpr_free(cert); + gpr_free(ca); + tsi_peer_property_destruct(chain_property); + sk_X509_INFO_pop_free(inf, X509_INFO_free); } int main(int argc, char** argv) { From 48d51b24e4072908ce80c555c9c625a5153acaf2 Mon Sep 17 00:00:00 2001 From: Akshay Kumar Date: Mon, 6 Jan 2020 14:23:42 -0800 Subject: [PATCH 23/31] FullChainExperimental-01-200106-ssl_transport_security_test-2 --- test/core/tsi/ssl_transport_security_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 37ad7025912..2acfcd03dfd 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -887,8 +887,8 @@ void ssl_tsi_test_extract_cert_chain() { gpr_free(chain); gpr_free(cert); gpr_free(ca); - tsi_peer_property_destruct(chain_property); - sk_X509_INFO_pop_free(inf, X509_INFO_free); + tsi_peer_property_destruct(&chain_property); + sk_X509_INFO_pop_free(certInfos, X509_INFO_free); } int main(int argc, char** argv) { From 4bb124f54f62436c38dac1f217e4d7f26a3e4a76 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 6 Jan 2020 14:24:40 -0800 Subject: [PATCH 24/31] Make yapf_code capable of making in-place changes --- tools/distrib/yapf_code.sh | 5 ++++- tools/run_tests/sanity/sanity_tests.yaml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/distrib/yapf_code.sh b/tools/distrib/yapf_code.sh index c377e3d7f98..4c9639ba8dc 100755 --- a/tools/distrib/yapf_code.sh +++ b/tools/distrib/yapf_code.sh @@ -15,6 +15,9 @@ set -ex +ACTION=${1:---in-place} +[[ $ACTION == '--in-place' ]] || [[ $ACTION == '--diff' ]] + # change to root directory cd "$(dirname "${0}")/../.." @@ -33,4 +36,4 @@ PYTHON=${VIRTUALENV}/bin/python "$PYTHON" -m pip install --upgrade futures "$PYTHON" -m pip install yapf==0.28.0 -$PYTHON -m yapf --diff --recursive --style=setup.cfg "${DIRS[@]}" +$PYTHON -m yapf $ACTION --recursive --style=setup.cfg "${DIRS[@]}" diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index e5579470074..59a9c240dc5 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -25,7 +25,7 @@ - script: tools/distrib/clang_tidy_code.sh - script: tools/distrib/pylint_code.sh - script: tools/distrib/python/check_grpcio_tools.py -- script: tools/distrib/yapf_code.sh +- script: tools/distrib/yapf_code.sh --diff cpu_cost: 1000 - script: tools/distrib/check_protobuf_pod_version.sh - script: tools/distrib/check_shadow_boringssl_symbol_list.sh From 3be7b4362f4737665fc4ecbee38f90e943a8e5d1 Mon Sep 17 00:00:00 2001 From: Akshay Kumar Date: Mon, 6 Jan 2020 15:22:40 -0800 Subject: [PATCH 25/31] FullChainExperimental-01-200106-ssl_transport_security_test-3 --- test/core/tsi/ssl_transport_security_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 2acfcd03dfd..69e226759f8 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -889,6 +889,7 @@ void ssl_tsi_test_extract_cert_chain() { gpr_free(ca); tsi_peer_property_destruct(&chain_property); sk_X509_INFO_pop_free(certInfos, X509_INFO_free); + sk_X509_pop_free(cert_chain, X509_free); } int main(int argc, char** argv) { From f50c5a025cb98a313360ebc3ad842970ca8eed85 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 6 Jan 2020 16:33:08 -0800 Subject: [PATCH 26/31] Revert "Merge pull request #21494 from grpc/revert-21478-max_message_size" This reverts commit 2e4ebd7478c58d119210b5b68e929e7098282f9c, reversing changes made to 1bd6fcc3388ad35047d7c0b28eb2bff862f276b3. --- include/grpcpp/server_impl.h | 7 ++----- src/cpp/server/server_builder.cc | 29 ++++++++++++++--------------- src/cpp/server/server_cc.cc | 12 ++++++++---- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index 5cc7f595d05..9506c419018 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -163,9 +163,6 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// /// Server constructors. To be used by \a ServerBuilder only. /// - /// \param max_message_size Maximum message length that the channel can - /// receive. - /// /// \param args The channel args /// /// \param sync_server_cqs The completion queues to use if the server is a @@ -182,7 +179,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on /// server completion queues passed via sync_server_cqs param. - Server(int max_message_size, ChannelArguments* args, + Server(ChannelArguments* args, std::shared_ptr>> sync_server_cqs, int min_pollers, int max_pollers, int sync_cq_timeout_msec, @@ -306,7 +303,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { std::unique_ptr> interceptor_creators_; - const int max_receive_message_size_; + int max_receive_message_size_; /// The following completion queues are ONLY used in case of Sync API /// i.e. if the server has any services with sync methods. The server uses diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index c058a75dc03..8acfe536270 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -218,20 +218,9 @@ ServerBuilder& ServerBuilder::AddListeningPort( std::unique_ptr ServerBuilder::BuildAndStart() { grpc::ChannelArguments args; - for (const auto& option : options_) { - option->UpdateArguments(&args); - option->UpdatePlugins(&plugins_); - } - - for (const auto& plugin : plugins_) { - plugin->UpdateServerBuilder(this); - plugin->UpdateChannelArguments(&args); - } - if (max_receive_message_size_ >= -1) { args.SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, max_receive_message_size_); } - // The default message size is -1 (max), so no need to explicitly set it for // -1. if (max_send_message_size_ >= 0) { @@ -254,6 +243,16 @@ std::unique_ptr ServerBuilder::BuildAndStart() { grpc_resource_quota_arg_vtable()); } + for (const auto& option : options_) { + option->UpdateArguments(&args); + option->UpdatePlugins(&plugins_); + } + + for (const auto& plugin : plugins_) { + plugin->UpdateServerBuilder(this); + plugin->UpdateChannelArguments(&args); + } + // == Determine if the server has any syncrhonous methods == bool has_sync_methods = false; for (const auto& value : services_) { @@ -332,10 +331,10 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } std::unique_ptr server(new grpc::Server( - max_receive_message_size_, &args, sync_server_cqs, - sync_server_settings_.min_pollers, sync_server_settings_.max_pollers, - sync_server_settings_.cq_timeout_msec, std::move(acceptors_), - resource_quota_, std::move(interceptor_creators_))); + &args, sync_server_cqs, sync_server_settings_.min_pollers, + sync_server_settings_.max_pollers, sync_server_settings_.cq_timeout_msec, + std::move(acceptors_), resource_quota_, + std::move(interceptor_creators_))); grpc_impl::ServerInitializer* initializer = server->initializer(); diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index ef4245b0e57..56f189cedaa 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -15,6 +15,7 @@ * */ +#include #include #include @@ -23,6 +24,7 @@ #include #include +#include #include #include #include @@ -964,7 +966,7 @@ class Server::SyncRequestThreadManager : public grpc::ThreadManager { static grpc::internal::GrpcLibraryInitializer g_gli_initializer; Server::Server( - int max_receive_message_size, grpc::ChannelArguments* args, + grpc::ChannelArguments* args, std::shared_ptr>> sync_server_cqs, int min_pollers, int max_pollers, int sync_cq_timeout_msec, @@ -976,7 +978,7 @@ Server::Server( interceptor_creators) : acceptors_(std::move(acceptors)), interceptor_creators_(std::move(interceptor_creators)), - max_receive_message_size_(max_receive_message_size), + max_receive_message_size_(-1), sync_server_cqs_(std::move(sync_server_cqs)), started_(false), shutdown_(false), @@ -1026,10 +1028,12 @@ Server::Server( static_cast( channel_args.args[i].value.pointer.p)); } - break; + } + if (0 == + strcmp(channel_args.args[i].key, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH)) { + max_receive_message_size_ = channel_args.args[i].value.integer; } } - server_ = grpc_server_create(&channel_args, nullptr); } From 138ce26bb54999ddf88281d9514509b4a4b2411b Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 6 Jan 2020 16:40:08 -0800 Subject: [PATCH 27/31] Fixes --- src/cpp/server/server_builder.cc | 21 ++++++++++++++++----- src/cpp/server/server_cc.cc | 3 +-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 8acfe536270..71f17da0a4b 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -26,6 +26,7 @@ #include +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/cpp/server/external_connection_acceptor_impl.h" @@ -218,7 +219,22 @@ ServerBuilder& ServerBuilder::AddListeningPort( std::unique_ptr ServerBuilder::BuildAndStart() { grpc::ChannelArguments args; + + for (const auto& option : options_) { + option->UpdateArguments(&args); + option->UpdatePlugins(&plugins_); + } if (max_receive_message_size_ >= -1) { + grpc_channel_args c_args = args.c_channel_args(); + const grpc_arg* arg = + grpc_channel_args_find(&c_args, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH); + // Some option has set max_receive_message_length and it is also set + // directly on the ServerBuilder. + if (arg != nullptr) { + gpr_log( + GPR_ERROR, + "gRPC ServerBuilder receives multiple max_receive_message_length"); + } args.SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, max_receive_message_size_); } // The default message size is -1 (max), so no need to explicitly set it for @@ -243,11 +259,6 @@ std::unique_ptr ServerBuilder::BuildAndStart() { grpc_resource_quota_arg_vtable()); } - for (const auto& option : options_) { - option->UpdateArguments(&args); - option->UpdatePlugins(&plugins_); - } - for (const auto& plugin : plugins_) { plugin->UpdateServerBuilder(this); plugin->UpdateChannelArguments(&args); diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 56f189cedaa..5367fb25ebb 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -15,7 +15,6 @@ * */ -#include #include #include @@ -978,7 +977,7 @@ Server::Server( interceptor_creators) : acceptors_(std::move(acceptors)), interceptor_creators_(std::move(interceptor_creators)), - max_receive_message_size_(-1), + max_receive_message_size_(INT_MIN), sync_server_cqs_(std::move(sync_server_cqs)), started_(false), shutdown_(false), From 48f026d90ece794eb718d7749e0b54b83ef76feb Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 30 Oct 2019 17:40:53 -0700 Subject: [PATCH 28/31] gRPC TCP Transmit-side Zerocopy. Implements TCP Tx-side zerocopy. Must be explicitly enabled to use. For large RPCs (>= 16KiB) it reduces the amount of CPU time spent since it avoids a userspace to kernel data buffer copy. However, there is a tradeoff - the application must process a callback on the socket error queue placed by the kernel, informing the application that the data buffer can be freed since the kernel is done. The cost of processing the error queue means that we do not have an advantage for small RPCs. --- include/grpc/impl/codegen/grpc_types.h | 14 + .../lib/iomgr/socket_utils_common_posix.cc | 14 + src/core/lib/iomgr/socket_utils_posix.h | 12 + src/core/lib/iomgr/tcp_posix.cc | 663 ++++++++++++++++-- .../iomgr/tcp_server_utils_posix_common.cc | 8 + 5 files changed, 655 insertions(+), 56 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 836441f8948..89fd15faf1a 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -323,6 +323,20 @@ typedef struct { "grpc.experimental.tcp_min_read_chunk_size" #define GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE \ "grpc.experimental.tcp_max_read_chunk_size" +/* TCP TX Zerocopy enable state: zero is disabled, non-zero is enabled. By + default, it is disabled. */ +#define GRPC_ARG_TCP_TX_ZEROCOPY_ENABLED \ + "grpc.experimental.tcp_tx_zerocopy_enabled" +/* TCP TX Zerocopy send threshold: only zerocopy if >= this many bytes sent. By + default, this is set to 16KB. */ +#define GRPC_ARG_TCP_TX_ZEROCOPY_SEND_BYTES_THRESHOLD \ + "grpc.experimental.tcp_tx_zerocopy_send_bytes_threshold" +/* TCP TX Zerocopy max simultaneous sends: limit for maximum number of pending + calls to tcp_write() using zerocopy. A tcp_write() is considered pending + until the kernel performs the zerocopy-done callback for all sendmsg() calls + issued by the tcp_write(). By default, this is set to 4. */ +#define GRPC_ARG_TCP_TX_ZEROCOPY_MAX_SIMULT_SENDS \ + "grpc.experimental.tcp_tx_zerocopy_max_simultaneous_sends" /* Timeout in milliseconds to use for calls to the grpclb load balancer. If 0 or unset, the balancer calls will have no deadline. */ #define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_call_timeout_ms" diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index f46cbd51c88..3974ae7dec2 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -50,6 +50,20 @@ #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +/* set a socket to use zerocopy */ +grpc_error* grpc_set_socket_zerocopy(int fd) { +#ifdef GRPC_LINUX_ERRQUEUE + const int enable = 1; + auto err = setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &enable, sizeof(enable)); + if (err != 0) { + return GRPC_OS_ERROR(errno, "setsockopt(SO_ZEROCOPY)"); + } + return GRPC_ERROR_NONE; +#else + return GRPC_OS_ERROR(ENOSYS, "setsockopt(SO_ZEROCOPY)"); +#endif +} + /* set a socket to non blocking mode */ grpc_error* grpc_set_socket_nonblocking(int fd, int non_blocking) { int oldflags = fcntl(fd, F_GETFL, 0); diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h index a708a7a0ed5..734d340a953 100644 --- a/src/core/lib/iomgr/socket_utils_posix.h +++ b/src/core/lib/iomgr/socket_utils_posix.h @@ -31,10 +31,22 @@ #include "src/core/lib/iomgr/socket_factory_posix.h" #include "src/core/lib/iomgr/socket_mutator.h" +#ifdef GRPC_LINUX_ERRQUEUE +#ifndef SO_ZEROCOPY +#define SO_ZEROCOPY 60 +#endif +#ifndef SO_EE_ORIGIN_ZEROCOPY +#define SO_EE_ORIGIN_ZEROCOPY 5 +#endif +#endif /* ifdef GRPC_LINUX_ERRQUEUE */ + /* a wrapper for accept or accept4 */ int grpc_accept4(int sockfd, grpc_resolved_address* resolved_addr, int nonblock, int cloexec); +/* set a socket to use zerocopy */ +grpc_error* grpc_set_socket_zerocopy(int fd); + /* set a socket to non blocking mode */ grpc_error* grpc_set_socket_nonblocking(int fd, int non_blocking); diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 668a0c805e8..c96031183b3 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -49,9 +50,11 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" @@ -71,6 +74,15 @@ #define SENDMSG_FLAGS 0 #endif +// TCP zero copy sendmsg flag. +// NB: We define this here as a fallback in case we're using an older set of +// library headers that has not defined MSG_ZEROCOPY. Since this constant is +// part of the kernel, we are guaranteed it will never change/disagree so +// defining it here is safe. +#ifndef MSG_ZEROCOPY +#define MSG_ZEROCOPY 0x4000000 +#endif + #ifdef GRPC_MSG_IOVLEN_TYPE typedef GRPC_MSG_IOVLEN_TYPE msg_iovlen_type; #else @@ -79,6 +91,264 @@ typedef size_t msg_iovlen_type; extern grpc_core::TraceFlag grpc_tcp_trace; +namespace grpc_core { + +class TcpZerocopySendRecord { + public: + TcpZerocopySendRecord() { grpc_slice_buffer_init(&buf_); } + + ~TcpZerocopySendRecord() { + AssertEmpty(); + grpc_slice_buffer_destroy_internal(&buf_); + } + + // Given the slices that we wish to send, and the current offset into the + // slice buffer (indicating which have already been sent), populate an iovec + // array that will be used for a zerocopy enabled sendmsg(). + msg_iovlen_type PopulateIovs(size_t* unwind_slice_idx, + size_t* unwind_byte_idx, size_t* sending_length, + iovec* iov); + + // A sendmsg() may not be able to send the bytes that we requested at this + // time, returning EAGAIN (possibly due to backpressure). In this case, + // unwind the offset into the slice buffer so we retry sending these bytes. + void UnwindIfThrottled(size_t unwind_slice_idx, size_t unwind_byte_idx) { + out_offset_.byte_idx = unwind_byte_idx; + out_offset_.slice_idx = unwind_slice_idx; + } + + // Update the offset into the slice buffer based on how much we wanted to sent + // vs. what sendmsg() actually sent (which may be lower, possibly due to + // backpressure). + void UpdateOffsetForBytesSent(size_t sending_length, size_t actually_sent); + + // Indicates whether all underlying data has been sent or not. + bool AllSlicesSent() { return out_offset_.slice_idx == buf_.count; } + + // Reset this structure for a new tcp_write() with zerocopy. + void PrepareForSends(grpc_slice_buffer* slices_to_send) { + AssertEmpty(); + out_offset_.slice_idx = 0; + out_offset_.byte_idx = 0; + grpc_slice_buffer_swap(slices_to_send, &buf_); + Ref(); + } + + // References: 1 reference per sendmsg(), and 1 for the tcp_write(). + void Ref() { ref_.FetchAdd(1, MemoryOrder::RELAXED); } + + // Unref: called when we get an error queue notification for a sendmsg(), if a + // sendmsg() failed or when tcp_write() is done. + bool Unref() { + const intptr_t prior = ref_.FetchSub(1, MemoryOrder::ACQ_REL); + GPR_DEBUG_ASSERT(prior > 0); + if (prior == 1) { + AllSendsComplete(); + return true; + } + return false; + } + + private: + struct OutgoingOffset { + size_t slice_idx = 0; + size_t byte_idx = 0; + }; + + void AssertEmpty() { + GPR_DEBUG_ASSERT(buf_.count == 0); + GPR_DEBUG_ASSERT(buf_.length == 0); + GPR_DEBUG_ASSERT(ref_.Load(MemoryOrder::RELAXED) == 0); + } + + // When all sendmsg() calls associated with this tcp_write() have been + // completed (ie. we have received the notifications for each sequence number + // for each sendmsg()) and all reference counts have been dropped, drop our + // reference to the underlying data since we no longer need it. + void AllSendsComplete() { + GPR_DEBUG_ASSERT(ref_.Load(MemoryOrder::RELAXED) == 0); + grpc_slice_buffer_reset_and_unref_internal(&buf_); + } + + grpc_slice_buffer buf_; + Atomic ref_; + OutgoingOffset out_offset_; +}; + +class TcpZerocopySendCtx { + public: + static constexpr int kDefaultMaxSends = 4; + static constexpr size_t kDefaultSendBytesThreshold = 16 * 1024; // 16KB + + TcpZerocopySendCtx(int max_sends = kDefaultMaxSends, + size_t send_bytes_threshold = kDefaultSendBytesThreshold) + : max_sends_(max_sends), + free_send_records_size_(max_sends), + threshold_bytes_(send_bytes_threshold) { + send_records_ = static_cast( + gpr_malloc(max_sends * sizeof(*send_records_))); + free_send_records_ = static_cast( + gpr_malloc(max_sends * sizeof(*free_send_records_))); + if (send_records_ == nullptr || free_send_records_ == nullptr) { + gpr_free(send_records_); + gpr_free(free_send_records_); + gpr_log(GPR_INFO, "Disabling TCP TX zerocopy due to memory pressure.\n"); + memory_limited_ = true; + } else { + for (int idx = 0; idx < max_sends_; ++idx) { + new (send_records_ + idx) TcpZerocopySendRecord(); + free_send_records_[idx] = send_records_ + idx; + } + } + } + + ~TcpZerocopySendCtx() { + if (send_records_ != nullptr) { + for (int idx = 0; idx < max_sends_; ++idx) { + send_records_[idx].~TcpZerocopySendRecord(); + } + } + gpr_free(send_records_); + gpr_free(free_send_records_); + } + + // True if we were unable to allocate the various bookkeeping structures at + // transport initialization time. If memory limited, we do not zerocopy. + bool memory_limited() const { return memory_limited_; } + + // TCP send zerocopy maintains an implicit sequence number for every + // successful sendmsg() with zerocopy enabled; the kernel later gives us an + // error queue notification with this sequence number indicating that the + // underlying data buffers that we sent can now be released. Once that + // notification is received, we can release the buffers associated with this + // zerocopy send record. Here, we associate the sequence number with the data + // buffers that were sent with the corresponding call to sendmsg(). + void NoteSend(TcpZerocopySendRecord* record) { + record->Ref(); + AssociateSeqWithSendRecord(last_send_, record); + ++last_send_; + } + + // If sendmsg() actually failed, though, we need to revert the sequence number + // that we speculatively bumped before calling sendmsg(). Note that we bump + // this sequence number and perform relevant bookkeeping (see: NoteSend()) + // *before* calling sendmsg() since, if we called it *after* sendmsg(), then + // there is a possible race with the release notification which could occur on + // another thread before we do the necessary bookkeeping. Hence, calling + // NoteSend() *before* sendmsg() and implementing an undo function is needed. + void UndoSend() { + --last_send_; + if (ReleaseSendRecord(last_send_)->Unref()) { + // We should still be holding the ref taken by tcp_write(). + GPR_DEBUG_ASSERT(0); + } + } + + // Simply associate this send record (and the underlying sent data buffers) + // with the implicit sequence number for this zerocopy sendmsg(). + void AssociateSeqWithSendRecord(uint32_t seq, TcpZerocopySendRecord* record) { + MutexLock guard(&lock_); + ctx_lookup_.emplace(seq, record); + } + + // Get a send record for a send that we wish to do with zerocopy. + TcpZerocopySendRecord* GetSendRecord() { + MutexLock guard(&lock_); + return TryGetSendRecordLocked(); + } + + // A given send record corresponds to a single tcp_write() with zerocopy + // enabled. This can result in several sendmsg() calls to flush all of the + // data to wire. Each sendmsg() takes a reference on the + // TcpZerocopySendRecord, and corresponds to a single sequence number. + // ReleaseSendRecord releases a reference on TcpZerocopySendRecord for a + // single sequence number. This is called either when we receive the relevant + // error queue notification (saying that we can discard the underlying + // buffers for this sendmsg()) is received from the kernel - or, in case + // sendmsg() was unsuccessful to begin with. + TcpZerocopySendRecord* ReleaseSendRecord(uint32_t seq) { + MutexLock guard(&lock_); + return ReleaseSendRecordLocked(seq); + } + + // After all the references to a TcpZerocopySendRecord are released, we can + // add it back to the pool (of size max_sends_). Note that we can only have + // max_sends_ tcp_write() instances with zerocopy enabled in flight at the + // same time. + void PutSendRecord(TcpZerocopySendRecord* record) { + GPR_DEBUG_ASSERT(record >= send_records_ && + record < send_records_ + max_sends_); + MutexLock guard(&lock_); + PutSendRecordLocked(record); + } + + // Indicate that we are disposing of this zerocopy context. This indicator + // will prevent new zerocopy writes from being issued. + void Shutdown() { shutdown_.Store(true, MemoryOrder::RELEASE); } + + // Indicates that there are no inflight tcp_write() instances with zerocopy + // enabled. + bool AllSendRecordsEmpty() { + MutexLock guard(&lock_); + return free_send_records_size_ == max_sends_; + } + + bool enabled() const { return enabled_; } + + void set_enabled(bool enabled) { + GPR_DEBUG_ASSERT(!enabled || !memory_limited()); + enabled_ = enabled; + } + + // Only use zerocopy if we are sending at least this many bytes. The + // additional overhead of reading the error queue for notifications means that + // zerocopy is not useful for small transfers. + size_t threshold_bytes() const { return threshold_bytes_; } + + private: + TcpZerocopySendRecord* ReleaseSendRecordLocked(uint32_t seq) { + auto iter = ctx_lookup_.find(seq); + GPR_DEBUG_ASSERT(iter != ctx_lookup_.end()); + TcpZerocopySendRecord* record = iter->second; + ctx_lookup_.erase(iter); + return record; + } + + TcpZerocopySendRecord* TryGetSendRecordLocked() { + if (shutdown_.Load(MemoryOrder::ACQUIRE)) { + return nullptr; + } + if (free_send_records_size_ == 0) { + return nullptr; + } + free_send_records_size_--; + return free_send_records_[free_send_records_size_]; + } + + void PutSendRecordLocked(TcpZerocopySendRecord* record) { + GPR_DEBUG_ASSERT(free_send_records_size_ < max_sends_); + free_send_records_[free_send_records_size_] = record; + free_send_records_size_++; + } + + TcpZerocopySendRecord* send_records_; + TcpZerocopySendRecord** free_send_records_; + int max_sends_; + int free_send_records_size_; + Mutex lock_; + uint32_t last_send_ = 0; + Atomic shutdown_; + bool enabled_ = false; + size_t threshold_bytes_ = kDefaultSendBytesThreshold; + std::unordered_map ctx_lookup_; + bool memory_limited_ = false; +}; + +} // namespace grpc_core + +using grpc_core::TcpZerocopySendCtx; +using grpc_core::TcpZerocopySendRecord; + namespace { struct grpc_tcp { grpc_endpoint base; @@ -142,6 +412,8 @@ struct grpc_tcp { bool ts_capable; /* Cache whether we can set timestamping options */ gpr_atm stop_error_notification; /* Set to 1 if we do not want to be notified on errors anymore */ + TcpZerocopySendCtx tcp_zerocopy_send_ctx; + TcpZerocopySendRecord* current_zerocopy_send = nullptr; }; struct backup_poller { @@ -151,6 +423,8 @@ struct backup_poller { } // namespace +static void ZerocopyDisableAndWaitForRemaining(grpc_tcp* tcp); + #define BACKUP_POLLER_POLLSET(b) ((grpc_pollset*)((b) + 1)) static gpr_atm g_uncovered_notifications_pending; @@ -339,6 +613,7 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error); static void tcp_shutdown(grpc_endpoint* ep, grpc_error* why) { grpc_tcp* tcp = reinterpret_cast(ep); + ZerocopyDisableAndWaitForRemaining(tcp); grpc_fd_shutdown(tcp->em_fd, why); grpc_resource_user_shutdown(tcp->resource_user); } @@ -357,6 +632,7 @@ static void tcp_free(grpc_tcp* tcp) { gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; gpr_mu_destroy(&tcp->tb_mu); + tcp->tcp_zerocopy_send_ctx.~TcpZerocopySendCtx(); gpr_free(tcp); } @@ -390,6 +666,7 @@ static void tcp_destroy(grpc_endpoint* ep) { grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { + ZerocopyDisableAndWaitForRemaining(tcp); gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_set_error(tcp->em_fd); } @@ -652,13 +929,13 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, /* A wrapper around sendmsg. It sends \a msg over \a fd and returns the number * of bytes sent. */ -ssize_t tcp_send(int fd, const struct msghdr* msg) { +ssize_t tcp_send(int fd, const struct msghdr* msg, int additional_flags = 0) { GPR_TIMER_SCOPE("sendmsg", 1); ssize_t sent_length; do { /* TODO(klempner): Cork if this is a partial write */ GRPC_STATS_INC_SYSCALL_WRITE(); - sent_length = sendmsg(fd, msg, SENDMSG_FLAGS); + sent_length = sendmsg(fd, msg, SENDMSG_FLAGS | additional_flags); } while (sent_length < 0 && errno == EINTR); return sent_length; } @@ -671,16 +948,52 @@ ssize_t tcp_send(int fd, const struct msghdr* msg) { */ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length); + ssize_t* sent_length, + int additional_flags = 0); /** The callback function to be invoked when we get an error on the socket. */ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); +static TcpZerocopySendRecord* tcp_get_send_zerocopy_record( + grpc_tcp* tcp, grpc_slice_buffer* buf); + #ifdef GRPC_LINUX_ERRQUEUE +static bool process_errors(grpc_tcp* tcp); + +static TcpZerocopySendRecord* tcp_get_send_zerocopy_record( + grpc_tcp* tcp, grpc_slice_buffer* buf) { + TcpZerocopySendRecord* zerocopy_send_record = nullptr; + const bool use_zerocopy = + tcp->tcp_zerocopy_send_ctx.enabled() && + tcp->tcp_zerocopy_send_ctx.threshold_bytes() < buf->length; + if (use_zerocopy) { + zerocopy_send_record = tcp->tcp_zerocopy_send_ctx.GetSendRecord(); + if (zerocopy_send_record == nullptr) { + process_errors(tcp); + zerocopy_send_record = tcp->tcp_zerocopy_send_ctx.GetSendRecord(); + } + if (zerocopy_send_record != nullptr) { + zerocopy_send_record->PrepareForSends(buf); + GPR_DEBUG_ASSERT(buf->count == 0); + GPR_DEBUG_ASSERT(buf->length == 0); + tcp->outgoing_byte_idx = 0; + tcp->outgoing_buffer = nullptr; + } + } + return zerocopy_send_record; +} + +static void ZerocopyDisableAndWaitForRemaining(grpc_tcp* tcp) { + tcp->tcp_zerocopy_send_ctx.Shutdown(); + while (!tcp->tcp_zerocopy_send_ctx.AllSendRecordsEmpty()) { + process_errors(tcp); + } +} static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length) { + ssize_t* sent_length, + int additional_flags) { if (!tcp->socket_ts_enabled) { uint32_t opt = grpc_core::kTimestampingSocketOptions; if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, @@ -708,7 +1021,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, msg->msg_controllen = CMSG_SPACE(sizeof(uint32_t)); /* If there was an error on sendmsg the logic in tcp_flush will handle it. */ - ssize_t length = tcp_send(tcp->fd, msg); + ssize_t length = tcp_send(tcp->fd, msg, additional_flags); *sent_length = length; /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { @@ -722,6 +1035,43 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, return true; } +static void UnrefMaybePutZerocopySendRecord(grpc_tcp* tcp, + TcpZerocopySendRecord* record, + uint32_t seq, const char* tag); +// Reads \a cmsg to process zerocopy control messages. +static void process_zerocopy(grpc_tcp* tcp, struct cmsghdr* cmsg) { + GPR_DEBUG_ASSERT(cmsg); + auto serr = reinterpret_cast(CMSG_DATA(cmsg)); + GPR_DEBUG_ASSERT(serr->ee_errno == 0); + GPR_DEBUG_ASSERT(serr->ee_origin == SO_EE_ORIGIN_ZEROCOPY); + const uint32_t lo = serr->ee_info; + const uint32_t hi = serr->ee_data; + for (uint32_t seq = lo; seq <= hi; ++seq) { + // TODO(arjunroy): It's likely that lo and hi refer to zerocopy sequence + // numbers that are generated by a single call to grpc_endpoint_write; ie. + // we can batch the unref operation. So, check if record is the same for + // both; if so, batch the unref/put. + TcpZerocopySendRecord* record = + tcp->tcp_zerocopy_send_ctx.ReleaseSendRecord(seq); + GPR_DEBUG_ASSERT(record); + UnrefMaybePutZerocopySendRecord(tcp, record, seq, "CALLBACK RCVD"); + } +} + +// Whether the cmsg received from error queue is of the IPv4 or IPv6 levels. +static bool CmsgIsIpLevel(const cmsghdr& cmsg) { + return (cmsg.cmsg_level == SOL_IPV6 && cmsg.cmsg_type == IPV6_RECVERR) || + (cmsg.cmsg_level == SOL_IP && cmsg.cmsg_type == IP_RECVERR); +} + +static bool CmsgIsZeroCopy(const cmsghdr& cmsg) { + if (!CmsgIsIpLevel(cmsg)) { + return false; + } + auto serr = reinterpret_cast CMSG_DATA(&cmsg); + return serr->ee_errno == 0 && serr->ee_origin == SO_EE_ORIGIN_ZEROCOPY; +} + /** Reads \a cmsg to derive timestamps from the control messages. If a valid * timestamp is found, the traced buffer list is updated with this timestamp. * The caller of this function should be looping on the control messages found @@ -783,73 +1133,76 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, /** For linux platforms, reads the socket's error queue and processes error * messages from the queue. */ -static void process_errors(grpc_tcp* tcp) { +static bool process_errors(grpc_tcp* tcp) { + bool processed_err = false; + struct iovec iov; + iov.iov_base = nullptr; + iov.iov_len = 0; + struct msghdr msg; + msg.msg_name = nullptr; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 0; + msg.msg_flags = 0; + /* Allocate enough space so we don't need to keep increasing this as size + * of OPT_STATS increase */ + constexpr size_t cmsg_alloc_space = + CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + + CMSG_SPACE(32 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t))); + /* Allocate aligned space for cmsgs received along with timestamps */ + union { + char rbuf[cmsg_alloc_space]; + struct cmsghdr align; + } aligned_buf; + msg.msg_control = aligned_buf.rbuf; + msg.msg_controllen = sizeof(aligned_buf.rbuf); + int r, saved_errno; while (true) { - struct iovec iov; - iov.iov_base = nullptr; - iov.iov_len = 0; - struct msghdr msg; - msg.msg_name = nullptr; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 0; - msg.msg_flags = 0; - - /* Allocate enough space so we don't need to keep increasing this as size - * of OPT_STATS increase */ - constexpr size_t cmsg_alloc_space = - CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + - CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + - CMSG_SPACE(32 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t))); - /* Allocate aligned space for cmsgs received along with timestamps */ - union { - char rbuf[cmsg_alloc_space]; - struct cmsghdr align; - } aligned_buf; - memset(&aligned_buf, 0, sizeof(aligned_buf)); - - msg.msg_control = aligned_buf.rbuf; - msg.msg_controllen = sizeof(aligned_buf.rbuf); - - int r, saved_errno; do { r = recvmsg(tcp->fd, &msg, MSG_ERRQUEUE); saved_errno = errno; } while (r < 0 && saved_errno == EINTR); if (r == -1 && saved_errno == EAGAIN) { - return; /* No more errors to process */ + return processed_err; /* No more errors to process */ } if (r == -1) { - return; + return processed_err; } - if ((msg.msg_flags & MSG_CTRUNC) != 0) { + if (GPR_UNLIKELY((msg.msg_flags & MSG_CTRUNC) != 0)) { gpr_log(GPR_ERROR, "Error message was truncated."); } if (msg.msg_controllen == 0) { /* There was no control message found. It was probably spurious. */ - return; + return processed_err; } bool seen = false; for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_TIMESTAMPING) { - /* Got a control message that is not a timestamp. Don't know how to - * handle this. */ + if (CmsgIsZeroCopy(*cmsg)) { + process_zerocopy(tcp, cmsg); + seen = true; + processed_err = true; + } else if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_TIMESTAMPING) { + cmsg = process_timestamp(tcp, &msg, cmsg); + seen = true; + processed_err = true; + } else { + /* Got a control message that is not a timestamp or zerocopy. Don't know + * how to handle this. */ if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "unknown control message cmsg_level:%d cmsg_type:%d", cmsg->cmsg_level, cmsg->cmsg_type); } - return; + return processed_err; } - cmsg = process_timestamp(tcp, &msg, cmsg); - seen = true; } if (!seen) { - return; + return processed_err; } } } @@ -870,18 +1223,28 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { /* We are still interested in collecting timestamps, so let's try reading * them. */ - process_errors(tcp); + bool processed = process_errors(tcp); /* This might not a timestamps error. Set the read and write closures to be * ready. */ - grpc_fd_set_readable(tcp->em_fd); - grpc_fd_set_writable(tcp->em_fd); + if (!processed) { + grpc_fd_set_readable(tcp->em_fd); + grpc_fd_set_writable(tcp->em_fd); + } grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); } #else /* GRPC_LINUX_ERRQUEUE */ +static TcpZerocopySendRecord* tcp_get_send_zerocopy_record( + grpc_tcp* tcp, grpc_slice_buffer* buf) { + return nullptr; +} + +static void ZerocopyDisableAndWaitForRemaining(grpc_tcp* tcp) {} + static bool tcp_write_with_timestamps(grpc_tcp* /*tcp*/, struct msghdr* /*msg*/, size_t /*sending_length*/, - ssize_t* /*sent_length*/) { + ssize_t* /*sent_length*/, + int /*additional_flags*/) { gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); GPR_ASSERT(0); return false; @@ -907,12 +1270,138 @@ void tcp_shutdown_buffer_list(grpc_tcp* tcp) { } } -/* returns true if done, false if pending; if returning true, *error is set */ #if defined(IOV_MAX) && IOV_MAX < 1000 #define MAX_WRITE_IOVEC IOV_MAX #else #define MAX_WRITE_IOVEC 1000 #endif +msg_iovlen_type TcpZerocopySendRecord::PopulateIovs(size_t* unwind_slice_idx, + size_t* unwind_byte_idx, + size_t* sending_length, + iovec* iov) { + msg_iovlen_type iov_size; + *unwind_slice_idx = out_offset_.slice_idx; + *unwind_byte_idx = out_offset_.byte_idx; + for (iov_size = 0; + out_offset_.slice_idx != buf_.count && iov_size != MAX_WRITE_IOVEC; + iov_size++) { + iov[iov_size].iov_base = + GRPC_SLICE_START_PTR(buf_.slices[out_offset_.slice_idx]) + + out_offset_.byte_idx; + iov[iov_size].iov_len = + GRPC_SLICE_LENGTH(buf_.slices[out_offset_.slice_idx]) - + out_offset_.byte_idx; + *sending_length += iov[iov_size].iov_len; + ++(out_offset_.slice_idx); + out_offset_.byte_idx = 0; + } + GPR_DEBUG_ASSERT(iov_size > 0); + return iov_size; +} + +void TcpZerocopySendRecord::UpdateOffsetForBytesSent(size_t sending_length, + size_t actually_sent) { + size_t trailing = sending_length - actually_sent; + while (trailing > 0) { + size_t slice_length; + out_offset_.slice_idx--; + slice_length = GRPC_SLICE_LENGTH(buf_.slices[out_offset_.slice_idx]); + if (slice_length > trailing) { + out_offset_.byte_idx = slice_length - trailing; + break; + } else { + trailing -= slice_length; + } + } +} + +// returns true if done, false if pending; if returning true, *error is set +static bool do_tcp_flush_zerocopy(grpc_tcp* tcp, TcpZerocopySendRecord* record, + grpc_error** error) { + struct msghdr msg; + struct iovec iov[MAX_WRITE_IOVEC]; + msg_iovlen_type iov_size; + ssize_t sent_length = 0; + size_t sending_length; + size_t unwind_slice_idx; + size_t unwind_byte_idx; + while (true) { + sending_length = 0; + iov_size = record->PopulateIovs(&unwind_slice_idx, &unwind_byte_idx, + &sending_length, iov); + msg.msg_name = nullptr; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = iov_size; + msg.msg_flags = 0; + bool tried_sending_message = false; + // Before calling sendmsg (with or without timestamps): we + // take a single ref on the zerocopy send record. + tcp->tcp_zerocopy_send_ctx.NoteSend(record); + if (tcp->outgoing_buffer_arg != nullptr) { + if (!tcp->ts_capable || + !tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, + MSG_ZEROCOPY)) { + /* We could not set socket options to collect Fathom timestamps. + * Fallback on writing without timestamps. */ + tcp->ts_capable = false; + tcp_shutdown_buffer_list(tcp); + } else { + tried_sending_message = true; + } + } + if (!tried_sending_message) { + msg.msg_control = nullptr; + msg.msg_controllen = 0; + GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); + GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); + sent_length = tcp_send(tcp->fd, &msg, MSG_ZEROCOPY); + } + if (sent_length < 0) { + // If this particular send failed, drop ref taken earlier in this method. + tcp->tcp_zerocopy_send_ctx.UndoSend(); + if (errno == EAGAIN) { + record->UnwindIfThrottled(unwind_slice_idx, unwind_byte_idx); + return false; + } else if (errno == EPIPE) { + *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp); + tcp_shutdown_buffer_list(tcp); + return true; + } else { + *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp); + tcp_shutdown_buffer_list(tcp); + return true; + } + } + tcp->bytes_counter += sent_length; + record->UpdateOffsetForBytesSent(sending_length, + static_cast(sent_length)); + if (record->AllSlicesSent()) { + *error = GRPC_ERROR_NONE; + return true; + } + } +} + +static void UnrefMaybePutZerocopySendRecord(grpc_tcp* tcp, + TcpZerocopySendRecord* record, + uint32_t seq, const char* tag) { + if (record->Unref()) { + tcp->tcp_zerocopy_send_ctx.PutSendRecord(record); + } +} + +static bool tcp_flush_zerocopy(grpc_tcp* tcp, TcpZerocopySendRecord* record, + grpc_error** error) { + bool done = do_tcp_flush_zerocopy(tcp, record, error); + if (done) { + // Either we encountered an error, or we successfully sent all the bytes. + // In either case, we're done with this record. + UnrefMaybePutZerocopySendRecord(tcp, record, 0, "flush_done"); + } + return done; +} + static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { struct msghdr msg; struct iovec iov[MAX_WRITE_IOVEC]; @@ -927,7 +1416,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { // buffer as we write size_t outgoing_slice_idx = 0; - for (;;) { + while (true) { sending_length = 0; unwind_slice_idx = outgoing_slice_idx; unwind_byte_idx = tcp->outgoing_byte_idx; @@ -1027,12 +1516,21 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { if (error != GRPC_ERROR_NONE) { cb = tcp->write_cb; tcp->write_cb = nullptr; + if (tcp->current_zerocopy_send != nullptr) { + UnrefMaybePutZerocopySendRecord(tcp, tcp->current_zerocopy_send, 0, + "handle_write_err"); + tcp->current_zerocopy_send = nullptr; + } grpc_core::Closure::Run(DEBUG_LOCATION, cb, GRPC_ERROR_REF(error)); TCP_UNREF(tcp, "write"); return; } - if (!tcp_flush(tcp, &error)) { + bool flush_result = + tcp->current_zerocopy_send != nullptr + ? tcp_flush_zerocopy(tcp, tcp->current_zerocopy_send, &error) + : tcp_flush(tcp, &error); + if (!flush_result) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "write: delayed"); } @@ -1042,6 +1540,7 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { } else { cb = tcp->write_cb; tcp->write_cb = nullptr; + tcp->current_zerocopy_send = nullptr; if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); @@ -1057,6 +1556,7 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, GPR_TIMER_SCOPE("tcp_write", 0); grpc_tcp* tcp = reinterpret_cast(ep); grpc_error* error = GRPC_ERROR_NONE; + TcpZerocopySendRecord* zerocopy_send_record = nullptr; if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { size_t i; @@ -1073,8 +1573,8 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, } GPR_ASSERT(tcp->write_cb == nullptr); + GPR_DEBUG_ASSERT(tcp->current_zerocopy_send == nullptr); - tcp->outgoing_buffer_arg = arg; if (buf->length == 0) { grpc_core::Closure::Run( DEBUG_LOCATION, cb, @@ -1085,15 +1585,26 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, tcp_shutdown_buffer_list(tcp); return; } - tcp->outgoing_buffer = buf; - tcp->outgoing_byte_idx = 0; + + zerocopy_send_record = tcp_get_send_zerocopy_record(tcp, buf); + if (zerocopy_send_record == nullptr) { + // Either not enough bytes, or couldn't allocate a zerocopy context. + tcp->outgoing_buffer = buf; + tcp->outgoing_byte_idx = 0; + } + tcp->outgoing_buffer_arg = arg; if (arg) { GPR_ASSERT(grpc_event_engine_can_track_errors()); } - if (!tcp_flush(tcp, &error)) { + bool flush_result = + zerocopy_send_record != nullptr + ? tcp_flush_zerocopy(tcp, zerocopy_send_record, &error) + : tcp_flush(tcp, &error); + if (!flush_result) { TCP_REF(tcp, "write"); tcp->write_cb = cb; + tcp->current_zerocopy_send = zerocopy_send_record; if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "write: delayed"); } @@ -1121,6 +1632,7 @@ static void tcp_add_to_pollset_set(grpc_endpoint* ep, static void tcp_delete_from_pollset_set(grpc_endpoint* ep, grpc_pollset_set* pollset_set) { grpc_tcp* tcp = reinterpret_cast(ep); + ZerocopyDisableAndWaitForRemaining(tcp); grpc_pollset_set_del_fd(pollset_set, tcp->em_fd); } @@ -1172,9 +1684,15 @@ static const grpc_endpoint_vtable vtable = {tcp_read, grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, const grpc_channel_args* channel_args, const char* peer_string) { + static constexpr bool kZerocpTxEnabledDefault = false; int tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE; int tcp_max_read_chunk_size = 4 * 1024 * 1024; int tcp_min_read_chunk_size = 256; + bool tcp_tx_zerocopy_enabled = kZerocpTxEnabledDefault; + int tcp_tx_zerocopy_send_bytes_thresh = + grpc_core::TcpZerocopySendCtx::kDefaultSendBytesThreshold; + int tcp_tx_zerocopy_max_simult_sends = + grpc_core::TcpZerocopySendCtx::kDefaultMaxSends; grpc_resource_quota* resource_quota = grpc_resource_quota_create(nullptr); if (channel_args != nullptr) { for (size_t i = 0; i < channel_args->num_args; i++) { @@ -1199,6 +1717,23 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, resource_quota = grpc_resource_quota_ref_internal(static_cast( channel_args->args[i].value.pointer.p)); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_TCP_TX_ZEROCOPY_ENABLED)) { + tcp_tx_zerocopy_enabled = grpc_channel_arg_get_bool( + &channel_args->args[i], kZerocpTxEnabledDefault); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_TCP_TX_ZEROCOPY_SEND_BYTES_THRESHOLD)) { + grpc_integer_options options = { + grpc_core::TcpZerocopySendCtx::kDefaultSendBytesThreshold, 0, + INT_MAX}; + tcp_tx_zerocopy_send_bytes_thresh = + grpc_channel_arg_get_integer(&channel_args->args[i], options); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_TCP_TX_ZEROCOPY_MAX_SIMULT_SENDS)) { + grpc_integer_options options = { + grpc_core::TcpZerocopySendCtx::kDefaultMaxSends, 0, INT_MAX}; + tcp_tx_zerocopy_max_simult_sends = + grpc_channel_arg_get_integer(&channel_args->args[i], options); } } } @@ -1215,6 +1750,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->fd = grpc_fd_wrapped_fd(em_fd); tcp->read_cb = nullptr; tcp->write_cb = nullptr; + tcp->current_zerocopy_send = nullptr; tcp->release_fd_cb = nullptr; tcp->release_fd = nullptr; tcp->incoming_buffer = nullptr; @@ -1228,6 +1764,20 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->socket_ts_enabled = false; tcp->ts_capable = true; tcp->outgoing_buffer_arg = nullptr; + new (&tcp->tcp_zerocopy_send_ctx) TcpZerocopySendCtx( + tcp_tx_zerocopy_max_simult_sends, tcp_tx_zerocopy_send_bytes_thresh); + if (tcp_tx_zerocopy_enabled && !tcp->tcp_zerocopy_send_ctx.memory_limited()) { +#ifdef GRPC_LINUX_ERRQUEUE + const int enable = 1; + auto err = + setsockopt(tcp->fd, SOL_SOCKET, SO_ZEROCOPY, &enable, sizeof(enable)); + if (err == 0) { + tcp->tcp_zerocopy_send_ctx.set_enabled(true); + } else { + gpr_log(GPR_ERROR, "Failed to set zerocopy options on the socket."); + } +#endif + } /* paired with unref in grpc_tcp_destroy */ new (&tcp->refcount) grpc_core::RefCount(1, &grpc_tcp_trace); gpr_atm_no_barrier_store(&tcp->shutdown_count, 0); @@ -1294,6 +1844,7 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { /* Stop errors notification. */ + ZerocopyDisableAndWaitForRemaining(tcp); gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_set_error(tcp->em_fd); } diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc index ee1cd5c1027..da18cc39c51 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc @@ -157,6 +157,14 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd, if (err != GRPC_ERROR_NONE) goto error; } +#ifdef GRPC_LINUX_ERRQUEUE + err = grpc_set_socket_zerocopy(fd); + if (err != GRPC_ERROR_NONE) { + /* it's not fatal, so just log it. */ + gpr_log(GPR_DEBUG, "Node does not support SO_ZEROCOPY, continuing."); + GRPC_ERROR_UNREF(err); + } +#endif err = grpc_set_socket_nonblocking(fd, 1); if (err != GRPC_ERROR_NONE) goto error; err = grpc_set_socket_cloexec(fd, 1); From 9fb00492ffb863717f5f8df2a4e81ea1676ab2f9 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 7 Jan 2020 11:19:49 -0800 Subject: [PATCH 29/31] Pass the manager to Nicolas --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/cleanup_request.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- .github/pull_request_template.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 70464ea5a2d..e8fe25011f1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Report a bug about: Create a report to help us improve labels: kind/bug, priority/P2 -assignees: veblush +assignees: nicolasnoble --- diff --git a/.github/ISSUE_TEMPLATE/cleanup_request.md b/.github/ISSUE_TEMPLATE/cleanup_request.md index 6e5c5aec48a..11e8be8ef3e 100644 --- a/.github/ISSUE_TEMPLATE/cleanup_request.md +++ b/.github/ISSUE_TEMPLATE/cleanup_request.md @@ -2,7 +2,7 @@ name: Request a cleanup about: Suggest a cleanup in our repository labels: kind/internal cleanup, priority/P2 -assignees: veblush +assignees: nicolasnoble --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index ba5d92da901..fb3dae79227 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Request a feature about: Suggest an idea for this project labels: kind/enhancement, priority/P2 -assignees: veblush +assignees: nicolasnoble --- diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 366b68604df..57af6c21597 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,4 +8,4 @@ If you know who should review your pull request, please remove the mentioning be --> -@veblush +@nicolasnoble From 02371b7569d789e7ab6dded54ea6dfd4d8a4728d Mon Sep 17 00:00:00 2001 From: Akshay Kumar Date: Tue, 7 Jan 2020 11:22:00 -0800 Subject: [PATCH 30/31] FullChainExperimental-01-200106-ssl_transport_security_test-4 --- include/grpc/grpc_security_constants.h | 9 ++++++--- .../security/security_connector/ssl_utils.cc | 19 +++---------------- .../security/security_connector/ssl_utils.h | 7 +------ .../tls/tls_security_connector.cc | 8 ++++---- src/core/tsi/ssl_transport_security.cc | 2 +- src/core/tsi/ssl_transport_security.h | 6 +++--- src/core/tsi/transport_security_interface.h | 11 ----------- 7 files changed, 18 insertions(+), 44 deletions(-) diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index 63900e41cb3..c414101b66d 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -117,12 +117,15 @@ typedef enum { typedef enum { /** Default option: performs server certificate verification and hostname - verification */ + verification. */ GRPC_TLS_SERVER_VERIFICATION, /** Performs server certificate verification, but skips hostname verification - */ + Client is responsible for verifying server's identity via + server authorization check callback. */ GRPC_TLS_SKIP_HOSTNAME_VERIFICATION, - /** Skips both server certificate and hostname verification */ + /** Skips both server certificate and hostname verification. + Client is responsible for verifying server's identity and + server's certificate via server authorization check callback. */ GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION } grpc_tls_server_verification_option; diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index e34c66b35d6..8b99850d048 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -108,20 +108,6 @@ grpc_get_tsi_client_certificate_request_type( } } -tsi_server_verification_option grpc_get_tsi_server_verification_option( - grpc_tls_server_verification_option server_verification_option) { - switch (server_verification_option) { - case GRPC_TLS_SERVER_VERIFICATION: - return TSI_SERVER_VERIFICATION; - case GRPC_TLS_SKIP_HOSTNAME_VERIFICATION: - return TSI_SKIP_HOSTNAME_VERIFICATION; - case GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION: - return TSI_SKIP_ALL_SERVER_VERIFICATION; - default: - return TSI_SERVER_VERIFICATION; - } -} - grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) { #if TSI_OPENSSL_ALPN_SUPPORT /* Check the ALPN if ALPN is supported. */ @@ -306,7 +292,7 @@ void grpc_shallow_peer_destruct(tsi_peer* peer) { grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( tsi_ssl_pem_key_cert_pair* pem_key_cert_pair, const char* pem_root_certs, - tsi_server_verification_option server_verification_option, + bool skip_server_certificate_verification, tsi_ssl_session_cache* ssl_session_cache, tsi_ssl_client_handshaker_factory** handshaker_factory) { const char* root_certs; @@ -337,7 +323,8 @@ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( } options.cipher_suites = grpc_get_ssl_cipher_suites(); options.session_cache = ssl_session_cache; - options.server_verification_option = server_verification_option; + options.skip_server_certificate_verification = + skip_server_certificate_verification; const tsi_result result = tsi_create_ssl_client_handshaker_factory_with_options(&options, handshaker_factory); diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index e6370db9768..bf9607a3e27 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -68,18 +68,13 @@ tsi_client_certificate_request_type grpc_get_tsi_client_certificate_request_type( grpc_ssl_client_certificate_request_type grpc_request_type); -/* Map from grpc_tls_server_verification_option to - * tsi_server_verification_option. */ -tsi_server_verification_option grpc_get_tsi_server_verification_option( - grpc_tls_server_verification_option server_verification_option); - /* Return an array of strings containing alpn protocols. */ const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols); /* Initialize TSI SSL server/client handshaker factory. */ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( tsi_ssl_pem_key_cert_pair* key_cert_pair, const char* pem_root_certs, - tsi_server_verification_option server_verification_option, + bool skip_server_certificate_verification, tsi_ssl_session_cache* ssl_session_cache, tsi_ssl_client_handshaker_factory** handshaker_factory); diff --git a/src/core/lib/security/security_connector/tls/tls_security_connector.cc b/src/core/lib/security/security_connector/tls/tls_security_connector.cc index 702a6352ef3..3cd83ae1a80 100644 --- a/src/core/lib/security/security_connector/tls/tls_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/tls_security_connector.cc @@ -286,9 +286,9 @@ grpc_security_status TlsChannelSecurityConnector::ReplaceHandshakerFactory( tsi_ssl_session_cache* ssl_session_cache) { const TlsCredentials* creds = static_cast(channel_creds()); - tsi_server_verification_option server_verification_option = - grpc_get_tsi_server_verification_option( - creds->options().server_verification_option()); + bool skip_server_certificate_verification = + creds->options().server_verification_option() == + GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION; /* Free the client handshaker factory if exists. */ if (client_handshaker_factory_) { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); @@ -297,7 +297,7 @@ grpc_security_status TlsChannelSecurityConnector::ReplaceHandshakerFactory( key_materials_config_->pem_key_cert_pair_list()); grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init( pem_key_cert_pair, key_materials_config_->pem_root_certs(), - server_verification_option, ssl_session_cache, + skip_server_certificate_verification, ssl_session_cache, &client_handshaker_factory_); /* Free memory. */ grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1); diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 2063ef0dfc9..2f85074ec89 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -1765,7 +1765,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory_with_options( tsi_ssl_handshaker_factory_unref(&impl->base); return result; } - if (options->server_verification_option == TSI_SKIP_ALL_SERVER_VERIFICATION) { + if (options->skip_server_certificate_verification) { SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NullVerifyCallback); } else { SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, nullptr); diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index 2ccd15088c9..ae1e413aad3 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -148,8 +148,8 @@ struct tsi_ssl_client_handshaker_options { /* ssl_session_cache is a cache for reusable client-side sessions. */ tsi_ssl_session_cache* session_cache; - /* Server verification option */ - tsi_server_verification_option server_verification_option; + /* skip server certificate verification. */ + bool skip_server_certificate_verification; tsi_ssl_client_handshaker_options() : pem_key_cert_pair(nullptr), @@ -159,7 +159,7 @@ struct tsi_ssl_client_handshaker_options { alpn_protocols(nullptr), num_alpn_protocols(0), session_cache(nullptr), - server_verification_option(TSI_SERVER_VERIFICATION) {} + skip_server_certificate_verification(false) {} }; /* Creates a client handshaker factory. diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index 6d597e4bdf7..7a0cdc3453a 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -55,17 +55,6 @@ typedef enum { TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY, } tsi_client_certificate_request_type; -typedef enum { - /** Default option: performs server certificate verification and hostname - verification */ - TSI_SERVER_VERIFICATION, - /** Performs server certificate verification, but skips hostname verification - */ - TSI_SKIP_HOSTNAME_VERIFICATION, - /** Skips both server certificate and hostname verification */ - TSI_SKIP_ALL_SERVER_VERIFICATION, -} tsi_server_verification_option; - const char* tsi_result_to_string(tsi_result result); /* --- tsi tracing --- */ From 017cbd4ebdb37344052a343bcac1173471f1145e Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 7 Jan 2020 14:00:41 -0800 Subject: [PATCH 31/31] Add linux-headers to alpine image --- src/php/docker/alpine/Dockerfile | 2 +- templates/src/php/docker/alpine/Dockerfile.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/docker/alpine/Dockerfile b/src/php/docker/alpine/Dockerfile index e5b977c4aa6..a71c2afeccf 100644 --- a/src/php/docker/alpine/Dockerfile +++ b/src/php/docker/alpine/Dockerfile @@ -14,7 +14,7 @@ FROM php:7.2-alpine3.9 -RUN apk add autoconf g++ make zlib-dev git bash wget +RUN apk add autoconf g++ make zlib-dev git bash wget linux-headers ARG MAKEFLAGS=-j8 diff --git a/templates/src/php/docker/alpine/Dockerfile.template b/templates/src/php/docker/alpine/Dockerfile.template index 493b320e831..10302b24e3b 100644 --- a/templates/src/php/docker/alpine/Dockerfile.template +++ b/templates/src/php/docker/alpine/Dockerfile.template @@ -16,7 +16,7 @@ FROM php:${settings.php_version.php_current_version()}-alpine3.9 - RUN apk add autoconf g++ make zlib-dev git bash wget + RUN apk add autoconf g++ make zlib-dev git bash wget linux-headers ARG MAKEFLAGS=-j8