简体   繁体   English

分发链接到第三方库的 pybind11 扩展

[英]Distributing pybind11 extension linked to third party libraries

I'm working on a pybind11 extension written in C++ but I'm having a hard time understanding how should it be distributed.我正在研究用 C++ 编写的 pybind11 扩展,但我很难理解它应该如何分发。

The project links to a number of third party libraries (eg libpng, glew etc.).该项目链接到许多第三方库(例如 libpng、glew 等)。

The project builds fine with CMAKE and it generates a.so file.该项目使用 CMAKE 构建良好,并生成一个 .so 文件。 Now I am not sure what is the right way of installing this extension.现在我不确定安装此扩展程序的正确方法是什么。 The extension seems to work, as if I try copy the file into the python lib directories it is picked up (I can import it, and it works correctly).扩展似乎有效,就好像我尝试将文件复制到它被拾取的 python lib 目录中(我可以导入它,并且它工作正常)。 However, this is clearly not the way to go I think.但是,我认为这显然不是通往 go 的方式。

I also tried the setuptools route (from https://pybind11.readthedocs.io/en/stable/compiling.html ) by creating a setup.py files like this:我还尝试了 setuptools 路由(来自https://pybind11.readthedocs.io/en/stable/compiling.html ),方法是创建一个 setup.py 文件,如下所示:

import sys

# Available at setup time due to pyproject.toml
from pybind11 import get_cmake_dir
from pybind11.setup_helpers import Pybind11Extension, build_ext
from setuptools import setup
from glob import glob

files = sorted(glob("*.cpp"))

__version__ = "0.0.1"

ext_modules = [
    Pybind11Extension("mylib",
        files,
        # Example: passing in the version to the compiled code
        define_macros = [('VERSION_INFO', __version__)],
        ),
]

setup(
    name="mylib",
    version=__version__,
    author="fab",
    author_email="fab@fab",
    url="https://github.com/pybind/python_example",
    description="mylib",
    long_description="",
    ext_modules=ext_modules,
    extras_require={"test": "pytest"},
    cmdclass={"build_ext": build_ext},
    zip_safe=False,
    python_requires=">=3.7",
)

and now I can build the extension by simply calling现在我可以通过简单地调用来构建扩展

pip3 install

however it looks like all the links are broken because whenever I try importing the extension in Python I get linkage errors, as if setuptools does not link correctly the extension with the 3rd party libs.但是看起来所有链接都断开了,因为每当我尝试在 Python 中导入扩展时,我都会收到链接错误,就好像 setuptools 没有正确地将扩展与第 3 方库链接一样。 For instance errors in linking with libpng as in:例如与 libpng 链接时的错误,如下所示:

>>> import mylib
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /home/fabrizio/.local/lib/python3.8/site-packages/mylib.cpython-38-x86_64-linux-gnu.so: undefined symbol: png_sig_cmp

However I have no clue how to add this link info to setuptools, and don't even know if that's possible (it should be the setuptools equivalent of CMAKE's target_link_libraries).但是我不知道如何将此链接信息添加到设置工具,甚至不知道这是否可能(它应该是相当于 CMAKE 的 target_link_libraries 的设置工具)。 I am really at a loss after weeks of reading documentation, forum threads and failed attempts.在阅读了数周的文档、论坛主题和失败的尝试后,我真的不知所措。 If anyone is able to point me in the right way or to clear some of the fog it would be really appreciated!如果有人能够以正确的方式指出我或清除一些迷雾,我将不胜感激!

Thanks!谢谢! Fab很棒

/home/fabrizio/.local/lib/python3.8/site-packages/mylib.cpython-38-x86_64-linux-gnu.so: undefined symbol: png_sig_cmp

This line pretty much says it clearly.这条线几乎说得很清楚。 Your local shared object file .so can't find the libpng.so against which it is linked.您的本地共享 object 文件.so找不到它所链接的libpng.so

You can confirm this by running:您可以通过运行来确认这一点:

ldd /home/fabrizio/.local/lib/python3.8/site-packages/mylib.cpython-38-x86_64-linux-gnu.so

There is no equivalent of target_link_libraries() in setuptools. setuptools 中没有 target_link_libraries target_link_libraries()的等价物。 Because that wouldn't make any sense .因为那没有任何意义 The library is already built and you've already linked it.该库已经构建并且您已经链接了它。 This is your system more or less telling you that it can't find the libraries it needs.这是您的系统或多或少地告诉您它找不到所需的库。 And those most likely need to be installed.那些最有可能需要安装。

This is also one of the reasons why Linux distributions provide their own package managers and why you should use the developer packages provided by said distributions.这也是 Linux 发行版提供自己的 package 管理器以及为什么您应该使用所述发行版提供的developer包的原因之一。

So how do you fix this?那么你如何解决这个问题? Well your .so file needs to find the other .so files against which you linked to understand how this works I will refer you to this link .那么您的.so文件需要找到您所链接的其他.so文件以了解其工作原理,我将向您推荐此链接

My main guess is based on the fact that when you manually copy the files it works - That during the build process you probably specify the rpath to a local directory.我的主要猜测是基于这样一个事实,即当您手动复制文件时它会起作用——在构建过程中您可能指定了本地目录的rpath Hence what you most likely need to do is specify to your setuptools that it needs to copy those files when installing.因此,您最有可能需要做的是指定您的安装工具在安装时需要复制这些文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM