Blame view

setup.py 9.86 KB
Martin Quarda committed
1
#!/usr/bin/env python
Guy Rozendorn committed
2 3 4 5
try:
    from setuptools import setup, Extension
except ImportError:
    from distutils.core import setup, Extension
Stefan Behnel committed
6
import os
Robert Bradshaw committed
7
import stat
Robert Bradshaw committed
8
import subprocess
Stefan Behnel committed
9
import textwrap
Robert Bradshaw committed
10
import sys
William Stein committed
11

Lars Buitinck committed
12 13
import platform
is_cpython = platform.python_implementation() == 'CPython'
Stefan Behnel committed
14

James Tocknell committed
15 16 17 18
# this specifies which versions of python we support, pip >= 9 knows to skip
# versions of packages which are not compatible with the running python
PYTHON_REQUIRES = '>=2.6, !=3.0.*, !=3.1.*, !=3.2.*'

Robert Bradshaw committed
19 20 21 22 23
if sys.platform == "darwin":
    # Don't create resource files on OS X tar.
    os.environ['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true'
    os.environ['COPYFILE_DISABLE'] = 'true'

Stefan Behnel committed
24 25
setup_args = {}

Stefan Behnel committed
26 27 28 29 30
def add_command_class(name, cls):
    cmdclasses = setup_args.get('cmdclass', {})
    cmdclasses[name] = cls
    setup_args['cmdclass'] = cmdclasses

Lisandro Dalcin committed
31 32 33
from distutils.command.sdist import sdist as sdist_orig
class sdist(sdist_orig):
    def run(self):
Lisandro Dalcin committed
34
        self.force_manifest = 1
Robert Bradshaw committed
35
        if (sys.platform != "win32" and
Lisandro Dalcin committed
36
            os.path.isdir('.git')):
Yaroslav Halchenko committed
37
            assert os.system("git rev-parse --verify HEAD > .gitrev") == 0
Lisandro Dalcin committed
38 39 40
        sdist_orig.run(self)
add_command_class('sdist', sdist)

Stefan Behnel committed
41
pxd_include_dirs = [
Christoph Gohlke committed
42 43
    directory for directory, dirs, files
    in os.walk(os.path.join('Cython', 'Includes'))
Stefan Behnel committed
44
    if '__init__.pyx' in files or '__init__.pxd' in files
Christoph Gohlke committed
45 46
    or directory == os.path.join('Cython', 'Includes')
    or directory == os.path.join('Cython', 'Includes', 'Deprecated')]
Stefan Behnel committed
47 48 49 50

pxd_include_patterns = [
    p+'/*.pxd' for p in pxd_include_dirs ] + [
    p+'/*.pyx' for p in pxd_include_dirs ]
Stefan Behnel committed
51

Stefan Behnel committed
52 53 54 55 56 57
setup_args['package_data'] = {
    'Cython.Plex'     : ['*.pxd'],
    'Cython.Compiler' : ['*.pxd'],
    'Cython.Runtime'  : ['*.pyx', '*.pxd'],
    'Cython.Utility'  : ['*.pyx', '*.pxd', '*.c', '*.h', '*.cpp'],
    'Cython'          : [ p[7:] for p in pxd_include_patterns ],
Stefan Behnel committed
58 59
    'Cython.Debugger.Tests': ['codefile', 'cfuncs.c'],
}
William Stein committed
60

Robert Bradshaw committed
61
# This dict is used for passing extra arguments that are setuptools
David Cournapeau committed
62 63 64 65
# specific to setup
setuptools_extra_args = {}

if 'setuptools' in sys.modules:
James Tocknell committed
66
    setuptools_extra_args['python_requires'] = PYTHON_REQUIRES
David Cournapeau committed
67 68 69 70
    setuptools_extra_args['zip_safe'] = False
    setuptools_extra_args['entry_points'] = {
        'console_scripts': [
            'cython = Cython.Compiler.Main:setuptools_main',
Robert Bradshaw committed
71 72
            'cythonize = Cython.Build.Cythonize:main',
            'cygdb = Cython.Debugger.Cygdb:main',
David Cournapeau committed
73 74 75
        ]
    }
    scripts = []
William Stein committed
76
else:
David Cournapeau committed
77
    if os.name == "posix":
Robert Bradshaw committed
78
        scripts = ["bin/cython", "bin/cythonize", "bin/cygdb"]
David Cournapeau committed
79
    else:
Robert Bradshaw committed
80
        scripts = ["cython.py", "cythonize.py", "cygdb.py"]
Mark Florisson committed
81

David Cournapeau committed
82

Stefan Behnel committed
83
def compile_cython_modules(profile=False, compile_more=False, cython_with_refnanny=False):
Stefan Behnel committed
84
    source_root = os.path.abspath(os.path.dirname(__file__))
Stefan Behnel committed
85 86 87 88 89 90 91
    compiled_modules = [
        "Cython.Plex.Scanners",
        "Cython.Plex.Actions",
        "Cython.Compiler.Scanning",
        "Cython.Compiler.Visitor",
        "Cython.Compiler.FlowControl",
        "Cython.Runtime.refnanny",
Stefan Behnel committed
92
        "Cython.Compiler.FusedNode",
Stefan Behnel committed
93 94
        "Cython.Tempita._tempita",
    ]
Stefan Behnel committed
95 96
    if compile_more:
        compiled_modules.extend([
Stefan Behnel committed
97 98 99
            "Cython.StringIOTree",
            "Cython.Compiler.Code",
            "Cython.Compiler.Lexicon",
Stefan Behnel committed
100
            "Cython.Compiler.Parsing",
Stefan Behnel committed
101
            "Cython.Compiler.Pythran",
Robert Bradshaw committed
102
            "Cython.Build.Dependencies",
Stefan Behnel committed
103 104 105 106 107 108
            "Cython.Compiler.ParseTreeTransforms",
            "Cython.Compiler.Nodes",
            "Cython.Compiler.ExprNodes",
            "Cython.Compiler.ModuleNode",
            "Cython.Compiler.Optimize",
            ])
William Stein committed
109

Robert Bradshaw committed
110 111 112 113 114
    from distutils.spawn import find_executable
    from distutils.sysconfig import get_python_inc
    pgen = find_executable(
        'pgen', os.pathsep.join([os.environ['PATH'], os.path.join(get_python_inc(), '..', 'Parser')]))
    if not pgen:
Erik Bray committed
115
        sys.stderr.write("Unable to find pgen, not compiling formal grammar.\n")
Robert Bradshaw committed
116 117
    else:
        parser_dir = os.path.join(os.path.dirname(__file__), 'Cython', 'Parser')
Robert Bradshaw committed
118
        grammar = os.path.join(parser_dir, 'Grammar')
Robert Bradshaw committed
119 120
        subprocess.check_call([
            pgen,
Robert Bradshaw committed
121
            os.path.join(grammar),
Robert Bradshaw committed
122 123 124
            os.path.join(parser_dir, 'graminit.h'),
            os.path.join(parser_dir, 'graminit.c'),
            ])
Robert Bradshaw committed
125 126 127 128
        cst_pyx = os.path.join(parser_dir, 'ConcreteSyntaxTree.pyx')
        if os.stat(grammar)[stat.ST_MTIME] > os.stat(cst_pyx)[stat.ST_MTIME]:
            mtime = os.stat(grammar)[stat.ST_MTIME]
            os.utime(cst_pyx, (mtime, mtime))
Robert Bradshaw committed
129 130 131 132
        compiled_modules.extend([
                "Cython.Parser.ConcreteSyntaxTree",
            ])

Stefan Behnel committed
133 134 135
    defines = []
    if cython_with_refnanny:
        defines.append(('CYTHON_REFNANNY', '1'))
William Stein committed
136

Stefan Behnel committed
137
    extensions = []
Lisandro Dalcin committed
138 139 140 141 142 143 144 145 146 147 148 149 150
    for module in compiled_modules:
        source_file = os.path.join(source_root, *module.split('.'))
        if os.path.exists(source_file + ".py"):
            pyx_source_file = source_file + ".py"
        else:
            pyx_source_file = source_file + ".pyx"
        dep_files = []
        if os.path.exists(source_file + '.pxd'):
            dep_files.append(source_file + '.pxd')
        if '.refnanny' in module:
            defines_for_module = []
        else:
            defines_for_module = defines
Stefan Behnel committed
151 152 153 154 155
        extensions.append(Extension(
            module, sources=[pyx_source_file],
            define_macros=defines_for_module,
            depends=dep_files))
        # XXX hack around setuptools quirk for '*.pyx' sources
Lisandro Dalcin committed
156 157
        extensions[-1].sources[0] = pyx_source_file

Stefan Behnel committed
158
    from Cython.Distutils.build_ext import new_build_ext
Stefan Behnel committed
159 160
    from Cython.Compiler.Options import get_directive_defaults
    get_directive_defaults()['language_level'] = 2
Stefan Behnel committed
161 162 163
    if profile:
        get_directive_defaults()['profile'] = True
        sys.stderr.write("Enabled profiling for the Cython binary modules\n")
Stefan Behnel committed
164

Stefan Behnel committed
165 166
    # not using cythonize() directly to let distutils decide whether building extensions was requested
    add_command_class("build_ext", new_build_ext)
Stefan Behnel committed
167 168 169
    setup_args['ext_modules'] = extensions


Stefan Behnel committed
170 171 172 173
cython_profile = '--cython-profile' in sys.argv
if cython_profile:
    sys.argv.remove('--cython-profile')

Stefan Behnel committed
174 175 176 177 178 179
try:
    sys.argv.remove("--cython-compile-all")
    cython_compile_more = True
except ValueError:
    cython_compile_more = False

Stefan Behnel committed
180 181 182 183 184 185
try:
    sys.argv.remove("--cython-with-refnanny")
    cython_with_refnanny = True
except ValueError:
    cython_with_refnanny = False

Stefan Behnel committed
186 187
try:
    sys.argv.remove("--no-cython-compile")
Stefan Behnel committed
188
    compile_cython_itself = False
Stefan Behnel committed
189
except ValueError:
Stefan Behnel committed
190 191
    compile_cython_itself = True

Stefan Behnel committed
192
if compile_cython_itself and (is_cpython or cython_compile_more):
Stefan Behnel committed
193
    compile_cython_modules(cython_profile, cython_compile_more, cython_with_refnanny)
Stefan Behnel committed
194

David Cournapeau committed
195
setup_args.update(setuptools_extra_args)
Stefan Behnel committed
196

Stefan Behnel committed
197
from Cython import __version__ as version
Stefan Behnel committed
198

Stefan Behnel committed
199 200 201 202 203 204 205 206 207 208 209 210

def dev_status():
    if 'b' in version or 'c' in version:
        # 1b1, 1beta1, 2rc1, ...
        return 'Development Status :: 4 - Beta'
    elif 'a' in version:
        # 1a1, 1alpha1, ...
        return 'Development Status :: 3 - Alpha'
    else:
        return 'Development Status :: 5 - Production/Stable'


Mark Florisson committed
211 212 213 214 215 216
packages = [
    'Cython',
    'Cython.Build',
    'Cython.Compiler',
    'Cython.Runtime',
    'Cython.Distutils',
Stefan Behnel committed
217 218
    'Cython.Debugger',
    'Cython.Debugger.Tests',
Mark Florisson committed
219 220
    'Cython.Plex',
    'Cython.Tests',
Robert Bradshaw committed
221
    'Cython.Build.Tests',
Mark Florisson committed
222
    'Cython.Compiler.Tests',
Mark Florisson committed
223
    'Cython.Utility',
Mark Florisson committed
224
    'Cython.Tempita',
Stefan Behnel committed
225
    'pyximport',
Mark Florisson committed
226 227
]

William Stein committed
228
setup(
Stefan Behnel committed
229 230
    name='Cython',
    version=version,
Stefan Behnel committed
231
    url='http://cython.org/',
Stefan Behnel committed
232 233 234 235 236 237 238 239
    author='Robert Bradshaw, Stefan Behnel, Dag Seljebotn, Greg Ewing, et al.',
    author_email='cython-devel@python.org',
    description="The Cython compiler for writing C extensions for the Python language.",
    long_description=textwrap.dedent("""\
    The Cython language makes writing C extensions for the Python language as
    easy as Python itself.  Cython is a source code translator based on Pyrex_,
    but supports more cutting edge functionality and optimizations.

Stefan Behnel committed
240 241 242 243 244
    The Cython language is a superset of the Python language (almost all Python
    code is also valid Cython code), but Cython additionally supports optional
    static typing to natively call C functions, operate with C++ classes and
    declare fast C types on variables and class attributes.  This allows the
    compiler to generate very efficient C code from Cython code.
Stefan Behnel committed
245

Stefan Behnel committed
246 247 248
    This makes Cython the ideal language for writing glue code for external
    C/C++ libraries, and for fast C modules that speed up the execution of
    Python code.
Stefan Behnel committed
249

Stefan Behnel committed
250 251 252
    Note that for one-time builds, e.g. for CI/testing, on platforms that are not
    covered by one of the wheel packages provided on PyPI, it is substantially faster
    than a full source build to install an uncompiled (slower) version of Cython with::
Stefan Behnel committed
253 254 255

        pip install Cython --install-option="--no-cython-compile"

Stefan Behnel committed
256 257
    .. _Pyrex: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
    """),
Ioannis Filippidis committed
258
    license='Apache',
Stefan Behnel committed
259
    classifiers=[
Stefan Behnel committed
260
        dev_status(),
Stefan Behnel committed
261 262 263 264 265
        "Intended Audience :: Developers",
        "License :: OSI Approved :: Apache Software License",
        "Operating System :: OS Independent",
        "Programming Language :: Python",
        "Programming Language :: Python :: 2",
Hugo committed
266 267
        "Programming Language :: Python :: 2.6",
        "Programming Language :: Python :: 2.7",
Stefan Behnel committed
268
        "Programming Language :: Python :: 3",
Hugo committed
269 270 271
        "Programming Language :: Python :: 3.4",
        "Programming Language :: Python :: 3.5",
        "Programming Language :: Python :: 3.6",
Stefan Behnel committed
272
        "Programming Language :: Python :: 3.7",
Hugo committed
273 274
        "Programming Language :: Python :: Implementation :: CPython",
        "Programming Language :: Python :: Implementation :: PyPy",
Stefan Behnel committed
275 276 277 278 279 280 281 282 283 284 285 286
        "Programming Language :: C",
        "Programming Language :: Cython",
        "Topic :: Software Development :: Code Generators",
        "Topic :: Software Development :: Compilers",
        "Topic :: Software Development :: Libraries :: Python Modules"
    ],

    scripts=scripts,
    packages=packages,
    py_modules=["cython"],
    **setup_args
)