82 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Python
		
	
	
	
| """
 | |
| 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
 | |
|     import stdoutcapture
 | |
|     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 ValueError, "cannot find the file name suffix of C ext modules"
 | |
|     lib = dirpath.join(modname+ext)
 | |
| 
 | |
|     # argl! we need better "build"-locations alltogether!
 | |
|     if lib.check():
 | |
|         lib.remove()
 | |
| 
 | |
|     c = stdoutcapture.Capture(mixed_out_err = True)
 | |
|     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
 |