[pypy-svn] r54725 - in pypy/dist/pypy: rpython/lltypesystem rpython/lltypesystem/test translator/c translator/tool
afa at codespeak.net
afa at codespeak.net
Wed May 14 11:16:49 CEST 2008
Author: afa
Date: Wed May 14 11:16:47 2008
New Revision: 54725
Modified:
pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
pypy/dist/pypy/rpython/lltypesystem/rffi.py
pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
pypy/dist/pypy/translator/c/genc.py
pypy/dist/pypy/translator/tool/cbuild.py
Log:
Make CExtModuleBuilder and ll2ctypes work on win32:
- export all needed symbols when building a dll
- eventually compile with debug info
- load the correct libc, depending on compiler version and options.
test_rffi and test_ll2ctypes pass, and probably many others.
Modified: pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py Wed May 14 11:16:47 2008
@@ -519,13 +519,27 @@
if ctypes:
if sys.platform == 'win32':
- # trying to guess the correct libc... only a few tests fail if there
- # is a mismatch between the one used by python2x.dll and the one
- # loaded here
- if sys.version_info < (2, 4):
- standard_c_lib = ctypes.cdll.LoadLibrary('msvcrt.dll')
+ # Parses sys.version and deduces the version of the compiler
+ import distutils.msvccompiler
+ version = distutils.msvccompiler.get_build_version()
+ if version is None:
+ # This logic works with official builds of Python.
+ if sys.version_info < (2, 4):
+ clibname = 'msvcrt'
+ else:
+ clibname = 'msvcr71'
else:
- standard_c_lib = ctypes.cdll.LoadLibrary('msvcr71.dll')
+ if version <= 6:
+ clibname = 'msvcrt'
+ else:
+ clibname = 'msvcr%d' % (version * 10)
+
+ # If python was built with in debug mode
+ import imp
+ if imp.get_suffixes()[0][0] == '_d.pyd':
+ clibname += 'd'
+
+ standard_c_lib = ctypes.cdll.LoadLibrary(clibname+'.dll')
else:
standard_c_lib = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c'))
Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rffi.py Wed May 14 11:16:47 2008
@@ -406,6 +406,7 @@
new_eci = eci.merge(ExternalCompilationInfo(
separate_module_sources = sources,
post_include_lines = [getter_prototype, setter_prototype],
+ export_symbols = [getter_name, setter_name],
))
getter = llexternal(getter_name, [], TYPE, compilation_info=new_eci,
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Wed May 14 11:16:47 2008
@@ -267,8 +267,11 @@
assert not ALLOCATED # detects memory leaks in the test
def test_frexp(self):
- eci = ExternalCompilationInfo(includes=['math.h'],
- libraries=['m'])
+ if sys.platform != 'win32':
+ eci = ExternalCompilationInfo(includes=['math.h'],
+ libraries=['m'])
+ else:
+ eci = ExternalCompilationInfo(includes=['math.h'])
A = lltype.FixedSizeArray(rffi.INT, 1)
frexp = rffi.llexternal('frexp', [rffi.DOUBLE, lltype.Ptr(A)],
rffi.DOUBLE, compilation_info=eci)
@@ -299,6 +302,8 @@
assert not ALLOCATED # detects memory leaks in the test
def test_opaque_obj(self):
+ if sys.platform == 'win32':
+ py.test.skip("No gettimeofday on win32")
eci = ExternalCompilationInfo(
includes = ['sys/time.h', 'time.h']
)
@@ -683,6 +688,8 @@
assert abs(float(b[2]) - 2.2) < 1E-6
def test_different_signatures(self):
+ if sys.platform=='win32':
+ py.test.skip("No fcntl on win32")
fcntl_int = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.INT],
rffi.INT)
fcntl_str = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.CCHARP],
@@ -693,7 +700,8 @@
def test_llexternal_source(self):
eci = ExternalCompilationInfo(
- separate_module_sources = ["int fn() { return 42; }"]
+ separate_module_sources = ["int fn() { return 42; }"],
+ export_symbols = ['fn'],
)
fn = rffi.llexternal('fn', [], rffi.INT, compilation_info=eci)
res = fn()
@@ -745,7 +753,8 @@
}
""")
- eci = ExternalCompilationInfo(separate_module_sources=[c_source])
+ eci = ExternalCompilationInfo(separate_module_sources=[c_source],
+ export_symbols=['eating_callback'])
args = [rffi.INT, rffi.CCallback([rffi.INT], rffi.INT)]
eating_callback = rffi.llexternal('eating_callback', args, rffi.INT,
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py Wed May 14 11:16:47 2008
@@ -1,5 +1,6 @@
import py
+import sys
from pypy.rpython.lltypesystem.rffi import *
from pypy.rpython.lltypesystem.rffi import _keeper_for_type # crap
from pypy.rlib.rposix import get_errno, set_errno
@@ -347,7 +348,8 @@
eci = ExternalCompilationInfo(includes=['callback.h'],
include_dirs=[str(udir)],
- separate_module_sources=[c_source])
+ separate_module_sources=[c_source],
+ export_symbols=['eating_callback'])
args = [INT, CCallback([INT], INT)]
eating_callback = llexternal('eating_callback', args, INT,
@@ -530,6 +532,8 @@
assert interpret(f, [], backendopt=True) == 43
def test_around_extcall(self):
+ if sys.platform == "win32":
+ py.test.skip('No pipes on windows')
import os
from pypy.annotation import model as annmodel
from pypy.rlib.objectmodel import invoke_around_extcall
Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py (original)
+++ pypy/dist/pypy/translator/c/genc.py Wed May 14 11:16:47 2008
@@ -181,7 +181,10 @@
def __del__(self):
import sys
- from _ctypes import dlclose
+ if sys.platform == "win32":
+ from _ctypes import FreeLibrary as dlclose
+ else:
+ from _ctypes import dlclose
# XXX fish fish fish
mod = self.__dict__['mod']
dlclose(mod._lib._handle)
@@ -204,9 +207,15 @@
def compile(self):
assert self.c_source_filename
assert not self._compiled
+ export_symbols = [self.db.get(self.getentrypointptr()),
+ 'RPython_StartupCode',
+ ]
+ if self.config.translation.countmallocs:
+ export_symbols.append('malloc_counters')
compile_c_module([self.c_source_filename] + self.extrafiles,
self.c_source_filename.purebasename, self.eci,
- tmpdir=self.c_source_filename.dirpath())
+ tmpdir=self.c_source_filename.dirpath(),
+ export_symbols=export_symbols)
self._compiled = True
def _make_wrapper_module(self):
@@ -219,7 +228,7 @@
CODE = """
import ctypes
-_lib = ctypes.PyDLL("%(so_name)s")
+_lib = ctypes.PyDLL(r"%(so_name)s")
_entry_point = getattr(_lib, "%(c_entrypoint_name)s")
_entry_point.restype = ctypes.py_object
Modified: pypy/dist/pypy/translator/tool/cbuild.py
==============================================================================
--- pypy/dist/pypy/translator/tool/cbuild.py (original)
+++ pypy/dist/pypy/translator/tool/cbuild.py Wed May 14 11:16:47 2008
@@ -16,7 +16,8 @@
_ATTRIBUTES = ['pre_include_lines', 'includes', 'include_dirs',
'post_include_lines', 'libraries', 'library_dirs',
- 'separate_module_sources', 'separate_module_files']
+ 'separate_module_sources', 'separate_module_files',
+ 'export_symbols']
_AVOID_DUPLICATES = ['separate_module_files', 'libraries', 'includes',
'include_dirs', 'library_dirs', 'separate_module_sources']
@@ -28,7 +29,8 @@
libraries = [],
library_dirs = [],
separate_module_sources = [],
- separate_module_files = []):
+ separate_module_files = [],
+ export_symbols = []):
"""
pre_include_lines: list of lines that should be put at the top
of the generated .c files, before any #include. They shouldn't
@@ -196,7 +198,8 @@
opt += '/Op'
gcv['OPT'] = opt
-def compile_c_module(cfiles, modbasename, eci, tmpdir=None):
+def compile_c_module(cfiles, modbasename, eci, tmpdir=None,
+ export_symbols=None):
#try:
# from distutils.log import set_threshold
# set_threshold(10000)
@@ -220,6 +223,11 @@
os.path.exists(s + 'lib'):
library_dirs.append(s + 'lib')
+ if export_symbols is None:
+ export_symbols = list(eci.export_symbols)
+ else:
+ export_symbols = list(eci.export_symbols) + export_symbols
+
num = 0
modname = modbasename
while 1:
@@ -253,11 +261,17 @@
from distutils.ccompiler import get_default_compiler
from distutils.command.build_ext import build_ext
- class build_ext_no_additional_symbol(build_ext):
+ class build_shared_library(build_ext):
+ """ We build shared libraries, not python modules.
+ On windows, avoid to export the initXXX function,
+ and don't use a .pyd extension. """
def get_export_symbols(self, ext):
- """ work around a 'feature' of distutils that forces every
- module to have a certain symbol on win """
return ext.export_symbols
+ def get_ext_filename (self, ext_name):
+ if sys.platform == 'win32':
+ return ext_name + ".dll"
+ else:
+ return ext_name + ".so"
saved_environ = os.environ.items()
try:
@@ -290,7 +304,9 @@
include_dirs=include_dirs,
library_dirs=library_dirs,
extra_compile_args=extra_compile_args,
- libraries=list(libraries),)
+ libraries=list(libraries),
+ export_symbols=export_symbols,
+ )
],
'script_name': 'setup.py',
'script_args': ['-q', 'build_ext'], # don't remove 'build_ext' here
@@ -299,9 +315,11 @@
# patch our own command obj into distutils
# because it does not have a facility to accept
# custom objects
- cmdobj = build_ext_no_additional_symbol(dist)
+ cmdobj = build_shared_library(dist)
cmdobj.inplace = True
cmdobj.force = True
+ if sys.platform == 'win32' and sys.executable.endswith('_d.exe'):
+ cmdobj.debug = True
dist.command_obj["build_ext"] = cmdobj
dist.have_run["build_ext"] = 0
More information about the Pypy-commit
mailing list