【问题标题】:Compile and use python-openzwave with open-zwave in non-standard location在非标准位置编译和使用带有 open-zwave 的 python-openzwave
【发布时间】:2016-10-10 10:48:42
【问题描述】:

我手动编译 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)

我的设置有什么问题?

【问题讨论】:

  • 您确定您的模块有初始化信息,如此处所述:docs.python.org/3/extending/…
  • 手动编译到底如何?如果我没记错的话,找不到initlibopenzwave 是因为Cython 文件不是cythonized 并正确编译(Cython 负责为您创建init&lt;modulename&gt; 函数。您能否详细说明编译过程?
  • @Jim,我已经下载了源代码github.com/OpenZWave/python-openzwave/raw/master/archives/…,解压并运行make build。此版本不需要Cython,根据此讨论 - groups.google.com/forum/#!topic/python-openzwave-discuss/…
  • @ShamilKMuhammed,这不是我的模块,但我可以看到libopenzwave.cpp 具有initlibopenzwave 功能。
  • 我看到 .pyx 文件正在构建的唯一情况是在 setup-lib.py 期间,它在 sudo make install(或 sudo make install-lib)执行时运行。我现在在import 上得到了一个可爱的段错误。

标签: python c++ z-wave


【解决方案1】:

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

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

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

python setup.py build_ext --inplace

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 2017-04-27
      • 2019-09-09
      • 1970-01-01
      • 2012-09-11
      • 2017-04-20
      相关资源
      最近更新 更多