编译并使用 python-openzwave 和 open-zwave 在非标准位置

Compile and use python-openzwave with open-zwave in non-standard location

本文关键字:open-zwave 非标准 位置 python-openzwave 编译      更新时间:2023-10-16

我手动编译了python-openzwave以使用C++库。

我想将其用作Kodi插件(在Pi 3上运行的OpenELEC),因此不能使用标准安装。 我已经编译了所有内容,下载了缺少的sixlouie库,现在尝试运行hello_world.py.

我目前的目录结构如下:

- root
- bin
- .lib
- config
Alarm.o
...
libopenzwave.a
libopenzwave.so
libopenzwave.so.1.4
...
- libopenzwave
driver.pxd
group.pxd
...
- louie
__init__.py
dispatcher.py
...
- openzwave
__init__.py
command.py
...
six.py
hello_world.py

但是当我运行hello_world.py时,我收到以下错误 -

Traceback (most recent call last):
File "hello_world.py", line 40, in <module> 
from openzwave.controller import ZWaveController 
File "/storage/.kodi/addons/service.multimedia.open-zwave/openzwave/controller.py", line 34, in <module> 
from libopenzwave import PyStatDriver, PyControllerState 
ImportError: No module named libopenzwave

如果我将libopenzwave.alibopenzwave.so移动到根文件夹,则会出现以下错误:

Traceback (most recent call last):
File "hello_world.py", line 40, in <module> 
from openzwave.controller import ZWaveController 
File "/storage/.kodi/addons/service.multimedia.open-zwave/openzwave/controller.py", line 34, in <module> 
from libopenzwave import PyStatDriver, PyControllerState 
ImportError: dynamic module does not define init function (initlibopenzwave)

我的设置有什么问题?

一般来说,所需的步骤包括调用make build,它处理为 openzwave 构建.cpp文件并下载所有依赖项(包括Cython);make install运行setup-apisetup-lib.py(此安装脚本还为openzwave创建C++Python扩展)、setup-web.pysetup-manager.py

由于您无法按照指定的方式运行make install而是使用它们提供的存档,因此在使用make build构建 openzwave 库后,创建 python 扩展的唯一其他选项是为其生成.so文件而不安装到标准位置。

在与Cython脚本相同的文件夹中构建 cython 扩展的.so是通过运行以下命令完成的:

python setup.py build_ext --inplace

这应该在名为libopenzwave.sosrc-lib中创建共享库(它不同于bin/目录中包含的libopenzwave.so),其中包含扩展模块中指定的所有功能。您可以尝试将其添加到libopenzwave文件夹中。

如果在构建 openzwave 库的make build期间传递特殊的编译器标志,则应在执行setup-lib.py脚本时指定相同的标志。这可以通过在执行之前指定CFLAGS来完成(如此处指定),否则您可能会遇到error adding symbols: File in wrong format等问题。

这是从问题的角度对python-openzwave构建的描述。几乎所有的步骤都对应于根Makefile的目标。

  • 先决条件。有几个独立的目标,几乎没有组织。大多数使用 Debian 特定的命令。
    • 如果从存档构建,则不需要Cython(详细信息如下)
  • Openzwave C++ Library(openzwave openzwave/.lib/Target).
    • 构建逻辑:openzwave/Makefile,不带参数调用(但使用继承的环境)。
    • 输入:openzwave/子树(包括libhidapilibtinyxml,静态链接)。
    • 输出:openzwave/.lib/libopenzwave.{a,so}
    • 接受PREFIX作为 envvar(默认/usr/local)
      • 影响我们的唯一效果是:$(PREFIX)/etc/openzwave/被分配给一个宏,该宏为配置文件(Options.cpp)添加搜索位置:config/->/etc/openzwave/-><custom location>
  • libopenzwave Python C 扩展模块(install-lib目标 - 是的,股票Makefile不能只是构建它;目标甚至没有对库的依赖)。
    • 构建逻辑:setup-lib.py
    • 输入:src-lib/openzwave/.lib/libopenzwave.a
    • 输出:build/<...>/libopenzwave.so- 是的,与openzwave的输出同名,因此请避免混淆它们
      • 默认情况下,openzwave与模块静态链接,因此无需将前者包含在部署中
      • 但是,该模块确实需要库中的config文件夹。制作包时,它包含在构建脚本中。
    • 与 Jim 所说的相反,不需要从存档构建 Cython,存档已经包含生成的.cpp
    • 现在,问题是:模块本身使用pkg_resources来定位其数据。因此,您不能只是将.soconfig放入currect目录中并调用一天。你需要让pkg_resources.get_distribution('libopenzwave')成功。
      • pkg_resources声称支持"普通文件系统包,.egg文件和解压缩的.egg文件"。
      • 特别是,我能够做到这一点:创建一个.egg(setup-lib.py bdist_egg),将其解压缩到当前目录中,然后将EGG-INFO重命名为libopenzwave.egg-info(就像在site-packages中一样)。如果我在导入模块之前没有专门将.so的位置添加到PYTHON_PATH/sys.path中,则会发出UserWarning
  • openzwavepyozwmanpyozwwebPython 包(install)
    • 这些是纯 Python 包。第一个使用 C 扩展模块,其他人使用第一个。
    • 构建逻辑:setup-api.pysetup-manager.pysetup-web.py
    • 输入:src-*/
    • 输出:(纯Python)
    • 他们只使用pkg_resources.declare_namespace()所以你只在sys.path上使用正确的文件/目录就可以
    • 了,没有任何.egg-info
相关文章: