Écrivez un script Ruby comme celui-ci [^ 1]
test.rb
require 'pycall/import'
puts "ok"
Une fois exécuté,
$ ruby test.rb
ImportError: No module named site
J'obtiens l'erreur.
Lors de l'installation de Python avec pyenv, spécifiez une option pour créer une bibliothèque partagée.
$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.6.1
Cela générera libpython3.6m.dylib sous ~ / .pyenv / versions / 3.6.1
. [^ 2]
$ cd $(pyenv prefix)
$ find . -name site.py
./lib/python3.6/site-packages/jedi/evaluate/site.py
./lib/python3.6/site.py
Il y a site.py. Je suppose que c'est juste que le chemin ne passe pas.
PYTHONPATH=$HOME/.pyenv/versions/3.6.1/lib/python3.6 ruby test.rb
File "/Users/cesare/.pyenv/versions/3.6.1/lib/python3.6/site.py", line 177
file=sys.stderr)
^
SyntaxError: invalid syntax
Le module a été trouvé avec succès, mais cette fois j'ai eu une erreur de syntaxe. Apparemment, je soupçonne que le système de traitement qui a chargé ce module n'est pas le système Python3.x.
J'ai regardé légèrement la source de PyCall et j'ai semblé utiliser FFI, donc je m'attendais à ce que le système de traitement soit probablement une bibliothèque partagée.
Sur Mac, l'extension des bibliothèques partagées est souvent .dylib, alors cherchons-la comme ceci.
$ find . -name '*.dylib'
./lib/python3.6/site-packages/matplotlib/.dylibs/libpng16.16.dylib
./lib/python3.6/site-packages/matplotlib/.dylibs/libz.1.2.10.dylib
./lib/python3.6/site-packages/scipy/.dylibs/libgcc_s.1.dylib
./lib/python3.6/site-packages/scipy/.dylibs/libgfortran.3.dylib
./lib/python3.6/site-packages/scipy/.dylibs/libquadmath.0.dylib
Certains sont sortis, mais ils sont différents car ils proviennent de packages installés plus tard.
Si vous regardez sous .pyenv / versions / 3.6.1 / lib
, vous pouvez voir que le fichier libpython3.6m.a roule, mais .a n'est pas une bibliothèque partagée et ce que vous recherchez n'est pas cela. Je suppose qu'il est probablement nécessaire qu'un fichier appelé libpython3.6m.dylib existe.
Quand j'ai récupéré la source du système de traitement Python et examiné l'option de configure
, j'ai trouvé qu'il semble que --enable-shared
puisse être spécifié. Il semble que vous puissiez utiliser la variable d'environnement CONFIGURE_OPTS
pour spécifier l'option de configure
lors de l'installation de pyenv.
Alors
$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.6.1
Cela a généré libpython3.6m.dylib. Lorsque je réexécute le script de test Ruby,
$ ruby test.rb
ok
Cela a fonctionné en toute sécurité.
Vous pouvez observer comment PyCall recherche libpython en utilisant la variable d'environnement DEBUG_FIND_LIBPYTHON
.
$ DEBUG_FIND_LIBPYTHON=1 ruby -e 'require "pycall"'
Ce faisant, les chemins recherchés seront répertoriés dans la sortie standard.
[^ 1]: J'ai obtenu ce code après avoir supprimé des éléments supplémentaires pour trouver la cause de l'erreur. Puisque "ok" n'apparaît pas dans la sortie standard, on peut voir qu'il s'agit de mousse avec "require'pycall / import".
[^ 2]: Lorsque --enable-shared
n'était pas spécifié, .dylib n'était pas généré et seul le fichier .a portant le même nom était placé.
Recommended Posts