【发布时间】:2017-12-01 20:30:09
【问题描述】:
我在 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 限制的建议。
【问题讨论】:
-
您可能只想将两者构建为单独的扩展模块?例如以stackoverflow.com/a/21826294/3657742为例
-
我在很大程度上同意@chrisb。您编写两个具有相同接口的扩展模块并使用
if rendering: import simGlfw as s; else: import simEgl as s。如果您想使用 Cython(即编译时)功能,这可能会改变,但如果是这种情况,您需要提供更多细节(尽管通用基类可能是一个很好的解决方案) -
我同意这是要走的路。但是,它确实需要将
sim.pyx文件编译成两个不同的.so文件。我尝试使用Extension(name='sim1', ...)和Extension(name='sim2', ...)执行此操作,但这会导致导入错误。或许您可以提出一个更好的方法? -
@chrisb,我的情况与您引用的帖子之间的关键区别在于,该帖子不需要在两个单独的扩展中使用相同的来源。
-
@ethanabrooks(不是 100% 肯定,但是......) Cython/Python 模块的名称来自源文件名,我认为这是导致您出现问题的原因。您可以尝试使用正确的名称创建两个几乎为空的 .pyx 文件,并使用 Cython's little used include mechanism 在每个文件中加载共享代码。
标签: cython setuptools distutils python-extensions