Author: mattip <matti.pi...@gmail.com> Branch: fold-arith-ops Changeset: r77488:c754273874e0 Date: 2015-05-22 17:00 +0300 http://bitbucket.org/pypy/pypy/changeset/c754273874e0/
Log: document branch diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.0.0 +Version: 1.0.2 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,8 +4,8 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "1.0.0" -__version_info__ = (1, 0, 0) +__version__ = "1.0.2" +__version_info__ = (1, 0, 2) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h --- a/lib_pypy/cffi/_cffi_include.h +++ b/lib_pypy/cffi/_cffi_include.h @@ -1,3 +1,4 @@ +#define _CFFI_ #include <Python.h> #ifdef __cplusplus extern "C" { @@ -6,7 +7,8 @@ #include "parse_c_type.h" /* this block of #ifs should be kept exactly identical between - c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */ + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ #if defined(_MSC_VER) # include <malloc.h> /* for alloca() */ # if _MSC_VER < 1600 /* MSVC < 2010 */ diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -109,6 +109,11 @@ if override: for cache in self._function_caches: cache.clear() + finishlist = self._parser._recomplete + if finishlist: + self._parser._recomplete = [] + for tp in finishlist: + tp.finish_backend_type(self, finishlist) def dlopen(self, name, flags=0): """Load and return a dynamic library identified by 'name'. diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -101,6 +101,7 @@ self._override = False self._packed = False self._int_constants = {} + self._recomplete = [] def _parse(self, csource): csource, macros = _preprocess(csource) @@ -555,6 +556,9 @@ raise NotImplementedError("%s: using both bitfields and '...;'" % (tp,)) tp.packed = self._packed + if tp.completed: # must be re-completed: it is not opaque any more + tp.completed = 0 + self._recomplete.append(tp) return tp def _make_partial(self, tp, nested): @@ -604,19 +608,21 @@ def _build_enum_type(self, explicit_name, decls): if decls is not None: - enumerators1 = [enum.name for enum in decls.enumerators] - enumerators = [s for s in enumerators1 - if not _r_enum_dotdotdot.match(s)] - partial = len(enumerators) < len(enumerators1) - enumerators = tuple(enumerators) + partial = False + enumerators = [] enumvalues = [] nextenumvalue = 0 - for enum in decls.enumerators[:len(enumerators)]: + for enum in decls.enumerators: + if _r_enum_dotdotdot.match(enum.name): + partial = True + continue if enum.value is not None: nextenumvalue = self._parse_constant(enum.value) + enumerators.append(enum.name) enumvalues.append(nextenumvalue) self._add_constants(enum.name, nextenumvalue) nextenumvalue += 1 + enumerators = tuple(enumerators) enumvalues = tuple(enumvalues) tp = model.EnumType(explicit_name, enumerators, enumvalues) tp.partial = partial diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py --- a/lib_pypy/cffi/model.py +++ b/lib_pypy/cffi/model.py @@ -293,7 +293,7 @@ class StructOrUnion(StructOrUnionOrEnum): fixedlayout = None - completed = False + completed = 0 partial = False packed = False @@ -351,12 +351,13 @@ "for '%s'" % (self.name,)) return BType = ffi._cached_btypes[self] - if self.fldtypes is None: - return # not completing it: it's an opaque struct # self.completed = 1 # - if self.fixedlayout is None: + if self.fldtypes is None: + pass # not completing it: it's an opaque struct + # + elif self.fixedlayout is None: fldtypes = [tp.get_cached_btype(ffi, finishlist) for tp in self.fldtypes] lst = list(zip(self.fldnames, fldtypes, self.fldbitsize)) diff --git a/lib_pypy/cffi/parse_c_type.h b/lib_pypy/cffi/parse_c_type.h --- a/lib_pypy/cffi/parse_c_type.h +++ b/lib_pypy/cffi/parse_c_type.h @@ -1,5 +1,5 @@ -/* See doc/parse_c_type.rst in the source of CFFI for more information */ +/* See doc/misc/parse_c_type.rst in the source of CFFI for more information */ typedef void *_cffi_opcode_t; diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py --- a/lib_pypy/cffi/recompiler.py +++ b/lib_pypy/cffi/recompiler.py @@ -581,10 +581,11 @@ def _generate_cpy_function_collecttype(self, tp, name): self._do_collect_type(tp.as_raw_function()) - if tp.ellipsis: + if tp.ellipsis and not self.target_is_python: self._do_collect_type(tp) def _generate_cpy_function_decl(self, tp, name): + assert not self.target_is_python assert isinstance(tp, model.FunctionPtrType) if tp.ellipsis: # cannot support vararg functions better than this: check for its @@ -702,7 +703,7 @@ prnt() def _generate_cpy_function_ctx(self, tp, name): - if tp.ellipsis: + if tp.ellipsis and not self.target_is_python: self._generate_cpy_constant_ctx(tp, name) return type_index = self._typesdict[tp.as_raw_function()] diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py --- a/lib_pypy/cffi/setuptools_ext.py +++ b/lib_pypy/cffi/setuptools_ext.py @@ -76,7 +76,7 @@ from cffi import recompiler allsources = ['$PLACEHOLDER'] - allsources.extend(kwds.get('sources', [])) + allsources.extend(kwds.pop('sources', [])) ext = Extension(name=module_name, sources=allsources, **kwds) def make_mod(tmpdir): diff --git a/pypy/doc/sprint-reports.rst b/pypy/doc/sprint-reports.rst --- a/pypy/doc/sprint-reports.rst +++ b/pypy/doc/sprint-reports.rst @@ -1,4 +1,4 @@ -Sprint reports from PyPy sprints 2003-2006 +Sprint reports from PyPy sprints 2003-2010 ========================================== Here are links to sprint reports from various sprints in the PyPy project, diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-2.6.0.rst copy from pypy/doc/whatsnew-head.rst copy to pypy/doc/whatsnew-2.6.0.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-2.6.0.rst @@ -117,4 +117,17 @@ .. branch: cffi-1.0 +branch cffi-1.0 PyPy now includes CFFI 1.0. + +.. branch: pypyw + +branch pypyw +PyPy on windows provides a non-console pypyw.exe as well as pypy.exe. +Similar to pythonw.exe, any use of stdout, stderr without redirection +will crash. + +.. branch: fold-arith-ops + +branch fold-arith-ops +remove multiple adds on add chains ("1 + 1 + 1 + ...") diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -1,120 +1,8 @@ ======================= -What's new in PyPy 2.5+ +What's new in PyPy 2.6+ ======================= -.. this is a revision shortly after release-2.5.1 -.. startrev: cb01edcb59414d9d93056e54ed060673d24e67c1 +.. this is a revision shortly after release-2.6.0 +.. startrev: 4c5c81da93e2e3c9df6be64d9bd79c958144de55 -issue2005: -ignore errors on closing random file handles while importing a module (cpython compatibility) -issue2013: -added constants to _ssl for TLS 1.1 and 1.2 - -issue2014: -Add PyLong_FromUnicode to cpyext. - -issue2017: -On non-Linux-x86 platforms, reduced the memory impact of -creating a lot of greenlets/tasklets. Particularly useful on Win32 and -on ARM, where you used to get a MemoryError after only 2500-5000 -greenlets (the 32-bit address space is exhausted). - -Update gdb_pypy for python3 (gdb comatability) - -Merged rstrategies into rpython which provides a library for Storage Strategies - -Support unicode strings in numpy.dtype creation i.e. np.dtype(u'int64') - -Various rpython cleanups for vmprof support - -issue2019: -Fix isspace as called by rpython unicode.strip() - -issue2023: -In the cpyext 'Concrete Object Layer' API, -don't call methods on the object (which can be overriden), -but directly on the concrete base type. - -issue2029: -Hide the default_factory attribute in a dict - -issue2027: -Better document pyinteractive and add --withmod-time - -.. branch: gc-incminimark-pinning-improve - -branch gc-incminimark-pinning-improve: -Object Pinning is now used in `bz2` and `rzlib` (therefore also affects -Python's `zlib`). In case the data to compress/decompress is inside the nursery -(incminimark) it no longer needs to create a non-moving copy of it. This saves -one `malloc` and copying the data. Additionally a new GC environment variable -is introduced (`PYPY_GC_MAX_PINNED`) primarily for debugging purposes. - -.. branch: refactor-pycall - -branch refactor-pycall: -Make `*`-unpacking in RPython function calls completely equivalent to passing -the tuple's elements as arguments. In other words, `f(*(a, b))` now behaves -exactly like `f(a, b)`. - -.. branch: issue2018 - -branch issue2018: -Allow prebuilt rpython dict with function values - -.. branch: vmprof -.. Merged but then backed out, hopefully it will return as vmprof2 - -.. branch: object-dtype2 - -branch object-dtype2: -Extend numpy dtypes to allow using objects with associated garbage collection hook - -.. branch: vmprof2 - -branch vmprof2: -Add backend support for vmprof - a lightweight statistical profiler - -to linux64, see client at https://vmprof.readthedocs.org - -.. branch: jit_hint_docs - -branch jit_hint_docs: -Add more detail to @jit.elidable and @jit.promote in rpython/rlib/jit.py - -.. branch: remove-frame-debug-attrs - -branch remove_frame-debug-attrs: -Remove the debug attributes from frames only used for tracing and replace -them with a debug object that is created on-demand - -.. branch: can_cast - -branch can_cast: -Implement np.can_cast, np.min_scalar_type and missing dtype comparison operations. - -.. branch: numpy-fixes - -branch numpy-fixes: -Fix some error related to object dtype, non-contiguous arrays, inplement parts of -__array_interface__, __array_priority__, __array_wrap__ - -.. branch: cells-local-stack - -branch cells-local-stack: -Unify the PyFrame.cells and Pyframe.locals_stack_w lists, making frame objects -1 or 3 words smaller. - -.. branch: pythonoptimize-env - -branch pythonoptimize-env -Implement PYTHONOPTIMIZE environment variable, fixing issue #2044 - -.. branch: numpy-flags - -branch numpy-flags -Finish implementation of ndarray.flags, including str() and repr() - -.. branch: cffi-1.0 - -PyPy now includes CFFI 1.0. diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -2,7 +2,7 @@ from pypy.interpreter.mixedmodule import MixedModule from rpython.rlib import rdynload -VERSION = "1.0.0" +VERSION = "1.0.2" class Module(MixedModule): diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -3335,4 +3335,4 @@ def test_version(): # this test is here mostly for PyPy - assert __version__ == "1.0.0" + assert __version__ == "1.0.2" diff --git a/pypy/module/cpyext/include/patchlevel.h b/pypy/module/cpyext/include/patchlevel.h --- a/pypy/module/cpyext/include/patchlevel.h +++ b/pypy/module/cpyext/include/patchlevel.h @@ -29,7 +29,7 @@ #define PY_VERSION "2.7.9" /* PyPy version as a string */ -#define PYPY_VERSION "2.6.0-alpha0" +#define PYPY_VERSION "2.7.0-alpha0" /* Subversion Revision number of this file (not of the repository). * Empty since Mercurial migration. */ diff --git a/pypy/module/cpyext/include/pyconfig.h b/pypy/module/cpyext/include/pyconfig.h --- a/pypy/module/cpyext/include/pyconfig.h +++ b/pypy/module/cpyext/include/pyconfig.h @@ -28,7 +28,7 @@ #endif #ifndef Py_BUILD_CORE /* not building the core - must be an ext */ -# if defined(_MSC_VER) +# if defined(_MSC_VER) && !defined(_CFFI_) /* So MSVC users need not specify the .lib file in * their Makefile (other compilers are generally * taken care of by distutils.) */ diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py --- a/pypy/module/sys/version.py +++ b/pypy/module/sys/version.py @@ -10,7 +10,7 @@ #XXX # sync CPYTHON_VERSION with patchlevel.h, package.py CPYTHON_API_VERSION = 1013 #XXX # sync with include/modsupport.h -PYPY_VERSION = (2, 6, 0, "alpha", 0) #XXX # sync patchlevel.h +PYPY_VERSION = (2, 7, 0, "alpha", 0) #XXX # sync patchlevel.h if platform.name == 'msvc': COMPILER_INFO = 'MSC v.%d 32 bit' % (platform.version * 10 + 600) diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py @@ -1704,3 +1704,13 @@ assert lib.DOT_HEX == 0x100 assert lib.DOT_HEX2 == 0x10 assert lib.DOT_UL == 1000 + + def test_opaque_struct_becomes_nonopaque(self): + # Issue #193: if we use a struct between the first cdef() where it is + # declared and another cdef() where its fields are defined, then the + # definition was ignored. + ffi = FFI(backend=self.Backend()) + ffi.cdef("struct foo_s;") + py.test.raises(TypeError, ffi.new, "struct foo_s *") + ffi.cdef("struct foo_s { int x; };") + ffi.new("struct foo_s *") diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py @@ -765,6 +765,11 @@ assert ffi.string(ffi.cast('enum ee2', -1239)) == 'EE4' assert ffi.string(ffi.cast('enum ee2', -1238)) == 'EE5' +def test_nonfull_enum_bug3(): + ffi = FFI() + ffi.cdef("enum ee2 { EE4=..., EE5=... };") + ffi.cdef("enum ee6 { EE7=10, EE8=..., EE9=... };") + def test_get_set_errno(): ffi = FFI() ffi.cdef("int foo(int);") diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py @@ -13,6 +13,7 @@ #define BIGPOS 420000000000L #define BIGNEG -420000000000L int add42(int x) { return x + 42; } + int add43(int x, ...) { return x; } int globalvar42 = 1234; struct foo_s; typedef struct bar_s { int x; signed char a[]; } bar_t; @@ -38,6 +39,7 @@ #define BIGPOS 420000000000L #define BIGNEG -420000000000L int add42(int); + int add43(int, ...); int globalvar42; int no_such_function(int); int no_such_globalvar; @@ -69,6 +71,13 @@ assert lib.add42(-10) == 32 assert type(lib.add42) is _cffi_backend.FFI.CData +def test_function_with_varargs(): + import _cffi_backend + from re_python_pysrc import ffi + lib = ffi.dlopen(extmod) + assert lib.add43(45, ffi.cast("int", -5)) == 45 + assert type(lib.add43) is _cffi_backend.FFI.CData + def test_dlclose(): import _cffi_backend from re_python_pysrc import ffi diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py @@ -762,3 +762,18 @@ py.test.raises(AttributeError, ffi.addressof, lib, 'unknown_var') py.test.raises(AttributeError, ffi.addressof, lib, "FOOBAR") assert ffi.addressof(lib, 'FetchRectBottom') == lib.FetchRectBottom + +def test_defines__CFFI_(): + # Check that we define the macro _CFFI_ automatically. + # It should be done before including Python.h, so that PyPy's Python.h + # can check for it. + ffi = FFI() + ffi.cdef(""" + #define CORRECT 1 + """) + lib = verify(ffi, "test_defines__CFFI_", """ + #ifdef _CFFI_ + # define CORRECT 1 + #endif + """) + assert lib.CORRECT == 1 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 @@ -50,16 +50,23 @@ os.system("chmod -R g-w %s" % dirname) +cffi_build_scripts = { + "sqlite3": "_sqlite3_build.py", + "audioop": "_audioop_build.py", + "tk": "_tkinter/tklib_build.py", + "curses": "_curses_build.py" if sys.platform != "win32" else None, + "syslog": "_syslog_build.py" if sys.platform != "win32" else None, + "gdbm": "_gdbm_build.py" if sys.platform != "win32" else None, + "pwdgrp": "_pwdgrp_build.py" if sys.platform != "win32" else None, + "xx": None, # for testing: 'None' should be completely ignored + } + def create_cffi_import_libraries(pypy_c, options, basedir): shutil.rmtree(str(basedir.join('lib_pypy', '__pycache__')), ignore_errors=True) - modules = ['_sqlite3_build.py', '_audioop_build.py'] - if not sys.platform == 'win32': - modules += ['_curses_build.py', '_syslog_build.py', '_gdbm_build.py', - '_pwdgrp_build.py'] - if not options.no_tk: - modules.append('_tkinter/tklib_build.py') - for module in modules: + for key, module in sorted(cffi_build_scripts.items()): + if module is None or getattr(options, 'no_' + key): + continue if module.endswith('.py'): args = [str(pypy_c), module] cwd = str(basedir.join('lib_pypy')) @@ -70,9 +77,9 @@ try: subprocess.check_call(args, cwd=cwd) except subprocess.CalledProcessError: - print >>sys.stderr, """Building {0} bindings failed. + print >>sys.stderr, """!!!!!!!!!!\nBuilding {0} bindings failed. You can either install development headers package or -add --without-{0} option to skip packaging binary CFFI extension.""".format(module) +add --without-{0} option to skip packaging this binary CFFI extension.""".format(key) raise MissingDependenciesError(module) def pypy_runs(pypy_c, quiet=False): @@ -109,8 +116,7 @@ try: create_cffi_import_libraries(pypy_c, options, basedir) except MissingDependenciesError: - # This is a non-fatal error - retval = -1 + return 1, None if sys.platform == 'win32' and not rename_pypy_c.lower().endswith('.exe'): rename_pypy_c += '.exe' @@ -142,6 +148,12 @@ pypydir.ensure('include', dir=True) if sys.platform == 'win32': + src,tgt = binaries[0] + pypyw = src.new(purebasename=src.purebasename + 'w') + if pypyw.exists(): + tgt = py.path.local(tgt) + binaries.append((pypyw, tgt.new(purebasename=tgt.purebasename + 'w').basename)) + print "Picking %s" % str(pypyw) # Can't rename a DLL: it is always called 'libpypy-c.dll' win_extras = ['libpypy-c.dll', 'sqlite3.dll'] if not options.no_tk: @@ -274,11 +286,18 @@ pypy_exe = 'pypy' parser = argparse.ArgumentParser() args = list(args) - args[0] = str(args[0]) - parser.add_argument('--without-tk', dest='no_tk', action='store_true', - help='build and package the cffi tkinter module') + if args: + args[0] = str(args[0]) + else: + args.append('--help') + for key, module in sorted(cffi_build_scripts.items()): + if module is not None: + parser.add_argument('--without-' + key, + dest='no_' + key, + action='store_true', + help='do not build and package the %r cffi module' % (key,)) parser.add_argument('--without-cffi', dest='no_cffi', action='store_true', - help='do not pre-import any cffi modules') + help='skip building *all* the cffi modules listed above') parser.add_argument('--nostrip', dest='nostrip', action='store_true', help='do not strip the exe, making it ~10MB larger') parser.add_argument('--rename_pypy_c', dest='pypy_c', type=str, default=pypy_exe, diff --git a/pypy/tool/release/test/test_package.py b/pypy/tool/release/test/test_package.py --- a/pypy/tool/release/test/test_package.py +++ b/pypy/tool/release/test/test_package.py @@ -1,7 +1,7 @@ import py from pypy.conftest import pypydir -from pypy.tool.release import package, package +from pypy.tool.release import package from pypy.module.sys.version import CPYTHON_VERSION import tarfile, zipfile, sys @@ -32,8 +32,9 @@ else: fake_pypy_c = False try: - retval, builddir = package.package(py.path.local(pypydir).dirpath(), test, - rename_pypy_c) + retval, builddir = package.package( + '--without-cffi', str(py.path.local(pypydir).dirpath()), + test, rename_pypy_c) assert retval == 0 prefix = builddir.join(test) cpyver = '%d.%d' % CPYTHON_VERSION[:2] diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py --- a/rpython/rlib/rdynload.py +++ b/rpython/rlib/rdynload.py @@ -152,9 +152,9 @@ def dlclose(handle): res = rwin32.FreeLibrary(handle) if res: - return -1 + return 0 # success else: - return 0 + return -1 # error def dlsym(handle, name): res = rwin32.GetProcAddress(handle, name) diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -293,7 +293,7 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) - def cmdexec(self, args='', env=None, err=False, expect_crash=False): + def cmdexec(self, args='', env=None, err=False, expect_crash=False, exe=None): assert self._compiled if sys.platform == 'win32': #Prevent opening a dialog box @@ -314,9 +314,10 @@ envrepr = '' else: envrepr = ' [env=%r]' % (env,) - log.cmdexec('%s %s%s' % (self.executable_name, args, envrepr)) - res = self.translator.platform.execute(self.executable_name, args, - env=env) + if exe is None: + exe = self.executable_name + log.cmdexec('%s %s%s' % (exe, args, envrepr)) + res = self.translator.platform.execute(exe, args, env=env) if sys.platform == 'win32': SetErrorMode(old_mode) if res.returncode != 0: diff --git a/rpython/translator/c/test/test_standalone.py b/rpython/translator/c/test/test_standalone.py --- a/rpython/translator/c/test/test_standalone.py +++ b/rpython/translator/c/test/test_standalone.py @@ -845,6 +845,13 @@ #Do not set LD_LIBRARY_PATH, make sure $ORIGIN flag is working out, err = cbuilder.cmdexec("a b") assert out == "3" + if sys.platform == 'win32': + # Make sure we have a test_1w.exe + # Since stdout, stderr are piped, we will get output + exe = cbuilder.executable_name + wexe = exe.new(purebasename=exe.purebasename + 'w') + out, err = cbuilder.cmdexec("a b", exe = wexe) + assert out == "3" def test_gcc_options(self): # check that the env var CC is correctly interpreted, even if diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -458,11 +458,14 @@ shutil_copy(str(fname), str(dstname)) self.log.info('Static data info written to %s' % dstname) - def compute_exe_name(self): + def compute_exe_name(self, suffix=''): newexename = self.exe_name % self.get_info() if '/' not in newexename and '\\' not in newexename: newexename = './' + newexename - return py.path.local(newexename) + newname = py.path.local(newexename) + if suffix: + newname = newname.new(purebasename = newname.purebasename + suffix) + return newname def create_exe(self): """ Copy the compiled executable into current directory, which is @@ -478,6 +481,11 @@ shutil_copy(str(soname), str(newsoname)) self.log.info("copied: %s" % (newsoname,)) if sys.platform == 'win32': + # Copy pypyw.exe + newexename = mkexename(self.compute_exe_name(suffix='w')) + exe = py.path.local(exename) + exename = exe.new(purebasename=exe.purebasename + 'w') + shutil_copy(str(exename), str(newexename)) # the import library is named python27.lib, according # to the pragma in pyconfig.h libname = str(newsoname.dirpath().join('python27.lib')) diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -260,6 +260,8 @@ if shared: so_name = exe_name.new(purebasename='lib' + exe_name.purebasename, ext=self.so_ext) + wtarget_name = exe_name.new(purebasename=exe_name.purebasename + 'w', + ext=self.exe_ext) target_name = so_name.basename else: target_name = exe_name.basename @@ -313,11 +315,13 @@ ('MAKE', 'nmake.exe'), ('_WIN32', '1'), ] + if shared: + definitions.insert(0, ('WTARGET', wtarget_name.basename)) if self.x64: definitions.append(('_WIN64', '1')) rules = [ - ('all', '$(DEFAULT_TARGET)', []), + ('all', '$(DEFAULT_TARGET) $(WTARGET)', []), ('.asm.obj', '', '$(MASM) /nologo /Fo$@ /c $< $(INCLUDEDIRS)'), ] @@ -411,14 +415,33 @@ 'int main(int argc, char* argv[]) ' '{ return $(PYPY_MAIN_FUNCTION)(argc, argv); } > $@') deps = ['main.obj'] + m.rule('wmain.c', '', + ['echo #define WIN32_LEAN_AND_MEAN > $@', + 'echo #include "windows.h" >> $@', + 'echo int $(PYPY_MAIN_FUNCTION)(int, char*[]); >> $@', + 'echo int WINAPI WinMain( >> $@', + 'echo HINSTANCE hInstance, /* handle to current instance */ >> $@', + 'echo HINSTANCE hPrevInstance, /* handle to previous instance */ >> $@', + 'echo LPSTR lpCmdLine, /* pointer to command line */ >> $@', + 'echo int nCmdShow /* show state of window */ >> $@', + 'echo ) >> $@', + 'echo { return $(PYPY_MAIN_FUNCTION)(__argc, __argv); } >> $@']) + wdeps = ['wmain.obj'] if icon: deps.append('icon.res') + wdeps.append('icon.res') m.rule('$(DEFAULT_TARGET)', ['$(TARGET)'] + deps, ['$(CC_LINK) /nologo /debug %s ' % (' '.join(deps),) + \ '$(SHARED_IMPORT_LIB) /out:$@ ' + \ '/MANIFEST /MANIFESTFILE:$*.manifest', 'mt.exe -nologo -manifest $*.manifest -outputresource:$@;1', ]) + m.rule('$(WTARGET)', ['$(TARGET)'] + wdeps, + ['$(CC_LINK) /nologo /debug /SUBSYSTEM:WINDOWS %s ' % (' '.join(wdeps),) + \ + '$(SHARED_IMPORT_LIB) /out:$@ ' + \ + '/MANIFEST /MANIFESTFILE:$*.manifest', + 'mt.exe -nologo -manifest $*.manifest -outputresource:$@;1', + ]) m.rule('debugmode_$(DEFAULT_TARGET)', ['debugmode_$(TARGET)']+deps, ['$(CC_LINK) /nologo /DEBUG %s ' % (' '.join(deps),) + \ 'debugmode_$(SHARED_IMPORT_LIB) /out:$@', diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -53,17 +53,21 @@ dst_name = udir.join('dst/pypy.exe') src_name = udir.join('src/dydy2.exe') + wsrc_name = udir.join('src/dydy2w.exe') dll_name = udir.join('src/pypy.dll') lib_name = udir.join('src/pypy.lib') pdb_name = udir.join('src/pypy.pdb') src_name.ensure() src_name.write('exe') + wsrc_name.ensure() + wsrc_name.write('wexe') dll_name.ensure() dll_name.write('dll') lib_name.ensure() lib_name.write('lib') pdb_name.ensure() pdb_name.write('pdb') + # Create the dst directory dst_name.ensure() class CBuilder(object): @@ -76,6 +80,7 @@ assert dst_name.read() == 'exe' assert dst_name.new(ext='dll').read() == 'dll' assert dst_name.new(purebasename='python27',ext='lib').read() == 'lib' + assert dst_name.new(purebasename=dst_name.purebasename + 'w').read() == 'wexe' def test_shutil_copy(): if os.name == 'nt': _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit