12

我手动编译python-openzwave以使用C++ library

我想将它用作 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)

我的设置有什么问题?

4

2 回答 2

2

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

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

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

python setup.py build_ext --inplace

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

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

于 2016-06-18T14:11:13.020 回答
1

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

  • 先决条件。有几个独立的目标,几乎没有组织。大多数使用 Debian 特定的命令。
    • 如果从存档构建,则不需要Cython (详情如下)
  • openzwave C++ 库openzwave openzwave/.lib/目标)。
    • 构建逻辑: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定位其数据。因此,您不能只是将.soandconfig放入当前目录并收工。你需要pkg_resources.get_distribution('libopenzwave')成功。
      • pkg_resources 声称支持 “普通文件系统包、.egg 文件和未打包的.egg 文件”。
      • 特别是,我能够做到这一点:制作一个.egg( setup-lib.py bdist_egg),将其解压缩到当前目录并重命名EGG-INFOlibopenzwave.egg-info(就像它在 中一样site-packages)。如果我在导入模块之前UserWarning没有专门将.so' 位置添加到PYTHON_PATH/中,则会发出A 。sys.path
  • openzwave,pyozwmanpyozwwebPython 包( install)
    • 这些是纯 Python 包。第一个使用 C 扩展模块,其他使用第一个。
    • 构建逻辑:setup-api.py, setup-manager.py,setup-web.py
    • 输入:src-*/
    • 输出:(纯 Python)
    • 他们只使用pkg_resources.declare_namespace()这样你就可以在sys.path没有任何.egg-info's 的情况下使用正确的文件/目录
于 2016-06-21T02:20:37.490 回答