DataDog / go-python3

Go bindings to the CPython-3 API
MIT License
376 stars 140 forks source link

How to wrap another Python after first install? #27

Open HelgeCPH opened 4 years ago

HelgeCPH commented 4 years ago

As far as I understand, when I build a binary that requires go-python3 then the resulting binary is linked dynamically to the Python that pkg-config found in the respective python3.pc file when installing go-python3 via go get. Is that right?

For example, I build a binary called gopython3, from your example program wrapping the entire interpreter. On MacOS otool displays the following for it:

$ otool -L gopython3
gopython3:
    /usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/Python (compatibility version 3.7.0, current version 3.7.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)

Now, I have two questions:

a) Is it possible to build a standalone binary that contains the Python interpreter directly?

My guess is, that this is not possible. I am still quite new to Golang and also not really experienced with all this building and linking stuff since I come from Python :) So, I read this article and -as suggested in it- I tried to build my gopython3 with the following, which does not work:

$ CGO_ENABLED=0 go build .
go build github.com/DataDog/go-python3: build constraints exclude all Go files in /Users/user/go/pkg/mod/github.com/!data!dog/go-python3@v0.0.0-20190130222855-0b25cc550560

But I do not really understand why it does not work. Could it be made to work and I am just doing something wrong or is it really impossible?

b) How to point to another interpreter after installing go-python3 for the first time?

Currently, I just did as suggested in your documentation. I made sure that I have pkg-config installed and I checked that I have a corresponding configuration file around. Actually, it seems as if I have multiple of these since I have multiple versions of Python installed (Some that were installed by Homebrew as dependencies of some other software and some seem to come from Anaconda, which I mainly use for Python development.):

$ locate python3.pc
/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/pkgconfig/python3.pc
/usr/local/Cellar/python/3.7.7/lib/pkgconfig/python3.pc
/usr/local/Cellar/python@3.8/3.8.2/Frameworks/Python.framework/Versions/3.8/lib/pkgconfig/python3.pc
/usr/local/Cellar/python@3.8/3.8.2/lib/pkgconfig/python3.pc
/usr/local/anaconda3/lib/pkgconfig/python3.pc
/usr/local/anaconda3/pkgs/python-3.6.5-hc167b69_1/lib/pkgconfig/python3.pc
/usr/local/anaconda3/pkgs/python-3.7.0-hc167b69_0/lib/pkgconfig/python3.pc
/usr/local/anaconda3/pkgs/python-3.7.3-h359304d_0/lib/pkgconfig/python3.pc
/usr/local/lib/pkgconfig/python3.pc

I am unsure which of the python3.pc files is actually selected by pkg-config. The output from otool suggests that it is the the first one, isn't it?

Since I understood that I cannot build a standalone program (see above), which statically links Python, I thought that I would like at least to not require the end-users of my program to install Python but instead ship my own Python together with my Go built binary. I took this Python: indygreg/python-build-standalone, built it, and it contains a corresponding .pc file under python-build-standalone/python/install/lib/pkgconfig.

Now, I would like to link go-python3 to this Python instead to the one reported by otool above. But I do not know how to do that properly.

I tried deleting go-python3 and reinstall it as in the following:

$ PKG_CONFIG_PATH=python-build-standalone/python/install/lib/pkgconfig  go get github.com/DataDog/go-python3@0.1.1
$ go build -a .

But my resulting gopython3 binary uses the same Python as before and not the one I intend to link. What am I doing wrong?

Thank you in advance for any hints!

HelgeCPH commented 4 years ago

Hi again, is it the wrong place to ask a question like the one above? If so, please let me know and just close the issue. However, I would really appreciate any help on the question if somebody knows something.