Я написал библиотеку на Cython, которая имеет два разных «режима»:
- При рендеринге я компилирую с использованием GLFW.
- Если не рендеринг, я компилирую, используя EGL, который быстрее, но я не понял, как рендерить с его помощью.
Каков рекомендуемый способ справиться с этой ситуацией?
Сейчас у меня следующая структура каталогов:
mujoco
├── __init__.py
├── simEgl.pyx
├── simGlfw.pyx
├── sim.pxd
└── sim.pyx
simEgl.pyx
содержит код EGL, а simGlfw.pyx
содержит код GLFW. setup.py
использует переменную среды, чтобы выбрать ту или другую для сборки.
Это работает нормально, за исключением того, что мне нужно перекомпилировать код каждый раз, когда я хочу переключаться между режимами. Должен быть способ получше.
Обновлять
Я согласен с тем, что лучший подход - одновременно скомпилировать две разные библиотеки и использовать переключатель, чтобы выбрать, какую из них импортировать. У меня уже есть базовый класс в sim.pyx
с общей функциональностью. Однако сам этот базовый класс должен быть скомпилирован с отдельными библиотеками. В частности, sim.pyx
зависит от libmujoco.so
, который зависит от GLFW или EGL.
Вот мой исчерпывающий поиск возможных подходов:
- Если я не скомпилирую расширение для
sim.pyx
, я получуImportError: No module named 'mujoco.sim'
- Если я скомпилирую расширение для
sim.pyx
без включения графических библиотек в расширение, я получуImportError: /home/ethanbro/.mujoco/mjpro150/bin/libmujoco150.so: undefined symbol: __glewBlitFramebuffer
- Если я скомпилирую расширение для
sim.pyx
и выберу один набор графических библиотек (GLFW), то, когда я попытаюсь использовать другой набор графических библиотек (EGL), это тоже не сработает, что неудивительно:ERROR: GLEW initalization error: Missing GL version
- Если я скомпилирую две разные версии библиотеки
sim.pyx
, одну с одним набором библиотек, одну с другим, я получу:TypeError: unorderable types: dict() < dict()
, что не очень полезное сообщение об ошибке, но, похоже, является результатом попытки поделиться исходным файлом между двумя разными расширения.
Что-то вроде варианта 4 должно быть возможно. Фактически, если бы я работал на чистом C, я бы просто построил два общих объекта бок о бок, используя разные библиотеки. Любые советы о том, как обойти это ограничение Cython, будут очень приветствоваться.
if rendering: import simGlfw as s; else: import simEgl as s
. Это может измениться, если вы хотите использовать функции Cython (т.е. функции времени компиляции), но в этом случае вам нужно предоставить более подробную информацию (хотя общий базовый класс может быть хорошим решением) - person DavidW   schedule 02.12.2017sim.pyx
файла в два разных.so
файла. Я пытаюсь сделать это с помощьюExtension(name='sim1', ...)
иExtension(name='sim2', ...)
, но это вызвало ошибку импорта. Может быть, вы можете предложить лучший способ? - person ethanabrooks   schedule 03.12.2017