Компилировать и использовать python-openzwave с открытым zwave в нестандартном местоположении

Я вручную скомпилировал python-openzwave для работы с библиотекой С++.

Я хотел бы использовать его в качестве дополнения Kodi (OpenELEC работает на Pi 3), поэтому не может использовать стандартную установку. Я скомпилировал все, загрузил отсутствующие six и louie libs, и теперь попробуйте запустить 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.a и libopenzwave.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)

Что не так с моей настройкой?

Ответ 1

В общем случае требуемые шаги состоят из вызовов make build, которые обрабатывают создание файлов .cpp для openzwave и загрузку всех зависимостей (включая Cython); и make install, который запускает setup-api, setup-lib.py (эта настройка script также создает расширение C++ Python для openzwave), setup-web.py и setup-manager.py.

Поскольку вы не можете запустить make install, как вы указали, и вместо этого используете предоставленный им архив, единственные другие возможности для создания расширения python, после создания библиотеки openzwave с помощью make build, генерируют файлы .so для он не устанавливается в стандартные местоположения.

Построение .so для расширения cython в той же папке, что и скрипты Cython, выполняется с помощью:

python setup.py build_ext --inplace

Это должно создать общую библиотеку в src-lib с именем libopenzwave.so (она отличается от libopenzwave.so, содержащейся в каталоге bin/), которая содержит все функции, указанные в модуле расширения. Вы можете попробовать добавить это в папку libopenzwave.

Если вы передаете специальные флаги компилятора во время make build для создания библиотеки openzwave, вы должны указать те же самые при выполнении setup-lib.py script. Это можно сделать, указав CFLAGS перед его выполнением (как указано здесь), иначе у вас могут возникнуть проблемы, такие как error adding symbols: File in wrong format.

Ответ 2

Здесь описание сборки python-openzwave с точки зрения вопроса. Почти все этапы соответствуют корневым целям Makefile.

  • Предпосылки. Существует несколько независимых целей с практически отсутствующей организацией. Большинство используют команды, специфичные для Debian.
    • Cython не требуется при создании из архива (подробнее см. ниже)
  • openzwave С++ library (openzwave openzwave/.lib/ target).
    • Логика сборки: openzwave/Makefile, вызывается без параметров (но с унаследованной средой).
    • Входы: openzwave/ поддерево (включает libhidapi и libtinyxml, статически связанные).
    • Выходы: openzwave/.lib/libopenzwave.{a,so}
    • Принимает PREFIX как envvar (/usr/local по умолчанию)
      • Единственный эффект, который влияет на нас: $(PREFIX)/etc/openzwave/ присваивается макросу, который добавляет местоположение поиска для файлов конфигурации (Options.cpp): config//etc/openzwave/<custom location>.
  • libopenzwave Модуль расширения Python C (install-lib target - да, запас Makefile не может просто его создать, у цели нет даже зависимости от библиотеки).
    • Логика сборки: setup-lib.py
    • Входы: src-lib/, openzwave/.lib/libopenzwave.a
    • Выходы: build/<...>/libopenzwave.so - да, то же имя, что и openzwave вывод, поэтому не путайте их
      • По умолчанию openzwave связывается статически с модулем, поэтому вам не нужно включать его в развертывание
      • Модулю, однако, нужна папка config из библиотеки. Он входит в сборку script при создании пакета.
    • В отличие от что Джим говорит, Cython не требуется для сборки из архива, архив уже включает сгенерированный .cpp.
    • Теперь улов: сам модуль использует pkg_resources для поиска своих данных. Поэтому вы не можете просто отбросить .so и config в каталог currect и называть его днем. Вам нужно сделать pkg_resources.get_distribution('libopenzwave') успешным.
      • pkg_resources утверждает, что поддерживает "нормальные файловые системы, файлы .egg и распакованные файлы .egg."
      • В частности, мне удалось снять это: сделайте .egg (setup-lib.py bdist_egg), распакуйте его в текущий каталог и переименуйте EGG-INFO в libopenzwave.egg-info (например, он находится в site-packages). A UserWarning выдается, если я специально не добавляю местоположение .so в PYTHON_PATH/sys.path перед импортом модуля.
  • openzwave, pyozwman и pyozwweb Пакеты Python (install)
    • это чистые пакеты Python. Первый использует модуль расширения C, другие используют первый.
    • Логика сборки: setup-api.py, setup-manager.py, setup-web.py
    • Вход: src-*/
    • Выход: (чистый Python)
    • Они используют только pkg_resources.declare_namespace(), так что с файлами /dirs на sys.path у вас будет все в порядке, без .egg-info