cython - Cython cimport 从另一个目录
问题描述
对于背景,我已阅读以下问题: https ://github.com/cython/cython/wiki/PackageHierarchy
问题是这样的。我曾经有大量的 C、C++ 和 Cython 都放在一个目录中并且编译得很好。现在,我将代码拆分为 2 个目录:
- 模块“cpysim”的 C/C++/Cython 源代码
- 另一个模块“dut”的 C/C++/Cython 代码
基本原理是模块cpysim
将被多次重用,而模块dut
会因项目而异。最后一个问题是 module 中的一个文件cpysim
只能参考 module 中的文件进行编译dut
,这就是给我带来问题的原因。
需要明确的是,当一切都在一个目录中时,一切都编译得很好。这就是它现在的样子。
<root>
-- __init__.py
-- cpysim
-- __init__.py
-- __init__.pxd
-- sim_core.cpp
-- sim_core.hpp
-- sim_core.pxd
....
wiretypes.pyx
<other sources>
-- dut
-- wire_names.def
-- setup_dut.py
<other sources>
目标
wiretypes.pyx
从目录编译dut
(从setup_dut.py
坐在dut
目录中)。
试试 1
这个进口给我带来了麻烦wiretypes.pyx
from libcpp cimport bool
from sim_core cimport sigtype_t # <-- this one
....
这是相关内容setup_dut.py
inc_dirs = ['./', '../', '../cpysim/', '../build', '../dSFMT-src-2.2.3', '../build/include']
....
Extension("wiretypes",
["../cpysim/wiretypes.pyx"],
language="c++",
libraries=["cpysim", "ethphy"],
include_dirs=inc_dirs,
library_dirs=lib_dirs,
extra_compile_args=compile_args,
extra_link_args=link_args),
....
ext = cythonize(extensions,
gdb_debug=True,
compiler_directives={'language_level': '3'})
setup(ext_modules=ext,
cmdclass={'build_ext': build_ext},
include_dirs=[np.get_include()])
为什么我认为这应该起作用:根据文档,指定包含sim_core.pxd
标头的包含路径就足够了。例如,cimport numpy as np
当你设置时工作include_dirs=[np.get_include()]
,np.get_include()
只是吐出一条路径。所以,在 中inc_dirs
,我把../cpysim
. 当我编译时,我得到
Error compiling Cython file:
------------------------------------------------------------
...
"""
Cython header defining a net.
"""
from libcpp cimport bool
from sim_core cimport sigtype_t
^
------------------------------------------------------------
/Users/colinww/system-model/cpysim/wiretypes.pyx:8:0: 'sim_core.pxd' not found
试试 2
我想也许我需要将cpysim
目录视为一个模块。所以我添加了__init__.py
,并将导入更改wiretypes.pyx
为:
from libcpp cimport bool
cimport cpysim.sim_core as sim_core
Error compiling Cython file:
------------------------------------------------------------
...
"""
Cython header defining a net.
"""
from libcpp cimport bool
cimport cpysim.sim_core as sim_core
^
------------------------------------------------------------
/Users/colinww/system-model/cpysim/wiretypes.pyx:8:8: 'cpysim/sim_core.pxd' not found
所以现在我很茫然。我不明白为什么我的第一次尝试没有成功,我知道包含目录正在正确传递,因为还有许多其他需要找到并正确编译的标头。
cimport
我认为我缺少工作方式的一些基本方面。
解决方案
似乎您会将包含与...包含混淆。
构建 Cython 扩展是一个两步过程:
从 pyx 文件生成 C-souce 文件,使用
cythonize
-function 和必要 pxd 文件的路径作为 Cython 编译器的包含路径(准确地说cythonize
,不直接调用 Cython 编译器 - 它稍后会发生,何时setup
执行,但为了这个答案,我们假设cythonized
= 调用 Cython-compiler)setup
当调用 -function时,使用所需的头文件(*.h 文件,例如 numpy's)的包含路径从生成的 C 文件生成一个 so 文件(或其他文件) 。
如果添加include_dirs
到会发生什么Extension
?Cython 编译器或 C 编译器使用它吗?
Cython 使用传递给 -function 的包含目录cythonize
,在您的情况下,它什么都不是(导致[.]
),即必须将其更改为
ext = cythonize(extensions, include_path=[<path1>, <path2>], ...)
但是,Cython 也用于sys.path
搜索pxd
文件 - 因此设置sys.path
可能是一种解决方法(这有点 hacky,因为每次操作sys.path
) - 在这种情况下,包含的顺序是:include_directories
,,sys.path
(Cython/Includes
至少在最新版本中) .
有趣的是,如果使用了没有显式调用的 setuptools cythonize
,那么include_dirs
Cython 和 C 编译器都会使用,即:
from setuptools import setup, Extension
extensions = [Extension("foo", ["foo.pyx"], include_dirs=[<path1>, <path2>])]
setup(name="foo", ext_modules=extensions)
导致两者都path1
被path2
Cython 和 C 编译器使用。
但是,我不确定是否include_path
可以推荐上述设置解决方案:它仅适用于setuptools
使用(另请参阅)已弃用 old_build_ext
,include_path
此处设置为:
...
for source in cython_sources:
...
options = CompilationOptions(...
include_path = includes, # HERE WE GO!
...)
result = cython_compile(source, options=options,
full_module_name=module_name)
推荐阅读
- c# - 如何在实现DI的地方调用另一个项目的方法
- user-interface - 如何在颤动中制作类别和子类别按钮
- c# - 如何在 C# 中为棋盘游戏制作撤消功能?
- java - Android Studio:在 X 行中找不到可执行代码
- arrays - 具有 DateValue 的多条件数组
- android - Okhttp3 Requestbody create() 伴侣已弃用。令人困惑的文档
- python - Scrapy:两个 HTML 元素之间的文本选择器..?
- c++ - GLFW C++ 架构 x86_64 的未定义符号
- apache-nifi - 导入 Sqoop 列名问题
- docker - “/var/www/html”的目录索引被禁止 docker/nginx 403 错误