sources for buildcmodule.py [rev. 38799]
1
2
3
4
5
6
7
8
9
10
11
12
13
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
80
81
82
83
84
85
"""
A utility to build a Python extension module from C, wrapping distutils.
"""
import py
#  XXX we should distutils in a subprocess, because it messes up the
#      environment and who knows what else.  Currently we just save
#      and restore os.environ.
def make_module_from_c(cfile):
    import os, sys, imp
    from distutils.core import setup
    from distutils.extension import Extension
    debug = 0
    #try:
    #    from distutils.log import set_threshold
    #    set_threshold(10000)
    #except ImportError:
    #    print "ERROR IMPORTING"
    #    pass
    dirpath = cfile.dirpath()
    modname = cfile.purebasename
    # find the expected extension of the compiled C module
    for ext, mode, filetype in imp.get_suffixes():
        if filetype == imp.C_EXTENSION:
            break
    else:
        raise ImportError, "cannot find the file name suffix of C ext modules"
    lib = dirpath.join(modname+ext)
    # XXX argl! we need better "build"-locations alltogether!
    if lib.check():
        try:
            lib.remove()
        except EnvironmentError:
            pass # XXX we just use the existing version, bah
    if not lib.check():
        c = py.io.StdCaptureFD()
        try:
            try:
                saved_environ = os.environ.items()
                try:
                    lastdir = dirpath.chdir()
                    try:
                        setup(
                          name = "pylibmodules",
                          ext_modules=[
                                Extension(modname, [str(cfile)])
                          ],
                          script_name = 'setup.py',
                          script_args = ['-q', 'build_ext', '--inplace']
                          #script_args = ['build_ext', '--inplace']
                        )
                    finally:
                        lastdir.chdir()
                finally:
                    for key, value in saved_environ:
                        if os.environ.get(key) != value:
                            os.environ[key] = value
            finally:
                foutput, foutput = c.done()
        except KeyboardInterrupt:
            raise
        except SystemExit, e:
            raise RuntimeError("cannot compile %s: %s\n%s" % (cfile, e,
                                                          foutput.read()))
    # XXX do we need to do some check on fout/ferr?
    # XXX not a nice way to import a module
    if debug:
        print "inserting path to sys.path", dirpath
    sys.path.insert(0, str(dirpath))
    if debug:
        print "import %(modname)s as testmodule" % locals()
    exec py.code.compile("import %(modname)s as testmodule" % locals())
    try:
        sys.path.remove(str(dirpath))
    except ValueError:
        pass
    return testmodule