Author: Armin Rigo <ar...@tunes.org> Branch: search-path-from-libpypy Changeset: r87363:cf88e0443153 Date: 2016-09-24 20:54 +0200 http://bitbucket.org/pypy/pypy/changeset/cf88e0443153/
Log: Search for the lib-python/lib_pypy directores starting from the libpypy-c.so location, instead of the pypy executable location. This is more consistent with what occurs in case of embedding. 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/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