[pypy-commit] pypy search-path-from-libpypy: Search for the lib-python/lib_pypy directores starting from the

arigo pypy.commits at gmail.com
Sat Sep 24 14:58:49 EDT 2016


Author: Armin Rigo <arigo at 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))
 
 
- at unwrap_spec(executable='str0')
-def pypy_find_stdlib(space, executable):
+ at 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))


More information about the pypy-commit mailing list