Author: Ronan Lamy <[email protected]>
Branch: testing-cleanup
Changeset: r85182:bd1fd28ffd7b
Date: 2016-06-14 22:08 +0100
http://bitbucket.org/pypy/pypy/changeset/bd1fd28ffd7b/
Log: copy and start adapting code from
rpython.translator.platform.distutils_platform
diff --git a/pypy/module/cpyext/test/support.py
b/pypy/module/cpyext/test/support.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/support.py
@@ -0,0 +1,133 @@
+import os
+import sys
+import py
+from rpython.translator.platform import log, CompilationError
+from rpython.translator.tool import stdoutcapture
+from rpython.translator.platform.distutils_platform import DistutilsPlatform
+
+rpy_platform = DistutilsPlatform()
+
+def log_spawned_cmd(spawn):
+ def spawn_and_log(cmd, *args, **kwds):
+ log.execute(' '.join(cmd))
+ return spawn(cmd, *args, **kwds)
+ return spawn_and_log
+
+CFLAGS = ['-O3']
+
+if os.name != 'nt':
+ so_ext = 'so'
+else:
+ so_ext = 'dll'
+
+def c_compile(cfilenames, eci, outputfilename=None, standalone=True):
+ self = rpy_platform
+ self._ensure_correct_math()
+ self.cfilenames = cfilenames
+ if standalone:
+ ext = ''
+ else:
+ ext = so_ext
+ self.standalone = standalone
+ self.libraries = list(eci.libraries)
+ self.include_dirs = list(eci.include_dirs)
+ self.library_dirs = list(eci.library_dirs)
+ self.compile_extra = list(eci.compile_extra)
+ self.link_extra = list(eci.link_extra)
+ self.frameworks = list(eci.frameworks)
+ if not self.name in ('win32', 'darwin', 'cygwin'): # xxx
+ if 'm' not in self.libraries:
+ self.libraries.append('m')
+ self.compile_extra += CFLAGS + ['-fomit-frame-pointer']
+ if 'pthread' not in self.libraries:
+ self.libraries.append('pthread')
+ if self.name != 'sunos5':
+ self.compile_extra += ['-pthread']
+ self.link_extra += ['-pthread']
+ else:
+ self.compile_extra += ['-pthreads']
+ self.link_extra += ['-lpthread']
+ if self.name == 'win32':
+ self.link_extra += ['/DEBUG'] # generate .pdb file
+ if self.name == 'darwin':
+ # support Fink & Darwinports
+ for s in ('/sw/', '/opt/local/'):
+ if s + 'include' not in self.include_dirs and \
+ os.path.exists(s + 'include'):
+ self.include_dirs.append(s + 'include')
+ if s + 'lib' not in self.library_dirs and \
+ os.path.exists(s + 'lib'):
+ self.library_dirs.append(s + 'lib')
+ self.compile_extra += CFLAGS + ['-fomit-frame-pointer']
+ for framework in self.frameworks:
+ self.link_extra += ['-framework', framework]
+
+ if outputfilename is None:
+ self.outputfilename = py.path.local(cfilenames[0]).new(ext=ext)
+ else:
+ self.outputfilename = py.path.local(outputfilename)
+ self.eci = eci
+ import distutils.errors
+ basename = self.outputfilename.new(ext='')
+ data = ''
+ try:
+ saved_environ = os.environ.copy()
+ c = stdoutcapture.Capture(mixed_out_err=True)
+ try:
+ self._build()
+ finally:
+ # workaround for a distutils bugs where some env vars can
+ # become longer and longer every time it is used
+ for key, value in saved_environ.items():
+ if os.environ.get(key) != value:
+ os.environ[key] = value
+ foutput, foutput = c.done()
+ data = foutput.read()
+ if data:
+ fdump = basename.new(ext='errors').open("wb")
+ fdump.write(data)
+ fdump.close()
+ except (distutils.errors.CompileError,
+ distutils.errors.LinkError):
+ raise CompilationError('', data)
+ except:
+ print >>sys.stderr, data
+ raise
+ return self.outputfilename
+
+def _build(self):
+ from distutils.ccompiler import new_compiler
+ from distutils import sysconfig
+ compiler = new_compiler(force=1)
+ if self.cc is not None:
+ for c in '''compiler compiler_so compiler_cxx
+ linker_exe linker_so'''.split():
+ compiler.executables[c][0] = self.cc
+ if not self.standalone:
+ sysconfig.customize_compiler(compiler) # XXX
+ compiler.spawn = log_spawned_cmd(compiler.spawn)
+ objects = []
+ for cfile in self.cfilenames:
+ cfile = py.path.local(cfile)
+ compile_extra = self.compile_extra[:]
+
+ old = cfile.dirpath().chdir()
+ try:
+ res = compiler.compile([cfile.basename],
+ include_dirs=self.eci.include_dirs,
+ extra_preargs=compile_extra)
+ assert len(res) == 1
+ cobjfile = py.path.local(res[0])
+ assert cobjfile.check()
+ objects.append(str(cobjfile))
+ finally:
+ old.chdir()
+
+ if self.standalone:
+ cmd = compiler.link_executable
+ else:
+ cmd = compiler.link_shared_object
+ cmd(objects, str(self.outputfilename),
+ libraries=self.eci.libraries,
+ extra_preargs=self.link_extra,
+ library_dirs=self.eci.library_dirs)
diff --git a/pypy/module/cpyext/test/test_cpyext.py
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -8,7 +8,6 @@
from pypy.interpreter import gateway
from rpython.rtyper.lltypesystem import lltype, ll2ctypes
from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.translator.platform.distutils_platform import DistutilsPlatform
from rpython.translator.gensupp import uniquemodulename
from rpython.tool.udir import udir
from pypy.module.cpyext import api
@@ -18,7 +17,7 @@
from rpython.tool import leakfinder
from rpython.rlib import rawrefcount
-rpy_platform = DistutilsPlatform()
+from .support import c_compile
@api.cpython_api([], api.PyObject)
def PyPy_Crash1(space):
@@ -52,7 +51,7 @@
files = convert_sources_to_files(source_strings, dirname)
source_files = files
eci = ExternalCompilationInfo(include_dirs=include_dirs, **kwds)
- soname = rpy_platform.compile(source_files, eci,
+ soname = c_compile(source_files, eci,
outputfilename=str(dirname/modname),
standalone=False)
return soname
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit