pyxbuild.py 2.09 KB
Newer Older
1 2 3 4 5
"""Build a Pyrex file from .pyx source to .so loadable module using
the installed distutils infrastructure. Call:

out_fname = pyx_to_dll("foo.pyx")
"""
Stefan Behnel's avatar
Stefan Behnel committed
6
import os
7 8 9 10 11 12

import distutils
from distutils.dist import Distribution
from distutils.errors import DistutilsArgError, DistutilsError, CCompilerError
from distutils.extension import Extension
from distutils.util import grok_environment_error
13
from Cython.Distutils import build_ext
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
import shutil

DEBUG = 0
def pyx_to_dll(filename, ext = None, force_rebuild = 0):
    """Compile a PYX file to a DLL and return the name of the generated .so 
       or .dll ."""
    assert os.path.exists(filename)

    path, name = os.path.split(filename)

    if not ext:
        modname, extension = os.path.splitext(name)
	assert extension == ".pyx", extension
        ext = Extension(name=modname, sources=[filename])

    if DEBUG:
        quiet = "--verbose"
    else:
	quiet = "--quiet"
    args = [quiet, "build_ext"]
    if force_rebuild:
        args.append("--force")
    dist = Distribution({"script_name": None, "script_args": args})
    if not dist.ext_modules:
        dist.ext_modules = []
    dist.ext_modules.append(ext)
    dist.cmdclass = {'build_ext': build_ext}
    build = dist.get_command_obj('build')
    build.build_base = os.path.join(path, "_pyxbld")

    try:
        ok = dist.parse_command_line()
    except DistutilsArgError, msg:
        raise

    if DEBUG:
        print "options (after parsing command line):"
        dist.dump_option_dicts()
    assert ok


    try:
        dist.run_commands()
        return dist.get_command_obj("build_ext").get_outputs()[0]
    except KeyboardInterrupt:
        raise SystemExit, "interrupted"
    except (IOError, os.error), exc:
        error = grok_environment_error(exc)

        if DEBUG:
            sys.stderr.write(error + "\n")
            raise
        else:
            raise SystemExit, error

    except (DistutilsError,
        CCompilerError), msg:
        if DEBUG:
            raise
        else:
            raise SystemExit, "error: " + str(msg)

if __name__=="__main__":
    pyx_to_dll("dummy.pyx")
    import test