#! /usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
import os
import glob
import platform
# distutils is deprecated and vendored into setuptools now.
from setuptools import setup
from setuptools import Extension
from setuptools import find_packages
# Extra compiler arguments passed to *all* extensions.
global_compile_args = []
# Extra compiler arguments passed to C++ extensions
cpp_compile_args = []
# Extra linker arguments passed to C++ extensions
cpp_link_args = []
# Extra compiler arguments passed to the main extension
main_compile_args = []
is_win = sys.platform.startswith("win")
# workaround segfaults on openbsd and RHEL 3 / CentOS 3 . see
# https://bitbucket.org/ambroff/greenlet/issue/11/segfault-on-openbsd-i386
# https://github.com/python-greenlet/greenlet/issues/4
# https://github.com/python-greenlet/greenlet/issues/94
# pylint:disable=too-many-boolean-expressions
is_linux = sys.platform.startswith('linux') # could be linux or linux2
plat_platform = platform.platform()
plat_machine = platform.machine()
plat_compiler = platform.python_compiler()
try:
# (sysname, nodename, release, version, machine)
unam_machine = os.uname()[-1]
except AttributeError:
unam_machine = ''
if (
(sys.platform == "openbsd4" and unam_machine == "i386")
or ("-with-redhat-3." in plat_platform and plat_machine == 'i686')
or (sys.platform == "sunos5" and unam_machine == "sun4v") # SysV-based Solaris
or ("SunOS" in plat_platform and plat_machine == "sun4v") # Old BSD-based SunOS
or (is_linux and plat_machine == "ppc")
# https://github.com/python-greenlet/greenlet/pull/300: When compiling for RISC-V the command
# ``riscv64-linux-gnu-gcc -pthread -fno-strict-aliasing -Wdate-time \
# -D_FORTIFY_SOURCE=2 -g -ffile-prefix-map=/build/python2.7-7GU7VT/python2.7-2.7.18=. \
# -fstack-protector-strong -Wformat -Werror=format-security -fPIC \
# -I/usr/include/python2.7
# -c src/greenlet/greenlet.cpp -o build/temp.linux-riscv64-2.7/src/greenlet/greenlet.o``
#
# fails with:
#
# src/greenlet/platform/switch_riscv_unix.h:30:1: error: s0 cannot be used in 'asm' here
#
# Adding the -Os flag fixes the problem.
or (is_linux and plat_machine == "riscv64")
):
global_compile_args.append("-Os")
if sys.platform == 'darwin' or 'clang' in plat_compiler:
# The clang compiler doesn't use --std=c++11 by default
cpp_compile_args.append("--std=c++11")
elif is_win and "MSC" in plat_compiler:
# Older versions of MSVC (Python 2.7) don't handle C++ exceptions
# correctly by default. While newer versions do handle exceptions
# by default, they don't do it fully correctly ("By default....the
# compiler generates code that only partially supports C++
# exceptions."). So we need an argument on all versions.
#"/EH" == exception handling.
# "s" == standard C++,
# "c" == extern C functions don't throw
# OR
# "a" == standard C++, and Windows SEH; anything may throw, compiler optimizations
# around try blocks are less aggressive. Because this catches SEH,
# which Windows uses internally, the MS docs say this can be a security issue.
# DO NOT USE.
# /EHsc is suggested, and /EHa isn't supposed to be linked to other things not built
# with it. Leaving off the "c" should just result in slower, safer code.
# Other options:
# "r" == Always generate standard confirming checks for noexcept blocks, terminating
# if violated. IMPORTANT: We rely on this.
# See https://docs.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=msvc-170
handler = "/EHsr"
cpp_compile_args.append(handler)
# To disable most optimizations:
#cpp_compile_args.append('/Od')
# To enable assertions:
#cpp_compile_args.append('/UNDEBUG')
# To enable more compile-time warnings (/Wall produces a mountain of output).
#cpp_compile_args.append('/W4')
# To link with the debug C runtime...except we can't because we need
# the Python debug lib too, and they're not around by default
# cpp_compile_args.append('/MDd')
# Support fiber-safe thread-local storage: "the compiler mustn't
# cache the address of the TLS array, or optimize it as a common
# subexpression across a function call." This would probably solve
# some of the issues we had with MSVC caching the thread local
# variables on the stack, leading to having to split some
# functions up. Revisit those.
cpp_compile_args.append("/GT")
# MSVC won't handle named struct initializers with its default
# standard. It complains about them instead and tells us to add
# this:
cpp_compile_args.append('/std:c++20')
def readfile(filename):
with open(filename, 'r') as f: # pylint:disable=unspecified-encoding
return f.read()
GREENLET_SRC_DIR = 'src/greenlet/'
GREENLET_HEADER_DIR = GREENLET_SRC_DIR
GREENLET_HEADER = GREENLET_HEADER_DIR + 'greenlet.h'
GREENLET_TEST_DIR = 'src/greenlet/tests/'
# The location of the platform specific assembly files
# for switching.
GREENLET_PLATFORM_DIR = GREENLET_SRC_DIR + 'platform/'
def _find_platform_headers():
return glob.glob(GREENLET_PLATFORM_DIR + "switch_*.h")
def _find_impl_headers():
return glob.glob(GREENLET_SRC_DIR + "*.hpp") + glob.glob(GREENLET_SRC_DIR + "*.cpp")
if hasattr(sys, "pypy_version_info"):
ext_modules = []
headers = []
else:
headers = [GREENLET_HEADER]
if is_win and '64 bit' in sys.version:
# this works when building with msvc, not with 64 bit gcc
# switch_