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