[pypy-svn] r62860 - pypy/trunk/pypy/rpython/tool

afa at codespeak.net afa at codespeak.net
Wed Mar 11 17:07:11 CET 2009


Author: afa
Date: Wed Mar 11 17:07:09 2009
New Revision: 62860

Modified:
   pypy/trunk/pypy/rpython/tool/rffi_platform.py
Log:
Start a better management of external libraries.
on Windows there is no standard place to install them.

I suggest to take the CPython way: in the root directory (pypy/../.. 
which is shared by all pypy branches on my disk), extract and build
all the needed third-party libraries, following documentation for each one.

for example, on my disk:
c:\dev\pypy\trunk       contains the trunk branch of pypy
c:\dev\pypy\zlib-1.2.3  download, untar, and build with 'nmake -f win32\Makefile.msc'
c:\dev\pypy\bzip2-1.0.5 download, untar, and build with 'nmake -f makefile.msc'
c:\dev\pypy\gc-7.1      download, untar, and build with 'nmake -f NT_THREADS_MAKEFILE'

The translation tools are aware of the structure of each project - they may try several ones.
You may install the version you wish - the last one (in alphabetical order) is preferred.
For the moment this is enabled only on Windows.


Modified: pypy/trunk/pypy/rpython/tool/rffi_platform.py
==============================================================================
--- pypy/trunk/pypy/rpython/tool/rffi_platform.py	(original)
+++ pypy/trunk/pypy/rpython/tool/rffi_platform.py	Wed Mar 11 17:07:09 2009
@@ -561,20 +561,103 @@
     gcv = sysconfig.get_config_vars()
     return gcv['INCLUDEPY']
 
-def check_boehm(platform=None, cache={}):
-    if platform is None:
-        from pypy.translator.platform import platform
+def configure_external_library(name, eci, configurations,
+                               symbol=None, _cache={}):
+    """try to find the external library.
+    On Unix, this simply tests and returns the given eci.
+
+    On Windows, various configurations may be tried to compile the
+    given eci object.  These configurations are a list of dicts,
+    containing:
+    
+    - prefix: if an absolute path, will prefix each include and
+              library directories.  If a relative path, the external
+              directory is searched for directories which names start
+              with the prefix.  The last one in alphabetical order
+              chosen, and becomes the prefix.
+
+    - include_dir: prefix + include_dir is added to the include directories
+    
+    - library_dir: prefix + library_dir is added to the library directories
+    """
+
+    if sys.platform != 'win32':
+        configurations = []
+    
+    key = (name, eci)
     try:
-        return cache[platform]
+        return _cache[key]
     except KeyError:
-        class CConfig:
-            _compilation_info_ = ExternalCompilationInfo(
-                includes=['gc/gc.h'],
-                platform=platform,
+        last_error = None
+
+        # Always try the default configuration
+        if {} not in configurations:
+            configurations.append({})
+
+        for configuration in configurations:
+            prefix = configuration.get('prefix', '')
+            include_dir = configuration.get('include_dir', '')
+            library_dir = configuration.get('library_dir', '')
+
+            if prefix and not os.path.isabs(prefix):
+                import glob
+
+                # XXX make this a global option?
+                from pypy.tool.autopath import pypydir
+                external_dir = py.path.local(pypydir).join('..', '..')
+
+                entries = glob.glob(str(external_dir.join(name + '*')))
+                if entries:
+                    # Get last version
+                    prefix = sorted(entries)[-1]
+                else:
+                    continue
+
+            include_dir = os.path.join(prefix, include_dir)
+            library_dir = os.path.join(prefix, library_dir)
+
+            eci_lib = ExternalCompilationInfo(
+                include_dirs=include_dir and [include_dir] or [],
+                library_dirs=library_dir and [library_dir] or [],
                 )
-            HAS = Has('GC_init')
-        cache[platform] = configure(CConfig)['HAS']
-        return cache[platform]
+            eci_lib = eci_lib.merge(eci)
+
+            # verify that this eci can be compiled
+            try:
+                verify_eci(eci_lib)
+            except CompilationError, e:
+                last_error = e
+            else:
+                _cache[key] = eci_lib
+                return eci_lib
+
+        # Nothing found
+        if last_error:
+            raise last_error
+        else:
+            raise CompilationError("Library %s is not installed" % (name,))
+
+def check_boehm(platform=None):
+    if platform is None:
+        from pypy.translator.platform import platform
+    if sys.platform == 'win32':
+        library_dir = 'Release'
+        includes=['gc.h']
+    else:
+        library_dir = ''
+        includes=['gc/gc.h']
+    eci = ExternalCompilationInfo(
+        platform=platform,
+        includes=includes,
+        libraries=['gc'],
+        )
+    try:
+        return configure_external_library(
+            'gc', eci,
+            [dict(prefix='gc-', include_dir='include', library_dir=library_dir)],
+            symbol='GC_init')
+    except CompilationError:
+        return None
 
 if __name__ == '__main__':
     doc = """Example:



More information about the Pypy-commit mailing list