使用go-python3库时出现许多未定义的引用。

huangapple go评论111阅读模式
英文:

Many undefined references when using go-python3 library

问题

描述发生了什么事:

为了背景,我目前正在尝试将Python嵌入到Golang中。我遇到了这个模块go-python3,决定使用它。我最初使用的是python3.7版本的模块,然后决定将我的python版本从3.7升级到3.8。

阅读:https://github.com/go-python/cpy3/issues/29#issuecomment-1321199010

我将pkgconfig中的python3.pc替换为python-3.8.pc,然后在尝试运行时出现以下错误:

protoc -Isrc/proto --go_opt=module=grpc-golang --go_out=. --go-grpc_opt=module=grpc-golang --go-grpc_out=. src/proto/*.proto
go build -o dest/server ./src/server && PYTHONPATH=.
# grpc-golang/src/server
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x78): undefined reference to `PyBool_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x80): undefined reference to `PyByteArray_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x88): undefined reference to `PyBytes_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x90): undefined reference to `PyComplex_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x98): undefined reference to `PyDict_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xa0): undefined reference to `PyExc_ArithmeticError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xa8): undefined reference to `PyExc_AssertionError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xb0): undefined reference to `PyExc_AttributeError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xb8): undefined reference to `PyExc_BaseException'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xc0): undefined reference to `PyExc_BlockingIOError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xc8): undefined reference to `PyExc_BrokenPipeError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xd0): undefined reference to `PyExc_BufferError'
:

这些是一些细节:

>> python3 --version
3.8.10
>> pkg-config --cflags --libs python3
-I/usr/include/python3.8 -I/usr/include/x86_64-linux-gnu/python3.8
>> echo $PKG_CONFIG_PATH
/usr/lib/x86_64-linux-gnu/pkgconfig/
>> pkg-config --list-all
python-3.8       Python - Build a C extension for Python
zlib             zlib - zlib compression library
protobuf-lite    Protocol Buffers - Google's Data Interchange Format
bash-completion  bash-completion - programmable completion for the bash shell
xkeyboard-config XKeyboardConfig - X Keyboard configuration data
protobuf         Protocol Buffers - Google's Data Interchange Format
systemd          systemd - systemd System and Service Manager
libdmmp          libdmmp - Device mapper multipath management library
python3          Python - Build a C extension for Python
libxcrypt        libxcrypt - Extended crypt library for DES, MD5, Blowfish and others
udev             udev - udev
shared-mime-info shared-mime-info - Freedesktop common MIME database
python-3.8-embed Python - Embed Python into an application
expat            expat - expat XML parser
python3-embed    Python - Embed Python into an application
libcrypt         libxcrypt - Extended crypt library for DES, MD5, Blowfish and others

描述你的期望:

应该能够正常工作,就像它的3.7版本一样。

英文:

Describe what happened:

For context, i am currently trying to embed python into golang. I came across this module go-python3 and decided to use it. I was originally using the python3.7 variant of the module then decided to upgrade my python version from 3.7 to 3.8.

Read: https://github.com/go-python/cpy3/issues/29#issuecomment-1321199010

I replaced python3.pc in pkgconfig with python-3.8.pc and got the following error when trying to run:

protoc -Isrc/proto --go_opt=module=grpc-golang --go_out=. --go-grpc_opt=module=grpc-golang --go-grpc_out=. src/proto/*.proto
go build -o dest/server ./src/server && PYTHONPATH=.
# grpc-golang/src/server
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x78): undefined reference to `PyBool_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x80): undefined reference to `PyByteArray_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x88): undefined reference to `PyBytes_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x90): undefined reference to `PyComplex_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x98): undefined reference to `PyDict_Type'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xa0): undefined reference to `PyExc_ArithmeticError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xa8): undefined reference to `PyExc_AssertionError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xb0): undefined reference to `PyExc_AttributeError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xb8): undefined reference to `PyExc_BaseException'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xc0): undefined reference to `PyExc_BlockingIOError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xc8): undefined reference to `PyExc_BrokenPipeError'
/usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xd0): undefined reference to `PyExc_BufferError'
:

This are some of the details:

>> python3 --version
3.8.10
>> pkg-config --cflags --libs python3
-I/usr/include/python3.8 -I/usr/include/x86_64-linux-gnu/python3.8
>> echo $PKG_CONFIG_PATH
/usr/lib/x86_64-linux-gnu/pkgconfig/
>> pkg-config --list-all
python-3.8       Python - Build a C extension for Python
zlib             zlib - zlib compression library
protobuf-lite    Protocol Buffers - Google's Data Interchange Format
bash-completion  bash-completion - programmable completion for the bash shell
xkeyboard-config XKeyboardConfig - X Keyboard configuration data
protobuf         Protocol Buffers - Google's Data Interchange Format
systemd          systemd - systemd System and Service Manager
libdmmp          libdmmp - Device mapper multipath management library
python3          Python - Build a C extension for Python
libxcrypt        libxcrypt - Extended crypt library for DES, MD5, Blowfish and others
udev             udev - udev
shared-mime-info shared-mime-info - Freedesktop common MIME database
python-3.8-embed Python - Embed Python into an application
expat            expat - expat XML parser
python3-embed    Python - Embed Python into an application
libcrypt         libxcrypt - Extended crypt library for DES, MD5, Blowfish and others

Describe what you expected:
Should be able to work fine, like its 3.7 variant.

答案1

得分: 1

我最近遇到了一个类似的问题。在搜索了一些关于嵌入Python的论坛后,我找到了这个帖子:“在C中嵌入Python,链接失败,出现未定义引用'Py_Initialize'”1。起初我不太确定如何在golang中做到这一点,但我一直在进行其他关于在golang中嵌入Python的在线搜索。在回顾这些搜索结果时,我看到了一篇文章,名为“Python和Go:第四部分-在内存中使用Python”2,其中在“构建”部分描述了如何在C构建过程中指定特定的标志。基本上,它展示了你可以在其中一个文件中定义标志,如下所示:

/*
#cgo pkg-config: python3
#cgo LDFLAGS: -L/usr/local/lib/python3.8/config-3.8-x86_64-linux-gnu -L/usr/local/lib -lpython3.8 -lcrypt -ldl -lm -lm

#include "Python.h"
*/
import "C"

尽管根据Python的文档,在另一个应用程序中编译嵌入的Python解释器时,你应该通过以下方式获取LDFLAGS:

python3.7-config --ldflags

对于Python版本<= 3.7(我不知道它可以追溯到多久之前。还要相应地替换“python3.7-config”),或者

python3.10-config --ldflags --embed

对于Python版本> 3.7(同样,将“python3.10-config”部分替换为所需的Python版本)

然后我想:“这个头文件的一个版本可能就在go-python项目的某个地方,只需要进行修改”,所以在四处寻找后,我在该项目的high_level_layer.go文件中找到了这个头文件,并将其修改为与上面显示的内容相匹配。

这里的情况是,golang与C具有本地功能,因此用C编写的库可以在golang中工作,反之亦然(经过足够的调整)。关于这个功能有很多文章。这是go官方网站上的一篇文章3。由于基本的Python解释器是用C编写的,如果正确设置了链接器标志和其他标志,golang编译器可以在编译时引用它的头文件和对象文件,这就是上面指定的内容。

另外,另一个注意事项是,我尝试使用了几个不同的go编译器进行编译。我成功地使用了版本1.15.5和1.18.1的编译器,但在1.19.5上没有成功。我不知道具体发生了什么,但我现在不打算去弄清楚,因为我目前只需要编译器版本>= 1.18的功能。最后,我实际上在python3.7上遇到了基本相同的问题,这些更改也解决了这些问题...

英文:

I ran into a similar problem just recently. After searching through a few forums on embedding python, I ran into this one: "Embedding Python in C, linking fails with undefined reference to `Py_Initialize'" 1. I wasn't entirely sure how to do this at first in golang, but I had been doing other online searches on embedded python in golang. Going back through these, I landed at an article call, "Python and Go : Part IV - Using Python in Memory" 2, where it describes in the "Building" section how to specify specific flags to be use in the C building process. Basically, it shows that you can define flags in one of files as such:

/*
#cgo pkg-config: python3
#cgo LDFLAGS: -L/usr/local/lib/python3.8/config-3.8-x86_64-linux-gnu -L/usr/local/lib -lpython3.8 -lcrypt -ldl -lm -lm

#include &quot;Python.h&quot;
*/
import &quot;C&quot;

Although, according to Python's documentation on compiling a python interpreter embedded in another application, you should get the LDFLAGS via,

python3.7-config --ldflags

for python versions <= 3.7 (I don't know how far back if goes. Also, replace the "python3.7-config" accordingly), or,

python3.10-config --ldflags --embed

for python versions > 3.7 (And once again, replace the "python3.10-config" part with the desired python version)

I then thought to myself, "A version of this header is probably located somewhere in the go-python project and it just needs to be changed", so after looking around, I found this header in the high_level_layer.go file in the project and modified it to match what's shown above.

What's exactly going on here is that golang has native functionality with C, so libraries written in C can work in golang, and the opposite is also true (with enough finagling). There's plenty of articles on this functionality. Here's one from go's official website, 3. And since the base python interpreter is written in C, its header and object files can be referenced at compile time by the golang compiler if the linker flags and other flags are set correctly, so that's exactly what's being specified above.

Also, on a different note, I've tried compiling with a few different go compilers. I've had success with the compiler for versions 1.15.5 and 1.18.1, but haven't with 1.19.5. I don't know what's exactly happening, but I'm not going to try and figure it out right now since all I need currently are features in compiler versions >= 1.18. Lastly, I actually had basically the same problems with python3.7, and these changes fixed these problems too...

huangapple
  • 本文由 发表于 2022年12月15日 11:48:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/74806635.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定