pyximport for compiling .pyx files on import
[cython.git] / pyximport / pyxbuild.py
1 """Build a Pyrex file from .pyx source to .so loadable module using
2 the installed distutils infrastructure. Call:
3
4 out_fname = pyx_to_dll("foo.pyx")
5 """
6 import os, md5
7
8 import distutils
9 from distutils.dist import Distribution
10 from distutils.errors import DistutilsArgError, DistutilsError, CCompilerError
11 from distutils.extension import Extension
12 from distutils.util import grok_environment_error
13 from Pyrex.Distutils import build_ext
14 import shutil
15
16 DEBUG = 0
17 def pyx_to_dll(filename, ext = None, force_rebuild = 0):
18     """Compile a PYX file to a DLL and return the name of the generated .so 
19        or .dll ."""
20     assert os.path.exists(filename)
21
22     path, name = os.path.split(filename)
23
24     if not ext:
25         modname, extension = os.path.splitext(name)
26         assert extension == ".pyx", extension
27         ext = Extension(name=modname, sources=[filename])
28
29     if DEBUG:
30         quiet = "--verbose"
31     else:
32         quiet = "--quiet"
33     args = [quiet, "build_ext"]
34     if force_rebuild:
35         args.append("--force")
36     dist = Distribution({"script_name": None, "script_args": args})
37     if not dist.ext_modules:
38         dist.ext_modules = []
39     dist.ext_modules.append(ext)
40     dist.cmdclass = {'build_ext': build_ext}
41     build = dist.get_command_obj('build')
42     build.build_base = os.path.join(path, "_pyxbld")
43
44     try:
45         ok = dist.parse_command_line()
46     except DistutilsArgError, msg:
47         raise
48
49     if DEBUG:
50         print "options (after parsing command line):"
51         dist.dump_option_dicts()
52     assert ok
53
54
55     try:
56         dist.run_commands()
57         return dist.get_command_obj("build_ext").get_outputs()[0]
58     except KeyboardInterrupt:
59         raise SystemExit, "interrupted"
60     except (IOError, os.error), exc:
61         error = grok_environment_error(exc)
62
63         if DEBUG:
64             sys.stderr.write(error + "\n")
65             raise
66         else:
67             raise SystemExit, error
68
69     except (DistutilsError,
70         CCompilerError), msg:
71         if DEBUG:
72             raise
73         else:
74             raise SystemExit, "error: " + str(msg)
75
76 if __name__=="__main__":
77     pyx_to_dll("dummy.pyx")
78     import test
79