14 """A setup module for the GRPC Python package."""
22 from distutils.unixccompiler
import UnixCCompiler
24 UnixCCompiler.src_extensions.append(
'.S')
27 from distutils
import cygwinccompiler
28 from distutils
import extension
as _extension
29 from distutils
import util
38 from subprocess
import PIPE
44 from setuptools.command
import egg_info
47 egg_info.manifest_maker.template =
'PYTHON-MANIFEST.in'
49 PY3 = sys.version_info.major == 3
50 PYTHON_STEM = os.path.join(
'src',
'python',
'grpcio')
55 ABSL_INCLUDE = (os.path.join(
'third_party',
'abseil-cpp'),)
56 ADDRESS_SORTING_INCLUDE = (os.path.join(
'third_party',
'address_sorting',
59 os.path.join(
'third_party',
'cares',
'cares',
'include'),
60 os.path.join(
'third_party',
'cares'),
61 os.path.join(
'third_party',
'cares',
'cares'),
63 if 'darwin' in sys.platform:
64 CARES_INCLUDE += (os.path.join(
'third_party',
'cares',
'config_darwin'),)
65 if 'freebsd' in sys.platform:
66 CARES_INCLUDE += (os.path.join(
'third_party',
'cares',
'config_freebsd'),)
67 if 'linux' in sys.platform:
68 CARES_INCLUDE += (os.path.join(
'third_party',
'cares',
'config_linux'),)
69 if 'openbsd' in sys.platform:
70 CARES_INCLUDE += (os.path.join(
'third_party',
'cares',
'config_openbsd'),)
71 RE2_INCLUDE = (os.path.join(
'third_party',
're2'),)
72 SSL_INCLUDE = (os.path.join(
'third_party',
'boringssl-with-bazel',
'src',
74 UPB_INCLUDE = (os.path.join(
'third_party',
'upb'),)
75 UPB_GRPC_GENERATED_INCLUDE = (os.path.join(
'src',
'core',
'ext',
77 UPBDEFS_GRPC_GENERATED_INCLUDE = (os.path.join(
'src',
'core',
'ext',
78 'upbdefs-generated'),)
79 XXHASH_INCLUDE = (os.path.join(
'third_party',
'xxhash'),)
80 ZLIB_INCLUDE = (os.path.join(
'third_party',
'zlib'),)
81 README = os.path.join(PYTHON_STEM,
'README.rst')
84 os.chdir(os.path.dirname(os.path.abspath(__file__)))
85 sys.path.insert(0, os.path.abspath(PYTHON_STEM))
88 import _parallel_compile_patch
90 import grpc_core_dependencies
98 LICENSE =
'Apache License 2.0'
101 'Development Status :: 5 - Production/Stable',
102 'Programming Language :: Python',
103 'Programming Language :: Python :: 3',
104 'Programming Language :: Python :: 3.5',
105 'Programming Language :: Python :: 3.6',
106 'Programming Language :: Python :: 3.7',
107 'Programming Language :: Python :: 3.8',
108 'Programming Language :: Python :: 3.9',
109 'Programming Language :: Python :: 3.10',
110 'License :: OSI Approved :: Apache Software License',
115 """Parses a bool option from an environment variable"""
116 return os.environ.get(env_name, default).upper()
not in [
'FALSE',
'0',
'']
127 BUILD_OVERRIDE_BORING_SSL_ASM_PLATFORM = os.environ.get(
128 'GRPC_BUILD_OVERRIDE_BORING_SSL_ASM_PLATFORM',
'')
163 BUILD_WITH_SYSTEM_ABSL = os.environ.get(
'GRPC_PYTHON_BUILD_SYSTEM_ABSL',
False)
173 'GRPC_PYTHON_BUILD_WITH_STATIC_LIBSTDCXX',
'False')
192 'GRPC_PYTHON_DISABLE_LIBC_COMPATIBILITY',
'False')
202 'GRPC_PYTHON_ENABLE_DOCUMENTATION_BUILD',
'False')
206 """Test if linker on system needs libatomic."""
207 code_test = (b
'#include <atomic>\n' +
208 b
'int main() { return std::atomic<int64_t>{}; }')
209 cxx = shlex.split(os.environ.get(
'CXX',
'c++'))
210 cpp_test = subprocess.Popen(cxx + [
'-x',
'c++',
'-std=c++14',
'-'],
214 cpp_test.communicate(input=code_test)
215 if cpp_test.returncode == 0:
219 cpp_test = subprocess.Popen(
220 [cxx,
'-x',
'c++',
'-std=c++14',
'-',
'-latomic'],
224 cpp_test.communicate(input=code_test)
225 return cpp_test.returncode == 0
235 EXTRA_ENV_COMPILE_ARGS = os.environ.get(
'GRPC_PYTHON_CFLAGS',
None)
236 EXTRA_ENV_LINK_ARGS = os.environ.get(
'GRPC_PYTHON_LDFLAGS',
None)
237 if EXTRA_ENV_COMPILE_ARGS
is None:
238 EXTRA_ENV_COMPILE_ARGS =
' -std=c++14'
239 if 'win32' in sys.platform:
240 if sys.version_info < (3, 5):
241 EXTRA_ENV_COMPILE_ARGS +=
' -D_hypot=hypot'
246 if '32' in platform.architecture()[0]:
247 EXTRA_ENV_COMPILE_ARGS +=
' -D_ftime=_ftime32 -D_timeb=__timeb32 -D_ftime_s=_ftime32_s'
249 EXTRA_ENV_COMPILE_ARGS +=
' -D_ftime=_ftime64 -D_timeb=__timeb64'
253 EXTRA_ENV_COMPILE_ARGS +=
' /MT'
254 elif "linux" in sys.platform:
255 EXTRA_ENV_COMPILE_ARGS +=
' -fvisibility=hidden -fno-wrapv -fno-exceptions'
256 elif "darwin" in sys.platform:
257 EXTRA_ENV_COMPILE_ARGS +=
' -stdlib=libc++ -fvisibility=hidden -fno-wrapv -fno-exceptions -DHAVE_UNISTD_H'
259 if EXTRA_ENV_LINK_ARGS
is None:
260 EXTRA_ENV_LINK_ARGS =
''
261 if "linux" in sys.platform
or "darwin" in sys.platform:
262 EXTRA_ENV_LINK_ARGS +=
' -lpthread'
264 EXTRA_ENV_LINK_ARGS +=
' -latomic'
265 elif "win32" in sys.platform
and sys.version_info < (3, 5):
266 msvcr = cygwinccompiler.get_msvcr()[0]
267 EXTRA_ENV_LINK_ARGS += (
268 ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr}'
269 ' -static -lshlwapi'.
format(msvcr=msvcr))
270 if "linux" in sys.platform:
271 EXTRA_ENV_LINK_ARGS +=
' -static-libgcc'
273 EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS)
274 EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS)
276 if BUILD_WITH_STATIC_LIBSTDCXX:
277 EXTRA_LINK_ARGS.append(
'-static-libstdc++')
279 CYTHON_EXTENSION_PACKAGE_NAMES = ()
281 CYTHON_EXTENSION_MODULE_NAMES = (
'grpc._cython.cygrpc',)
283 CYTHON_HELPER_C_FILES = ()
285 CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES)
286 if "win32" in sys.platform:
287 CORE_C_FILES = filter(
lambda x:
'third_party/cares' not in x, CORE_C_FILES)
289 if BUILD_WITH_SYSTEM_OPENSSL:
290 CORE_C_FILES = filter(
lambda x:
'third_party/boringssl' not in x,
292 CORE_C_FILES = filter(
lambda x:
'src/boringssl' not in x, CORE_C_FILES)
293 SSL_INCLUDE = (os.path.join(
'/usr',
'include',
'openssl'),)
295 if BUILD_WITH_SYSTEM_ZLIB:
296 CORE_C_FILES = filter(
lambda x:
'third_party/zlib' not in x, CORE_C_FILES)
297 ZLIB_INCLUDE = (os.path.join(
'/usr',
'include'),)
299 if BUILD_WITH_SYSTEM_CARES:
300 CORE_C_FILES = filter(
lambda x:
'third_party/cares' not in x, CORE_C_FILES)
301 CARES_INCLUDE = (os.path.join(
'/usr',
'include'),)
303 if BUILD_WITH_SYSTEM_RE2:
304 CORE_C_FILES = filter(
lambda x:
'third_party/re2' not in x, CORE_C_FILES)
305 RE2_INCLUDE = (os.path.join(
'/usr',
'include',
're2'),)
307 if BUILD_WITH_SYSTEM_ABSL:
308 CORE_C_FILES = filter(
lambda x:
'third_party/abseil-cpp' not in x,
310 ABSL_INCLUDE = (os.path.join(
'/usr',
'include'),)
312 EXTENSION_INCLUDE_DIRECTORIES = ((PYTHON_STEM,) + CORE_INCLUDE + ABSL_INCLUDE +
313 ADDRESS_SORTING_INCLUDE + CARES_INCLUDE +
314 RE2_INCLUDE + SSL_INCLUDE + UPB_INCLUDE +
315 UPB_GRPC_GENERATED_INCLUDE +
316 UPBDEFS_GRPC_GENERATED_INCLUDE +
317 XXHASH_INCLUDE + ZLIB_INCLUDE)
319 EXTENSION_LIBRARIES = ()
320 if "linux" in sys.platform:
321 EXTENSION_LIBRARIES += (
'rt',)
322 if not "win32" in sys.platform:
323 EXTENSION_LIBRARIES += (
'm',)
324 if "win32" in sys.platform:
325 EXTENSION_LIBRARIES += (
331 if BUILD_WITH_SYSTEM_OPENSSL:
332 EXTENSION_LIBRARIES += (
336 if BUILD_WITH_SYSTEM_ZLIB:
337 EXTENSION_LIBRARIES += (
'z',)
338 if BUILD_WITH_SYSTEM_CARES:
339 EXTENSION_LIBRARIES += (
'cares',)
340 if BUILD_WITH_SYSTEM_RE2:
341 EXTENSION_LIBRARIES += (
're2',)
342 if BUILD_WITH_SYSTEM_ABSL:
343 EXTENSION_LIBRARIES += tuple(
344 lib.stem[3:]
for lib
in pathlib.Path(
'/usr').glob(
'lib*/libabsl_*.so'))
346 DEFINE_MACROS = ((
'_WIN32_WINNT', 0x600),)
354 if "win32" in sys.platform:
355 return '"\\\"{}\\\""'.
format(argument)
356 return '"{}"'.
format(argument)
361 (
"GRPC_XDS_USER_AGENT_VERSION_SUFFIX",
366 if BUILD_WITH_BORING_SSL_ASM
and not BUILD_WITH_SYSTEM_OPENSSL:
367 boringssl_asm_platform = BUILD_OVERRIDE_BORING_SSL_ASM_PLATFORM
if BUILD_OVERRIDE_BORING_SSL_ASM_PLATFORM
else util.get_platform(
369 LINUX_X86_64 =
'linux-x86_64'
370 LINUX_ARM =
'linux-arm'
371 LINUX_AARCH64 =
'linux-aarch64'
372 if LINUX_X86_64 == boringssl_asm_platform:
373 asm_key =
'crypto_linux_x86_64'
374 elif LINUX_ARM == boringssl_asm_platform:
375 asm_key =
'crypto_linux_arm'
376 elif LINUX_AARCH64 == boringssl_asm_platform:
377 asm_key =
'crypto_linux_aarch64'
378 elif "mac" in boringssl_asm_platform
and "x86_64" in boringssl_asm_platform:
379 asm_key =
'crypto_mac_x86_64'
381 print(
"ASM Builds for BoringSSL currently not supported on:",
382 boringssl_asm_platform)
384 asm_files = grpc_core_dependencies.ASM_SOURCE_FILES[asm_key]
386 DEFINE_MACROS += ((
'OPENSSL_NO_ASM', 1),)
388 if not DISABLE_LIBC_COMPATIBILITY:
389 DEFINE_MACROS += ((
'GPR_BACKWARDS_COMPATIBILITY_MODE', 1),)
391 if "win32" in sys.platform:
395 (
'WIN32_LEAN_AND_MEAN', 1),
396 (
'CARES_STATICLIB', 1),
398 (
'NTDDI_VERSION', 0x06000000),
401 if '64bit' in platform.architecture()[0]:
402 DEFINE_MACROS += ((
'MS_WIN64', 1),)
403 elif sys.version_info >= (3, 5):
406 DEFINE_MACROS += ((
'NTDDI_VERSION', 0x06000000),)
409 (
'HAVE_CONFIG_H', 1),
410 (
'GRPC_ENABLE_FORK_SUPPORT', 1),
413 LDFLAGS = tuple(EXTRA_LINK_ARGS)
414 CFLAGS = tuple(EXTRA_COMPILE_ARGS)
415 if "linux" in sys.platform
or "darwin" in sys.platform:
416 pymodinit_type =
'PyObject*' if PY3
else 'void'
417 pymodinit =
'extern "C" __attribute__((visibility ("default"))) {}'.
format(
419 DEFINE_MACROS += ((
'PyMODINIT_FUNC', pymodinit),)
420 DEFINE_MACROS += ((
'GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK', 1),)
426 if 'darwin' in sys.platform:
427 mac_target = sysconfig.get_config_var(
'MACOSX_DEPLOYMENT_TARGET')
429 mac_target = pkg_resources.parse_version(
str(mac_target))
430 if mac_target < pkg_resources.parse_version(
'10.10.0'):
431 os.environ[
'MACOSX_DEPLOYMENT_TARGET'] =
'10.10'
432 os.environ[
'_PYTHON_HOST_PLATFORM'] = re.sub(
433 r'macosx-[0-9]+\.[0-9]+-(.+)',
r'macosx-10.10-\1',
438 cython_module_files = [
439 os.path.join(PYTHON_STEM,
440 name.replace(
'.',
'/') +
'.pyx')
441 for name
in CYTHON_EXTENSION_MODULE_NAMES
443 config = os.environ.get(
'CONFIG',
'opt')
444 prefix =
'libs/' + config +
'/'
445 if USE_PREBUILT_GRPC_CORE:
447 prefix +
'libares.a', prefix +
'libboringssl.a',
448 prefix +
'libgpr.a', prefix +
'libgrpc.a'
452 core_c_files = list(CORE_C_FILES)
455 _extension.Extension(
457 sources=([module_file] + list(CYTHON_HELPER_C_FILES) +
458 core_c_files + asm_files),
459 include_dirs=list(EXTENSION_INCLUDE_DIRECTORIES),
460 libraries=list(EXTENSION_LIBRARIES),
461 define_macros=list(DEFINE_MACROS),
462 extra_objects=extra_objects,
463 extra_compile_args=list(CFLAGS),
464 extra_link_args=list(LDFLAGS),
465 )
for (module_name, module_file
466 )
in zip(list(CYTHON_EXTENSION_MODULE_NAMES), cython_module_files)
468 need_cython = BUILD_WITH_CYTHON
469 if not BUILD_WITH_CYTHON:
475 linetracing=ENABLE_CYTHON_TRACING,
476 mandatory=BUILD_WITH_CYTHON), need_cython
481 PACKAGE_DIRECTORIES = {
487 "futures>=2.2.0; python_version<'3.2'",
488 "enum34>=1.0.4; python_version<'3.4'",
491 'protobuf':
'grpcio-tools>={version}'.
format(version=grpc_version.VERSION),
494 SETUP_REQUIRES = INSTALL_REQUIRES + (
497 )
if ENABLE_DOCUMENTATION_BUILD
else ()
502 if BUILD_WITH_CYTHON:
504 "You requested a Cython build via GRPC_PYTHON_BUILD_WITH_CYTHON, "
505 "but do not have Cython installed. We won't stop you from using "
506 "other commands, but the extension files will fail to build.\n")
509 'We could not find Cython. Setup may take 10-20 minutes.\n')
510 SETUP_REQUIRES += (
'cython>=0.23',)
522 credentials_dir = os.path.join(PYTHON_STEM,
'grpc',
'_cython',
'_credentials')
524 os.mkdir(credentials_dir)
527 shutil.copyfile(os.path.join(
'etc',
'roots.pem'),
528 os.path.join(credentials_dir,
'roots.pem'))
534 '_credentials/roots.pem',
535 '_windows/grpc_c.32.python',
536 '_windows/grpc_c.64.python',
539 PACKAGES = setuptools.find_packages(PYTHON_STEM)
543 version=grpc_version.VERSION,
544 description=
'HTTP/2-based RPC framework',
545 author=
'The gRPC Authors',
546 author_email=
'grpc-io@googlegroups.com',
547 url=
'https://grpc.io',
549 classifiers=CLASSIFIERS,
551 ext_modules=CYTHON_EXTENSION_MODULES,
552 packages=list(PACKAGES),
553 package_dir=PACKAGE_DIRECTORIES,
554 package_data=PACKAGE_DATA,
555 python_requires=
'>=3.6',
556 install_requires=INSTALL_REQUIRES,
557 extras_require=EXTRAS_REQUIRES,
558 setup_requires=SETUP_REQUIRES,
559 cmdclass=COMMAND_CLASS,