diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index 164088bf7bf..91c3541160b 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -118,6 +118,23 @@ if EXTRA_ENV_COMPILE_ARGS is None: EXTRA_ENV_COMPILE_ARGS += ' -fno-wrapv -frtti' if EXTRA_ENV_LINK_ARGS is None: EXTRA_ENV_LINK_ARGS = '' + # NOTE(rbellevi): Clang on Mac OS will make all static symbols (both variables + # and objects) global weak symbols. When a process loads the + # protobuf wheel's shared object library before loading *this* C extension, + # the runtime linker will prefer the protobuf module's version of symbols. This + # results in the process using a mixture of symbols from the protobuf wheel and + # this wheel, which may be using different versions of libprotobuf. In the case + # that they *are* using different versions of libprotobuf *and* there has been a + # change in data layout (or in other invariants) segfaults, data corruption, or + # "bad things" may happen. + # + # This flag ensures that on Mac, the only global symbol is the one loaded by the + # Python interpreter. The problematic global weak symbols become local weak symbols. + # This is not required on Linux since the compiler does not produce global weak + # symbols. This is not required on Windows as our ".pyd" file does not contain any + # symbols. + if "darwin" in sys.platform: + EXTRA_ENV_LINK_ARGS += ' -Wl,-exported_symbol,_PyInit__protoc_compiler' if "linux" in sys.platform or "darwin" in sys.platform: EXTRA_ENV_LINK_ARGS += ' -lpthread' if check_linker_need_libatomic():