Write a Ruby script like this [^ 1]
test.rb
require 'pycall/import'
puts "ok"
Once executed,
$ ruby test.rb
ImportError: No module named site
Error appears.
When installing Python with pyenv, specify an option to create a shared library.
$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.6.1
This will generate libpython3.6m.dylib under ~ / .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
There is site.py. I guess it's just that the path doesn't pass.
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
The module was successfully found, but this time I got a syntax error. Apparently, I suspect that the processing system that loaded this module is not Python3.x system.
I took a quick look at the PyCall source and seemed to be using FFI, so I expected the processing system to be a shared library.
On Mac, the extension of the shared library is often .dylib, so for the time being, try searching for it like this.
$ 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
There are some, but they are different because they are from packages that I installed later.
If you look under .pyenv / versions / 3.6.1 / lib
, you can see that the file libpython3.6m.a is rolling, but .a is not a shared library and what you are looking for is not this. I guess it's probably necessary that a file called libpython3.6m.dylib exists.
When I fetched the source of the Python processing system and examined the option of configure
, I found that it seems that --enable-shared
can be specified. It seems that you can use the environment variable CONFIGURE_OPTS
to specify the configure
option when installing pyenv.
So
$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.6.1
This generated libpython3.6m.dylib. When I rerun the test Ruby script,
$ ruby test.rb
ok
It worked safely.
You can observe PyCall looking for libpython using the environment variable DEBUG_FIND_LIBPYTHON
.
$ DEBUG_FIND_LIBPYTHON=1 ruby -e 'require "pycall"'
By doing so, the searched paths will be listed in the standard output.
[^ 1]: I got this code after cutting extra things to minimize it to find the cause of the error. Since "ok" does not appear in the standard output, it can be seen that it is moss with require'pycall / import'
.
[^ 2]: When --enable-shared
was not specified, .dylib was not generated and only .a files with the same name were placed.
Recommended Posts