Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r87366:dc3eb3eaa65c Date: 2016-09-24 22:14 +0200 http://bitbucket.org/pypy/pypy/changeset/dc3eb3eaa65c/
Log: hg merge search-path-from-libpypy The compiled pypy-c now looks for its lib-python/lib_pypy path starting from the location of the *libpypy-c* instead of the executable. This is arguably more consistent, and also it is what occurs anyway if you're embedding pypy. diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -89,17 +89,20 @@ def pypy_setup_home(ll_home, verbose): from pypy.module.sys.initpath import pypy_find_stdlib verbose = rffi.cast(lltype.Signed, verbose) - if ll_home: + if ll_home and ord(ll_home[0]): home1 = rffi.charp2str(ll_home) home = os.path.join(home1, 'x') # <- so that 'll_home' can be # directly the root directory + dynamic = False else: - home = home1 = pypydir - w_path = pypy_find_stdlib(space, home) + home1 = "pypy's shared library location" + home = pypydir + dynamic = True + w_path = pypy_find_stdlib(space, home, dynamic) if space.is_none(w_path): if verbose: debug("pypy_setup_home: directories 'lib-python' and 'lib_pypy'" - " not found in '%s' or in any parent directory" % home1) + " not found in %s or in any parent directory" % home1) return rffi.cast(rffi.INT, 1) space.startup() space.appexec([w_path], """(path): diff --git a/pypy/interpreter/test/test_app_main.py b/pypy/interpreter/test/test_app_main.py --- a/pypy/interpreter/test/test_app_main.py +++ b/pypy/interpreter/test/test_app_main.py @@ -1019,23 +1019,32 @@ old_sys_path = sys.path[:] old_cwd = os.getcwd() - sys.path.append(self.goal_dir) # make sure cwd does not contain a stdlib if self.tmp_dir.startswith(self.trunkdir): skip('TMPDIR is inside the PyPy source') - os.chdir(self.tmp_dir) + sys.path.append(self.goal_dir) tmp_pypy_c = os.path.join(self.tmp_dir, 'pypy-c') try: + os.chdir(self.tmp_dir) + + # If we are running PyPy with a libpypy-c, the following + # lines find the stdlib anyway. Otherwise, it is not found. + expected_found = ( + '__pypy__' in sys.builtin_module_names and + sys.pypy_translation_info['translation.shared']) + import app_main - app_main.setup_bootstrap_path(tmp_pypy_c) # stdlib not found + app_main.setup_bootstrap_path(tmp_pypy_c) assert sys.executable == '' - assert sys.path == old_sys_path + [self.goal_dir] + if not expected_found: + assert sys.path == old_sys_path + [self.goal_dir] app_main.setup_bootstrap_path(self.fake_exe) if not sys.platform == 'win32': # an existing file is always 'executable' on windows assert sys.executable == '' # not executable! - assert sys.path == old_sys_path + [self.goal_dir] + if not expected_found: + assert sys.path == old_sys_path + [self.goal_dir] os.chmod(self.fake_exe, 0755) app_main.setup_bootstrap_path(self.fake_exe) @@ -1046,7 +1055,8 @@ if newpath[0].endswith('__extensions__'): newpath = newpath[1:] # we get at least 'expected_path', and maybe more (e.g.plat-linux2) - assert newpath[:len(self.expected_path)] == self.expected_path + if not expected_found: + assert newpath[:len(self.expected_path)] == self.expected_path finally: sys.path[:] = old_sys_path os.chdir(old_cwd) diff --git a/pypy/module/_cffi_backend/embedding.py b/pypy/module/_cffi_backend/embedding.py --- a/pypy/module/_cffi_backend/embedding.py +++ b/pypy/module/_cffi_backend/embedding.py @@ -112,29 +112,7 @@ #define _WIN32_WINNT 0x0501 #include <windows.h> -#define CFFI_INIT_HOME_PATH_MAX _MAX_PATH static void _cffi_init(void); -static void _cffi_init_error(const char *msg, const char *extra); - -static int _cffi_init_home(char *output_home_path) -{ - HMODULE hModule = 0; - DWORD res; - - GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCTSTR)&_cffi_init, &hModule); - - if (hModule == 0 ) { - _cffi_init_error("GetModuleHandleEx() failed", ""); - return -1; - } - res = GetModuleFileName(hModule, output_home_path, CFFI_INIT_HOME_PATH_MAX); - if (res >= CFFI_INIT_HOME_PATH_MAX) { - return -1; - } - return 0; -} static void _cffi_init_once(void) { @@ -155,28 +133,9 @@ else: do_includes = r""" -#include <dlfcn.h> #include <pthread.h> -#define CFFI_INIT_HOME_PATH_MAX PATH_MAX static void _cffi_init(void); -static void _cffi_init_error(const char *msg, const char *extra); - -static int _cffi_init_home(char *output_home_path) -{ - Dl_info info; - dlerror(); /* reset */ - if (dladdr(&_cffi_init, &info) == 0) { - _cffi_init_error("dladdr() failed: ", dlerror()); - return -1; - } - if (realpath(info.dli_fname, output_home_path) == NULL) { - perror("realpath() failed"); - _cffi_init_error("realpath() failed", ""); - return -1; - } - return 0; -} static void _cffi_init_once(void) { @@ -201,14 +160,10 @@ static void _cffi_init(void) { - char home[CFFI_INIT_HOME_PATH_MAX + 1]; - rpython_startup_code(); RPyGilAllocate(); - if (_cffi_init_home(home) != 0) - return; - if (pypy_setup_home(home, 1) != 0) { + if (pypy_setup_home(NULL, 1) != 0) { _cffi_init_error("pypy_setup_home() failed", ""); return; } diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py --- a/pypy/module/sys/initpath.py +++ b/pypy/module/sys/initpath.py @@ -9,6 +9,8 @@ from rpython.rlib import rpath from rpython.rlib.objectmodel import we_are_translated +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.translator.tool.cbuild import ExternalCompilationInfo from pypy.interpreter.gateway import unwrap_spec from pypy.module.sys.state import get as get_state @@ -155,8 +157,13 @@ return space.wrap(resolvedirof(filename)) -@unwrap_spec(executable='str0') -def pypy_find_stdlib(space, executable): +@unwrap_spec(executable='str0', dynamic=int) +def pypy_find_stdlib(space, executable, dynamic=1): + if dynamic and space.config.translation.shared: + dynamic_location = pypy_init_home() + if dynamic_location: + executable = rffi.charp2str(dynamic_location) + pypy_init_free(dynamic_location) path, prefix = find_stdlib(get_state(space), executable) if path is None: return space.w_None @@ -164,3 +171,75 @@ space.setitem(space.sys.w_dict, space.wrap('prefix'), w_prefix) space.setitem(space.sys.w_dict, space.wrap('exec_prefix'), w_prefix) return space.newlist([space.wrap(p) for p in path]) + + +# ____________________________________________________________ + + +if os.name == 'nt': + + _source_code = r""" +#define _WIN32_WINNT 0x0501 +#include <windows.h> +#include <stdio.h> + +RPY_EXPORTED +char *_pypy_init_home(void) +{ + HMODULE hModule = 0; + DWORD res; + char *p; + + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)&_pypy_init_home, &hModule); + + if (hModule == 0 ) { + fprintf(stderr, "PyPy initialization: GetModuleHandleEx() failed\n"); + return NULL; + } + p = malloc(_MAX_PATH); + if (p == NULL) + return NULL; + res = GetModuleFileName(hModule, p, _MAX_PATH); + if (res >= _MAX_PATH || res <= 0) { + free(p); + fprintf(stderr, "PyPy initialization: GetModuleFileName() failed\n"); + return NULL; + } + return p; +} +""" + +else: + + _source_code = r""" +#include <dlfcn.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +RPY_EXPORTED +char *_pypy_init_home(void) +{ + Dl_info info; + dlerror(); /* reset */ + if (dladdr(&_pypy_init_home, &info) == 0) { + fprintf(stderr, "PyPy initialization: dladdr() failed: %s\n", + dlerror()); + return NULL; + } + char *p = realpath(info.dli_fname, NULL); + if (p == NULL) { + p = strdup(info.dli_fname); + } + return p; +} +""" + +_eci = ExternalCompilationInfo(separate_module_sources=[_source_code]) + +pypy_init_home = rffi.llexternal("_pypy_init_home", [], rffi.CCHARP, + _nowrapper=True, compilation_info=_eci) +pypy_init_free = rffi.llexternal("free", [rffi.CCHARP], lltype.Void, + _nowrapper=True, compilation_info=_eci) diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py --- a/pypy/module/sys/test/test_initpath.py +++ b/pypy/module/sys/test/test_initpath.py @@ -1,8 +1,10 @@ import py import os.path -from pypy.module.sys.initpath import (compute_stdlib_path, find_executable, find_stdlib, - resolvedirof) +from pypy.module.sys.initpath import (compute_stdlib_path, find_executable, + find_stdlib, resolvedirof, + pypy_init_home, pypy_init_free) from pypy.module.sys.version import PYPY_VERSION, CPYTHON_VERSION +from rpython.rtyper.lltypesystem import rffi def build_hierarchy(prefix): dirname = '%d.%d' % CPYTHON_VERSION[:2] @@ -10,7 +12,7 @@ b = prefix.join('lib-python', dirname).ensure(dir=1) return a, b -def test_find_stdlib(tmpdir, monkeypatch): +def test_find_stdlib(tmpdir): bin_dir = tmpdir.join('bin').ensure(dir=True) pypy = bin_dir.join('pypy').ensure(file=True) build_hierarchy(tmpdir) @@ -33,6 +35,14 @@ path, prefix = find_stdlib(None, str(pypy_sym)) assert prefix == pypydir +def test_pypy_init_home(): + p = pypy_init_home() + assert p + s = rffi.charp2str(p) + pypy_init_free(p) + print s + assert os.path.exists(s) + def test_compute_stdlib_path(tmpdir): dirs = build_hierarchy(tmpdir) path = compute_stdlib_path(None, str(tmpdir)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit