Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit