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

Reply via email to