[pypy-commit] pypy default: Most of the cygwin patch (Uwe F. Mayer on pypy-dev).

arigo noreply at buildbot.pypy.org
Sun Jun 3 11:52:48 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r55275:2907bd0a82ce
Date: 2012-06-03 11:52 +0200
http://bitbucket.org/pypy/pypy/changeset/2907bd0a82ce/

Log:	Most of the cygwin patch (Uwe F. Mayer on pypy-dev).

diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py
--- a/lib_pypy/ctypes_support.py
+++ b/lib_pypy/ctypes_support.py
@@ -12,6 +12,8 @@
 if sys.platform == 'win32':
     import _ffi
     standard_c_lib = ctypes.CDLL('msvcrt', handle=_ffi.get_libc())
+elif sys.platform == 'cygwin':
+    standard_c_lib = ctypes.CDLL(ctypes.util.find_library('cygwin'))
 else:
     standard_c_lib = ctypes.CDLL(ctypes.util.find_library('c'))
 
diff --git a/pypy/module/_minimal_curses/fficurses.py b/pypy/module/_minimal_curses/fficurses.py
--- a/pypy/module/_minimal_curses/fficurses.py
+++ b/pypy/module/_minimal_curses/fficurses.py
@@ -8,11 +8,20 @@
 from pypy.rpython.extfunc import register_external
 from pypy.module._minimal_curses import interp_curses
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from sys import platform
 
-eci = ExternalCompilationInfo(
-    includes = ['curses.h', 'term.h'],
-    libraries = ['curses'],
-)
+_CYGWIN = platform == 'cygwin'
+
+if _CYGWIN:
+    eci = ExternalCompilationInfo(
+        includes = ['ncurses/curses.h', 'ncurses/term.h'],
+        libraries = ['curses'],
+    )
+else:
+    eci = ExternalCompilationInfo(
+        includes = ['curses.h', 'term.h'],
+        libraries = ['curses'],
+    )
 
 rffi_platform.verify_eci(eci)
 
diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py
--- a/pypy/module/rctime/interp_time.py
+++ b/pypy/module/rctime/interp_time.py
@@ -12,6 +12,15 @@
 
 _POSIX = os.name == "posix"
 _WIN = os.name == "nt"
+_CYGWIN = sys.platform == "cygwin"
+
+_time_zones = []
+if _CYGWIN:
+    _time_zones = ["GMT-12", "GMT-11", "GMT-10", "GMT-9", "GMT-8", "GMT-7",
+                   "GMT-6", "GMT-5", "GMT-4", "GMT-3", "GMT-2", "GMT-1",
+                   "GMT",  "GMT+1", "GMT+2", "GMT+3", "GMT+4", "GMT+5",
+                   "GMT+6",  "GMT+7", "GMT+8", "GMT+9", "GMT+10", "GMT+11",
+                   "GMT+12",  "GMT+13", "GMT+14"]
 
 if _WIN:
     # Interruptible sleeps on Windows:
@@ -107,11 +116,17 @@
     CConfig.timeval = platform.Struct("struct timeval",
                                       [("tv_sec", rffi.INT),
                                        ("tv_usec", rffi.INT)])
-    CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
-        ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
-        ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
-        ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT), ("tm_gmtoff", rffi.LONG),
-        ("tm_zone", rffi.CCHARP)])
+    if _CYGWIN:
+        CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
+            ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
+            ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
+            ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT)])
+    else:
+        CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
+            ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
+            ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
+            ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT), ("tm_gmtoff", rffi.LONG),
+            ("tm_zone", rffi.CCHARP)])
 elif _WIN:
     calling_conv = 'win'
     CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
@@ -202,35 +217,81 @@
          tzname = rffi.charp2str(tzname_ptr[0]), rffi.charp2str(tzname_ptr[1])
 
     if _POSIX:
-        YEAR = (365 * 24 + 6) * 3600
+        if _CYGWIN:
+            YEAR = (365 * 24 + 6) * 3600
 
-        t = (((c_time(lltype.nullptr(rffi.TIME_TP.TO))) / YEAR) * YEAR)
-        # we cannot have reference to stack variable, put it on the heap
-        t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
-        t_ref[0] = rffi.cast(rffi.TIME_T, t)
-        p = c_localtime(t_ref)
-        janzone = -p.c_tm_gmtoff
-        tm_zone = rffi.charp2str(p.c_tm_zone)
-        janname = ["   ", tm_zone][bool(tm_zone)]
-        tt = t + YEAR / 2
-        t_ref[0] = rffi.cast(rffi.TIME_T, tt)
-        p = c_localtime(t_ref)
-        lltype.free(t_ref, flavor='raw')
-        tm_zone = rffi.charp2str(p.c_tm_zone)
-        julyzone = -p.c_tm_gmtoff
-        julyname = ["   ", tm_zone][bool(tm_zone)]
+            # about January 11th
+            t = (((c_time(lltype.nullptr(rffi.TIME_TP.TO))) / YEAR) * YEAR + 10 * 24 * 3600)
+            # we cannot have reference to stack variable, put it on the heap
+            t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
+            t_ref[0] = rffi.cast(rffi.TIME_T, t)
+            p = c_localtime(t_ref)
+            q = c_gmtime(t_ref)
+            janzone = (p.c_tm_hour + 24 * p.c_tm_mday) - (q.c_tm_hour + 24 * q.c_tm_mday)
+            if janzone < -12:
+                janname = "   "
+            elif janzone > 14:
+                janname = "   "
+            else:
+                janname = _time_zones[janzone - 12]
+            janzone = janzone * 3600
+            # about July 11th
+            tt = t + YEAR / 2
+            t_ref[0] = rffi.cast(rffi.TIME_T, tt)
+            p = c_localtime(t_ref)
+            q = c_gmtime(t_ref)
+            julyzone = (p.c_tm_hour + 24 * p.c_tm_mday) - (q.c_tm_hour + 24 * q.c_tm_mday)
+            if julyzone < -12:
+                julyname = "   "
+            elif julyzone > 14:
+                julyname = "   "
+            else:
+                julyname = _time_zones[julyzone - 12]
+            julyzone = julyzone * 3600
+            lltype.free(t_ref, flavor='raw')
 
-        if janzone < julyzone:
-            # DST is reversed in the southern hemisphere
-            timezone = julyzone
-            altzone = janzone
-            daylight = int(janzone != julyzone)
-            tzname = [julyname, janname]
+            if janzone < julyzone:
+                # DST is reversed in the southern hemisphere
+                timezone = julyzone
+                altzone = janzone
+                daylight = int(janzone != julyzone)
+                tzname = [julyname, janname]
+            else:
+                timezone = janzone
+                altzone = julyzone
+                daylight = int(janzone != julyzone)
+                tzname = [janname, julyname]
+
         else:
-            timezone = janzone
-            altzone = julyzone
-            daylight = int(janzone != julyzone)
-            tzname = [janname, julyname]
+            YEAR = (365 * 24 + 6) * 3600
+
+            t = (((c_time(lltype.nullptr(rffi.TIME_TP.TO))) / YEAR) * YEAR)
+            # we cannot have reference to stack variable, put it on the heap
+            t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
+            t_ref[0] = rffi.cast(rffi.TIME_T, t)
+            p = c_localtime(t_ref)
+            janzone = -p.c_tm_gmtoff
+            tm_zone = rffi.charp2str(p.c_tm_zone)
+            janname = ["   ", tm_zone][bool(tm_zone)]
+            tt = t + YEAR / 2
+            t_ref[0] = rffi.cast(rffi.TIME_T, tt)
+            p = c_localtime(t_ref)
+            lltype.free(t_ref, flavor='raw')
+            tm_zone = rffi.charp2str(p.c_tm_zone)
+            julyzone = -p.c_tm_gmtoff
+            julyname = ["   ", tm_zone][bool(tm_zone)]
+
+            if janzone < julyzone:
+                # DST is reversed in the southern hemisphere
+                timezone = julyzone
+                altzone = janzone
+                daylight = int(janzone != julyzone)
+                tzname = [julyname, janname]
+            else:
+                timezone = janzone
+                altzone = julyzone
+                daylight = int(janzone != julyzone)
+                tzname = [janname, julyname]
 
     _set_module_object(space, "timezone", space.wrap(timezone))
     _set_module_object(space, 'daylight', space.wrap(daylight))
@@ -361,9 +422,12 @@
     rffi.setintfield(glob_buf, 'c_tm_yday', tm_yday)
     rffi.setintfield(glob_buf, 'c_tm_isdst', space.int_w(tup_w[8]))
     if _POSIX:
-        # actually never happens, but makes annotator happy
-        glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO)
-        rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0)
+        if _CYGWIN:
+            pass
+        else:
+            # actually never happens, but makes annotator happy
+            glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO)
+            rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0)
 
     w_accept2dyear = _get_module_object(space, "accept2dyear")
     accept2dyear = space.int_w(w_accept2dyear)
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -148,6 +148,7 @@
 else:
     includes += ['sys/utime.h']
 
+_CYGWIN = sys.platform == 'cygwin'
 
 class CConfig:
     """
@@ -1329,9 +1330,14 @@
                 return result
         else:
             # Posix
-            os_waitpid = self.llexternal('waitpid',
-                                         [rffi.PID_T, rffi.INTP, rffi.INT],
-                                         rffi.PID_T)
+            if _CYGWIN:
+                os_waitpid = self.llexternal('cygwin_waitpid',
+                                             [rffi.PID_T, rffi.INTP, rffi.INT],
+                                             rffi.PID_T)
+            else:
+                os_waitpid = self.llexternal('waitpid',
+                                             [rffi.PID_T, rffi.INTP, rffi.INT],
+                                             rffi.PID_T)
 
         def os_waitpid_llimpl(pid, options):
             status_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -145,6 +145,8 @@
             archive = str(builddir.join(name + '.tar.bz2'))
             if sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
                 e = os.system('tar --numeric-owner -cvjf ' + archive + " " + name)
+            elif sys.platform == 'cygwin':
+                e = os.system('tar --owner=Administrator --group=Administrators --numeric-owner -cvjf ' + archive + " " + name)
             else:
                 e = os.system('tar --owner=root --group=root --numeric-owner -cvjf ' + archive + " " + name)
             if e:
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -15,6 +15,8 @@
 from pypy.rlib import exports
 from pypy.tool.nullpath import NullPyPathLocal
 
+_CYGWIN = sys.platform == 'cygwin'
+
 def import_module_from_directory(dir, modname):
     file, pathname, description = imp.find_module(modname, [str(dir)])
     try:
@@ -954,6 +956,8 @@
         srcdir / 'profiling.c',
         srcdir / 'debug_print.c',
     ]
+    if _CYGWIN:
+        files.append(srcdir / 'cygwin_wait.c')
     return eci.merge(ExternalCompilationInfo(separate_module_files=files))
 
 
diff --git a/pypy/translator/c/src/cygwin_wait.c b/pypy/translator/c/src/cygwin_wait.c
new file mode 100644
--- /dev/null
+++ b/pypy/translator/c/src/cygwin_wait.c
@@ -0,0 +1,47 @@
+/*
+  Work around compile error:
+  [translation:ERROR]     implement_4.c: In function 'pypy_g_ccall_waitpid__Signed_arrayPtr_Signed':
+  [translation:ERROR]     implement_4.c:150095:2: error: incompatible type for argument 2 of 'waitpid'
+  [translation:ERROR]     /usr/include/sys/wait.h:43:7: note: expected '__wait_status_ptr_t' but argument is of type 'long int *'
+*/
+
+#ifdef __CYGWIN__
+
+#include "wait.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /*
+typedef int *__wait_status_ptr_t;
+  */
+
+  /*
+pid_t wait (__wait_status_ptr_t __status);
+pid_t waitpid (pid_t __pid, __wait_status_ptr_t __status, int __options);
+pid_t wait3 (__wait_status_ptr_t __status, int __options, struct rusage *__rusage);
+pid_t wait4 (pid_t __pid, __wait_status_ptr_t __status, int __options, struct rusage *__rusage);
+  */
+
+  pid_t cygwin_wait (int * __status){
+    return wait ((__wait_status_ptr_t) __status);
+  }
+
+  pid_t cygwin_waitpid (pid_t __pid, int * __status, int __options){
+    return waitpid (__pid, (__wait_status_ptr_t) __status, __options);
+  }
+
+  pid_t cygwin_wait3 (int * __status, int __options, struct rusage *__rusage){
+    return wait3 ((__wait_status_ptr_t) __status, __options, __rusage);
+  }
+
+  pid_t cygwin_wait4 (pid_t __pid, int * __status, int __options, struct rusage *__rusage){
+    return wait4 (__pid, (__wait_status_ptr_t) __status, __options, __rusage);
+  }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pypy/translator/c/src/cygwin_wait.h b/pypy/translator/c/src/cygwin_wait.h
new file mode 100644
--- /dev/null
+++ b/pypy/translator/c/src/cygwin_wait.h
@@ -0,0 +1,43 @@
+/*
+  Work around compile error:
+  [translation:ERROR]     implement_4.c: In function 'pypy_g_ccall_waitpid__Signed_arrayPtr_Signed':
+  [translation:ERROR]     implement_4.c:150095:2: error: incompatible type for argument 2 of 'waitpid'
+  [translation:ERROR]     /usr/include/sys/wait.h:43:7: note: expected '__wait_status_ptr_t' but argument is of type 'long int *'
+*/
+
+#ifdef __CYGWIN__
+
+#ifndef _PYPY_WAIT_H
+#define _PYPY_WAIT_H
+
+#ifndef _SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /*
+typedef int *__wait_status_ptr_t;
+  */
+
+  /*
+pid_t wait (__wait_status_ptr_t __status);
+pid_t waitpid (pid_t __pid, __wait_status_ptr_t __status, int __options);
+pid_t wait3 (__wait_status_ptr_t __status, int __options, struct rusage *__rusage);
+pid_t wait4 (pid_t __pid, __wait_status_ptr_t __status, int __options, struct rusage *__rusage);
+  */
+
+  pid_t cygwin_wait (int * __status);
+  pid_t cygwin_waitpid (pid_t __pid, int * __status, int __options);
+  pid_t cygwin_wait3 (int * __status, int __options, struct rusage *__rusage);
+  pid_t cygwin_wait4 (pid_t __pid, int * __status, int __options, struct rusage *__rusage);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h
--- a/pypy/translator/c/src/g_include.h
+++ b/pypy/translator/c/src/g_include.h
@@ -61,3 +61,8 @@
 #    pragma warning(disable: 4033 4102 4101 4716)
 #  endif
 #endif
+
+/* work around waitpid expecting different pointer type */
+#ifdef __CYGWIN__
+#include "src/cygwin_wait.h"
+#endif
diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py
--- a/pypy/translator/platform/__init__.py
+++ b/pypy/translator/platform/__init__.py
@@ -278,6 +278,13 @@
         host_factory = Windows
     else:
         host_factory = Windows_x64
+elif sys.platform == 'cygwin':
+    from pypy.translator.platform.cygwin import Cygwin, Cygwin64
+    import platform
+    if platform.architecture()[0] == '32bit':
+        host_factory = Cygwin
+    else:
+        host_factory = Cygwin64
 else:
     # pray
     from pypy.translator.platform.distutils_platform import DistutilsPlatform
diff --git a/pypy/translator/platform/cygwin.py b/pypy/translator/platform/cygwin.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/platform/cygwin.py
@@ -0,0 +1,56 @@
+"""Support for Cygwin."""
+
+import os
+import sys
+from pypy.translator.platform.posix import BasePosix
+
+class BaseCygwin(BasePosix):
+    name = "cygwin"
+    
+#    link_flags = tuple(
+#                 ['-pthread',]
+#                 + os.environ.get('LDFLAGS', '').split())
+    link_flags = tuple(
+                 []
+                 + os.environ.get('LDFLAGS', '').split())
+    extra_libs = ('-lrt',)
+#    cflags = tuple(
+#             ['-O3', '-pthread', '-fomit-frame-pointer',
+#              '-Wall', '-Wno-unused']
+#             + os.environ.get('CFLAGS', '').split())
+    cflags = tuple(
+             ['-O3', '-fomit-frame-pointer',
+              '-Wall', '-Wno-unused']
+             + os.environ.get('CFLAGS', '').split())
+    standalone_only = ()
+    shared_only = ('-fPIC',)
+    so_ext = 'dll'
+    exe_ext = 'exe'
+    so_prefixes = ('lib', '')
+    
+    def _args_for_shared(self, args):
+        return ['-shared'] + args
+
+    def _include_dirs_for_libffi(self):
+        return self._pkg_config("libffi", "--cflags-only-I",
+                                ['/usr/include/libffi'])
+
+    def _library_dirs_for_libffi(self):
+        return self._pkg_config("libffi", "--libs-only-L",
+                                ['/usr/lib/libffi'])
+
+    def library_dirs_for_libffi_a(self):
+        # places where we need to look for libffi.a
+        # XXX obscuuure!  only look for libffi.a if run with translate.py
+        if 'translate' in sys.modules:
+            return self.library_dirs_for_libffi() + ['/usr/lib']
+        else:
+            return []
+
+
+class Cygwin(BaseCygwin):
+    shared_only = ()    # it seems that on 32-bit linux, compiling with -fPIC
+                        # gives assembler that asmgcc is not happy about.
+
+class Cygwin64(BaseCygwin):
+    pass
diff --git a/pypy/translator/platform/posix.py b/pypy/translator/platform/posix.py
--- a/pypy/translator/platform/posix.py
+++ b/pypy/translator/platform/posix.py
@@ -1,6 +1,6 @@
 """Base support for POSIX-like platforms."""
 
-import py, os
+import py, os, sys
 
 from pypy.tool import autopath
 from pypy.translator.platform import Platform, log, _run_subprocess
@@ -55,7 +55,8 @@
 
         if relto:
             response_file = relto.bestrelpath(response_file)
-        if self.cc == 'mingw32' or (self.cc== 'gcc' and os.name=='nt'):    
+        if (self.cc == 'mingw32' or (self.cc== 'gcc' and os.name=='nt')
+                or sys.platform == 'cygwin'):
             return ["-Wl,--export-all-symbols,--version-script=%s" % \
                     (response_file,)]
         return ["-Wl,--export-dynamic,--version-script=%s" % (response_file,)]


More information about the pypy-commit mailing list