Author: Armin Rigo <ar...@tunes.org>
Branch: static-callback-embedding
Changeset: r2548:2d42a1e6d060
Date: 2016-01-07 23:05 +0100
http://bitbucket.org/cffi/cffi/changeset/2d42a1e6d060/

Log:    In-progress: fix tests to attempt to use distutils also for
        compiling the executable

diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -537,14 +537,17 @@
 
     def _apply_embedding_fix(self, kwds):
         # must include an argument like "-lpython2.7" for the compiler
-        if sys.platform == "win32":
-            template = "python%d%d"
-            if sys.flags.debug:
-                template = template + '_d'
+        if '__pypy__' in sys.builtin_module_names:
+            pythonlib = "pypy-c"
         else:
-            template = "python%d.%d"
-        pythonlib = (template %
-                (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+            if sys.platform == "win32":
+                template = "python%d%d"
+                if sys.flags.debug:
+                    template = template + '_d'
+            else:
+                template = "python%d.%d"
+            pythonlib = (template %
+                    (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
         libraries = kwds.get('libraries', [])
         if pythonlib not in libraries:
             kwds['libraries'] = libraries + [pythonlib]
diff --git a/testing/embedding/add1.py b/testing/embedding/add1.py
--- a/testing/embedding/add1.py
+++ b/testing/embedding/add1.py
@@ -28,4 +28,5 @@
 ffi.set_source("_add1_cffi", """
 """)
 
-ffi.compile(verbose=True)
+fn = ffi.compile(verbose=True)
+print 'FILENAME:', fn
diff --git a/testing/embedding/add2.py b/testing/embedding/add2.py
--- a/testing/embedding/add2.py
+++ b/testing/embedding/add2.py
@@ -24,4 +24,5 @@
 ffi.set_source("_add2_cffi", """
 """)
 
-ffi.compile()
+fn = ffi.compile(verbose=True)
+print 'FILENAME:', fn
diff --git a/testing/embedding/add3.py b/testing/embedding/add3.py
--- a/testing/embedding/add3.py
+++ b/testing/embedding/add3.py
@@ -19,4 +19,5 @@
 ffi.set_source("_add3_cffi", """
 """)
 
-ffi.compile()
+fn = ffi.compile(verbose=True)
+print 'FILENAME:', fn
diff --git a/testing/embedding/add_recursive.py 
b/testing/embedding/add_recursive.py
--- a/testing/embedding/add_recursive.py
+++ b/testing/embedding/add_recursive.py
@@ -24,4 +24,5 @@
 int (*my_callback)(int);
 """)
 
-ffi.compile()
+fn = ffi.compile(verbose=True)
+print 'FILENAME:', fn
diff --git a/testing/embedding/perf.py b/testing/embedding/perf.py
--- a/testing/embedding/perf.py
+++ b/testing/embedding/perf.py
@@ -17,4 +17,5 @@
 ffi.set_source("_perf_cffi", """
 """)
 
-ffi.compile(verbose=True)
+fn = ffi.compile(verbose=True)
+print 'FILENAME:', fn
diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py
--- a/testing/embedding/test_basic.py
+++ b/testing/embedding/test_basic.py
@@ -1,24 +1,30 @@
 import py
-import sys, os
-import shutil, subprocess
+import sys, os, re
+import shutil, subprocess, time
 from testing.udir import udir
 
 local_dir = os.path.dirname(os.path.abspath(__file__))
 
 
 class EmbeddingTests:
-    _compiled_modules = set()
+    _compiled_modules = {}
+
+    def setup_method(self, meth):
+        self._path = udir.join('embedding', meth.__name__)
 
     def get_path(self):
-        return str(udir.ensure('embedding', dir=True))
+        return str(self._path.ensure(dir=1))
 
     def _run(self, args, env=None):
         print(args)
-        popen = subprocess.Popen(args, env=env, cwd=self.get_path())
+        popen = subprocess.Popen(args, env=env, cwd=self.get_path(), 
stdout=subprocess.PIPE)
+        output = popen.stdout.read()
         err = popen.wait()
         if err:
             raise OSError("popen failed with exit code %r: %r" % (
                 err, args))
+        print(output.rstrip())
+        return output
 
     def prepare_module(self, name):
         if name not in self._compiled_modules:
@@ -27,71 +33,42 @@
             # NOTE: if you have an .egg globally installed with an older
             # version of cffi, this will not work, because sys.path ends
             # up with the .egg before the PYTHONPATH entries.  I didn't
-            # find a solution to that: we can hack sys.path inside the
+            # find a solution to that: we could hack sys.path inside the
             # script run here, but we can't hack it in the same way in
             # execute().
             env = os.environ.copy()
             env['PYTHONPATH'] = os.path.dirname(os.path.dirname(local_dir))
-            self._run([sys.executable, os.path.join(local_dir, filename)],
-                      env=env)
-            self._compiled_modules.add(name)
+            output = self._run([sys.executable, os.path.join(local_dir, 
filename)],
+                               env=env)
+            match = re.compile(r"\bFILENAME: (.+)").search(output)
+            assert match
+            dynamic_lib_name = match.group(1)
+            self._compiled_modules[name] = dynamic_lib_name
+        return self._compiled_modules[name]
 
-    def compile(self, name, modules, **flags):
+    def compile(self, name, modules, opt=False, threads=False, defines={}):
         path = self.get_path()
         filename = '%s.c' % name
         shutil.copy(os.path.join(local_dir, filename), path)
-        if sys.platform.startswith('linux'):
-            self._compile_linux(name, modules, **flags)
-        elif sys.platform.startswith('win'):
-            self._compile_win(name, modules, **flags)
-        else:
-            py.test.skip("don't know how to invoke the C compiler on %r" %
-                         (sys.platform,))
-
-    def _compile_linux(self, name, modules,
-                       opt=False, threads=False, defines={}):
-        path = self.get_path()
-        filename = '%s.c' % name
-        if 'CC' in os.environ:
-            args = os.environ['CC'].split()
-        else:
-            args = ['gcc']
-        if 'CFLAGS' in os.environ:
-            args.extend(os.environ['CFLAGS'].split())
-        if 'LDFLAGS' in os.environ:
-            args.extend(os.environ['LDFLAGS'].split())
-        if threads:
-            args.append('-pthread')
-        if opt:
-            args.append('-O2')
-        args.extend(['-g', filename, '-o', name, '-L.'])
-        if '__pypy__' in sys.builtin_module_names:
-            # xxx a bit hackish, maybe ffi.compile() should do a better job
-            executable = os.path.abspath(sys.executable)
-            libpypy_c = os.path.join(os.path.dirname(executable),
-                                     'libpypy-c.so')
-            try:
-                os.symlink(libpypy_c, os.path.join(path, 'libpypy-c.so'))
-            except OSError:
-                pass
-            args.extend(['%s.pypy-26.so' % modname for modname in modules])
-            args.append('-lpypy-c')
-        else:
-            args.extend(['%s.so' % modname for modname in modules])
-            args.append('-lpython2.7')
-        args.append('-Wl,-rpath=$ORIGIN/')
-        for key, value in sorted(defines.items()):
-            args.append('-D%s=%s' % (key, value))
-        self._run(args)
-
-    def _compile_win(self, name, modules,
-                     opt=False, threads=False, defines={}):
-        xxxx
+        import distutils.ccompiler
+        curdir = os.getcwd()
+        try:
+            os.chdir(self.get_path())
+            c = distutils.ccompiler.new_compiler()
+            print('compiling %s with %r' % (name, modules))
+            extra_preargs = []
+            if threads and sys.platform != 'win32':
+                extra_preargs.append('-pthread')
+            objects = c.compile([filename], macros=sorted(defines.items()), 
debug=True)
+            c.link_executable(objects + modules, name, 
extra_preargs=extra_preargs)
+        finally:
+            os.chdir(curdir)
 
     def execute(self, name):
         path = self.get_path()
         env = os.environ.copy()
         env['PYTHONPATH'] = os.path.dirname(os.path.dirname(local_dir))
+        env['LD_LIBRARY_PATH'] = path
         print 'running %r in %r' % (name, path)
         popen = subprocess.Popen([name], cwd=path, env=env,
                                  stdout=subprocess.PIPE)
@@ -104,8 +81,8 @@
 
 class TestBasic(EmbeddingTests):
     def test_basic(self):
-        self.prepare_module('add1')
-        self.compile('add1-test', ['_add1_cffi'])
+        add1_cffi = self.prepare_module('add1')
+        self.compile('add1-test', [add1_cffi])
         output = self.execute('add1-test')
         assert output == ("preparing...\n"
                           "adding 40 and 2\n"
@@ -113,9 +90,9 @@
                           "got: 42 95\n")
 
     def test_two_modules(self):
-        self.prepare_module('add1')
-        self.prepare_module('add2')
-        self.compile('add2-test', ['_add1_cffi', '_add2_cffi'])
+        add1_cffi = self.prepare_module('add1')
+        add2_cffi = self.prepare_module('add2')
+        self.compile('add2-test', [add1_cffi, add2_cffi])
         output = self.execute('add2-test')
         assert output == ("preparing...\n"
                           "adding 40 and 2\n"
diff --git a/testing/embedding/test_performance.py 
b/testing/embedding/test_performance.py
--- a/testing/embedding/test_performance.py
+++ b/testing/embedding/test_performance.py
@@ -3,16 +3,16 @@
 
 class TestPerformance(EmbeddingTests):
     def test_perf_single_threaded(self):
-        self.prepare_module('perf')
-        self.compile('perf-test', ['_perf_cffi'], opt=True)
+        perf_cffi = self.prepare_module('perf')
+        self.compile('perf-test', [perf_cffi], opt=True)
         output = self.execute('perf-test')
         print '='*79
         print output.rstrip()
         print '='*79
 
     def test_perf_in_1_thread(self):
-        self.prepare_module('perf')
-        self.compile('perf-test', ['_perf_cffi'], opt=True, threads=True,
+        perf_cffi = self.prepare_module('perf')
+        self.compile('perf-test', [perf_cffi], opt=True, threads=True,
                      defines={'PTEST_USE_THREAD': '1'})
         output = self.execute('perf-test')
         print '='*79
@@ -20,8 +20,8 @@
         print '='*79
 
     def test_perf_in_2_threads(self):
-        self.prepare_module('perf')
-        self.compile('perf-test', ['_perf_cffi'], opt=True, threads=True,
+        perf_cffi = self.prepare_module('perf')
+        self.compile('perf-test', [perf_cffi], opt=True, threads=True,
                      defines={'PTEST_USE_THREAD': '2'})
         output = self.execute('perf-test')
         print '='*79
@@ -29,8 +29,8 @@
         print '='*79
 
     def test_perf_in_4_threads(self):
-        self.prepare_module('perf')
-        self.compile('perf-test', ['_perf_cffi'], opt=True, threads=True,
+        perf_cffi = self.prepare_module('perf')
+        self.compile('perf-test', [perf_cffi], opt=True, threads=True,
                      defines={'PTEST_USE_THREAD': '4'})
         output = self.execute('perf-test')
         print '='*79
@@ -38,8 +38,8 @@
         print '='*79
 
     def test_perf_in_8_threads(self):
-        self.prepare_module('perf')
-        self.compile('perf-test', ['_perf_cffi'], opt=True, threads=True,
+        perf_cffi = self.prepare_module('perf')
+        self.compile('perf-test', [perf_cffi], opt=True, threads=True,
                      defines={'PTEST_USE_THREAD': '8'})
         output = self.execute('perf-test')
         print '='*79
diff --git a/testing/embedding/test_recursive.py 
b/testing/embedding/test_recursive.py
--- a/testing/embedding/test_recursive.py
+++ b/testing/embedding/test_recursive.py
@@ -3,8 +3,8 @@
 
 class TestRecursive(EmbeddingTests):
     def test_recursive(self):
-        self.prepare_module('add_recursive')
-        self.compile('add_recursive-test', ['_add_recursive_cffi'])
+        add_recursive_cffi = self.prepare_module('add_recursive')
+        self.compile('add_recursive-test', [add_recursive_cffi])
         output = self.execute('add_recursive-test')
         assert output == ("preparing REC\n"
                           "some_callback(400)\n"
diff --git a/testing/embedding/test_thread.py b/testing/embedding/test_thread.py
--- a/testing/embedding/test_thread.py
+++ b/testing/embedding/test_thread.py
@@ -3,8 +3,8 @@
 
 class TestThread(EmbeddingTests):
     def test_first_calls_in_parallel(self):
-        self.prepare_module('add1')
-        self.compile('thread1-test', ['_add1_cffi'], threads=True)
+        add1_cffi = self.prepare_module('add1')
+        self.compile('thread1-test', [add1_cffi], threads=True)
         for i in range(50):
             output = self.execute('thread1-test')
             assert output == ("starting\n"
@@ -18,9 +18,9 @@
         return text[:i] + text[i+len(content):]
 
     def test_init_different_modules_in_different_threads(self):
-        self.prepare_module('add1')
-        self.prepare_module('add2')
-        self.compile('thread2-test', ['_add1_cffi', '_add2_cffi'], 
threads=True)
+        add1_cffi = self.prepare_module('add1')
+        add2_cffi = self.prepare_module('add2')
+        self.compile('thread2-test', [add1_cffi, add2_cffi], threads=True)
         output = self.execute('thread2-test')
         output = self._take_out(output, "preparing")
         output = self._take_out(output, ".")
@@ -34,9 +34,9 @@
                           "done\n")
 
     def test_alt_issue(self):
-        self.prepare_module('add1')
-        self.prepare_module('add2')
-        self.compile('thread2-test', ['_add1_cffi', '_add2_cffi'],
+        add1_cffi = self.prepare_module('add1')
+        add2_cffi = self.prepare_module('add2')
+        self.compile('thread2-test', [add1_cffi, add2_cffi],
                      threads=True, defines={'T2TEST_AGAIN_ADD1': '1'})
         output = self.execute('thread2-test')
         output = self._take_out(output, "adding 40 and 2\n")
@@ -48,9 +48,9 @@
                           "done\n")
 
     def test_load_in_parallel_more(self):
-        self.prepare_module('add2')
-        self.prepare_module('add3')
-        self.compile('thread3-test', ['_add2_cffi', '_add3_cffi'], 
threads=True)
+        add2_cffi = self.prepare_module('add2')
+        add3_cffi = self.prepare_module('add3')
+        self.compile('thread3-test', [add2_cffi, add3_cffi], threads=True)
         for i in range(150):
             output = self.execute('thread3-test')
             for j in range(10):
diff --git a/testing/embedding/test_tlocal.py b/testing/embedding/test_tlocal.py
--- a/testing/embedding/test_tlocal.py
+++ b/testing/embedding/test_tlocal.py
@@ -3,8 +3,8 @@
 
 class TestThreadLocal(EmbeddingTests):
     def test_thread_local(self):
-        self.prepare_module('tlocal')
-        self.compile('tlocal-test', ['_tlocal_cffi'], threads=True)
+        tlocal_cffi = self.prepare_module('tlocal')
+        self.compile('tlocal-test', [tlocal_cffi], threads=True)
         for i in range(10):
             output = self.execute('tlocal-test')
             assert output == "done\n"
diff --git a/testing/embedding/tlocal.py b/testing/embedding/tlocal.py
--- a/testing/embedding/tlocal.py
+++ b/testing/embedding/tlocal.py
@@ -24,4 +24,5 @@
 ffi.set_source("_tlocal_cffi", """
 """)
 
-ffi.compile(verbose=True)
+fn = ffi.compile(verbose=True)
+print 'FILENAME:', fn
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to