1
# Subclasses disutils.command.build_ext,
2
# replacing it with a Pyrex version that compiles pyx->c
3
# before calling the original build_ext command.
4
# July 2002, Graham Fawcett
5
# Modified by Darrell Gallion <dgallion1@yahoo.com>
6
# to allow inclusion of .c files along with .pyx files.
7
# Pyrex is (c) Greg Ewing.
9
import distutils.command.build_ext
10
import Pyrex.Compiler.Main
11
from Pyrex.Compiler.Errors import PyrexError
12
from distutils.dep_util import newer
16
def replace_suffix(path, new_suffix):
17
return os.path.splitext(path)[0] + new_suffix
19
class build_ext (distutils.command.build_ext.build_ext):
21
description = "compile Pyrex scripts, then build C/C++ extensions (compile/link to build directory)"
23
def finalize_options (self):
24
distutils.command.build_ext.build_ext.finalize_options(self)
26
# The following hack should no longer be needed.
28
# compiling with mingw32 gets an "initializer not a constant" error
29
# doesn't appear to happen with MSVC!
30
# so if we are compiling with mingw32,
31
# switch to C++ mode, to avoid the problem
32
if self.compiler == 'mingw32':
35
def swig_sources (self, sources):
36
if not self.extensions:
39
# collect the names of the source (.pyx) files
41
pyx_sources = [source for source in sources if source.endswith('.pyx')]
42
other_sources = [source for source in sources if not source.endswith('.pyx')]
44
extension = self.swig_cpp and '.cpp' or '.c'
45
for pyx in pyx_sources:
46
# should I raise an exception if it doesn't exist?
47
if os.path.exists(pyx):
49
#target = source.replace('.pyx', extension)
50
target = replace_suffix(source, extension)
51
if newer(source, target) or self.force:
52
self.pyrex_compile(source)
55
# rename .c to .cpp (Pyrex always builds .c ...)
56
if os.path.exists(target):
58
#os.rename(source.replace('.pyx', '.c'), target)
59
os.rename(replace_suffix(source, '.c'), target)
60
# massage the cpp file
63
return [replace_suffix(src, extension) for src in pyx_sources] + other_sources
65
def pyrex_compile(self, source):
66
result = Pyrex.Compiler.Main.compile(source)
67
if result.num_errors <> 0:
70
def c_to_cpp(self, filename):
71
"""touch up the Pyrex generated c/cpp files to meet mingw32/distutils requirements."""
72
f = open(filename, 'r')
73
lines = [line for line in f.readlines() if not line.startswith('staticforward PyTypeObject __pyx_type_')]
75
f = open(filename, 'w')
76
lines.insert(1, 'extern "C" {\n')
78
f.write(''.join(lines))