对于背景,我阅读了以下问题: https://github.com/cython/cython/wiki/PackageHierarchy
Cython cimport cannot find .pxd module
How do you get cimport to work in Cython?
Error compiling Cython file: pxd not found in package
问题是这个。我曾经有很多C,C ++和Cython都坐在一个目录中,并且可以很好地编译。现在,我将代码分为两个目录:
基本原理是模块function (a, v) { return a+Number(v.dataset.itemRate) }
将被多次重用,而模块cpysim
将在项目之间变化。最后的麻烦是模块dut
中的一个文件只能参考模块cpysim
中的文件进行编译,这就是给我带来的问题。
很明显,当所有内容都放在一个目录中时,所有内容都可以正常编译。这就是现在的样子。
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
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()])
标头的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
目录视为一个模块。所以我添加了cpysim
,并将__init__.py
中的导入更改为:
wiretypes.pyx
from libcpp cimport bool
cimport cpysim.sim_core as sim_core
所以现在我很茫然。我不明白为什么我的第一次尝试不起作用,我知道include dirs传递正确,因为还需要找到许多其他标头并正确编译它们。
我认为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
的工作方式存在一些基本方面,我很想念。
答案 0 :(得分:1)
似乎您将include与... include混淆了。
构建Cython扩展是一个两步过程:
使用cythonize
函数和必要pxd文件的路径作为cython编译器的包含路径,从pyx文件生成C-souce文件(精确{{1 }}不会直接调用Cython编译器-稍后会在执行cythonize
时发生,但是为了得到这个答案,我们假装setup
=调用Cython编译器)
在调用cythonized
函数时,使用所需的包含头的路径(* .h文件,例如numpy的)从生成的C文件生成一个so文件(或其他文件)。
如果将“ include_dirs”添加到setup
会发生什么? Cython编译器或C编译器使用它吗?
Cython使用传递给Extension
-函数的包含目录,在您的情况下,它什么都没有(结果为cythonize
),即必须将其更改为
[.]
但是,Cython还使用ext = cythonize(extensions, include_path=[<path1>, <path2>], ...)
搜索sys.path
文件-因此设置pxd
可能是一种解决方法(有点麻烦,因为对{{1} })-在这种情况下,包含的顺序为:sys.path
,sys.path
,include_directories
(至少在最多current versions中)。
有趣的是,如果使用了没有显式调用sys.path
的setuptools,那么Cython和C编译器都会使用Cython/Includes
,即:
cythonize
Cython和C编译器同时使用include_dirs
和from setuptools import setup, Extension
extensions = [Extension("foo", ["foo.pyx"], include_dirs=[<path1>, <path2>])]
setup(name="foo", ext_modules=extensions)
。
但是,我不确定上述用于设置path1
的解决方案是否可以被推荐:仅因为path2
uses(另请参见that){{3 }}'old_build_ext include_path
include_path` deprecated:
setuptools