[Pyrex] distutils and .c files
dunk
dunk at dunkfordyce.co.uk
Sat Nov 12 12:03:57 CET 2005
hi,
following up from my last message im using the following code to improve
working with distutils. it automatically adds any included files as deps to
the extension and also removes the generated .c file if pyrex encountered
errors.
the code:
import os
import sys
from distutils.core import setup
from distutils.extension import Extension
from Pyrex.Distutils import build_ext
import Pyrex.Compiler.Main
from distutils.dep_util import newer
def replace_suffix(path, new_suffix):
return os.path.splitext(path)[0] + new_suffix
def find_includes(filename):
includes = []
for line in open(filename).readlines():
if line.startswith('include "'):
includes.append( line.split('"')[1] )
# XXX should recursivly scan files?
return includes
class pyrex_build_ext(build_ext):
def swig_sources (self, sources, ext=None):
if not self.extensions:
return
# collect the names of the source (.pyx) files
pyx_sources = []
pyx_sources = [source for source in sources if source.endswith('.pyx')]
other_sources = [source for source in sources if not
source.endswith('.pyx')]
deps = [source for source in ext.depends if source.endswith('.pxd') or
source.endswith('.pyx')]
extension = self.swig_cpp and '.cpp' or '.c'
for pyx in pyx_sources:
# should I raise an exception if it doesn't exist?
if os.path.exists(pyx):
print "pyrex'ing %s..." % pyx
source = pyx
target = replace_suffix(source, extension)
pxd = replace_suffix(source, '.pxd')
if os.path.exists(pxd):
includes = find_includes(pxd)
compile = False
if self.force:
print "forcing compile"
compile = True
elif newer(source, target):
print "%s is newer than %s" % (source, target)
compile = True
else:
for file in deps:
if newer(file, target):
print "include %s is newer than %s" % (file, target)
compile = True
break
if compile:
if self.pyrex_compile(source) != 0:
print "errors compiling %s. aborting and removing %s" % (source,
target)
os.unlink(target)
sys.exit(1)
if self.swig_cpp:
# rename .c to .cpp (Pyrex always builds .c ...)
if os.path.exists(target):
os.unlink(target)
#os.rename(source.replace('.pyx', '.c'), target)
os.rename(replace_suffix(source, '.c'), target)
# massage the cpp file
self.c_to_cpp(target)
else:
print "not compiling"
return [replace_suffix(src, extension) for src in pyx_sources] +
other_sources
def pyrex_compile(self, source):
result = Pyrex.Compiler.Main.compile(source)
return result.num_errors
class PyrexExtension(Extension):
def __init__(self, name, sources, **kwargs):
pyx = sources[0]
pxd = replace_suffix(pyx, '.pxd')
includes = find_includes(pyx) + find_includes(pxd)
try:
kwargs['depends'] += includes
except KeyError:
kwargs['depends'] = includes
Extension.__init__(self, name, sources, **kwargs)
On Thursday 10 November 2005 17:29, dunk wrote:
> hi,
> refering to the post entitled "pyrexc leaves bad C files, distutils doesn't
> clean" [
> http://lists.copyleft.no/pipermail/pyrex/2004-September/000928.html ]...
>
> the answer appears to be "You're right, this is not the best of situations.
> I'll add it to the list of things to fix."
>
> did that ever get fixed?
>
> it doesnt mention it in the post but shouldnt setup.py clean remove the .c
> files?
>
> cheers,
> dunk
>
> _______________________________________________
> Pyrex mailing list
> Pyrex at lists.copyleft.no
> http://lists.copyleft.no/mailman/listinfo/pyrex
More information about the Pyrex
mailing list