Cython cimport从另一个目录

时间:2019-06-28 18:59:52

标签: cython cythonize

对于背景,我阅读了以下问题: https://github.com/cython/cython/wiki/PackageHierarchy

https://cython.readthedocs.io/en/latest/src/userguide/sharing_declarations.html#search-paths-for-definition-files

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都坐在一个目录中,并且可以很好地编译。现在,我将代码分为两个目录:

  1. 模块“ cpysim”的C / C ++ / Cython源代码
  2. 另一个模块“ dut”的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

尝试1

此导入给我带来了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

尝试2

我认为也许我需要将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 的工作方式存在一些基本方面,我很想念。

1 个答案:

答案 0 :(得分:1)

似乎您将include与... include混淆了。

构建Cython扩展是一个两步过程:

  1. 使用cythonize函数和必要pxd文件的路径作为cython编译器的包含路径,从pyx文件生成C-souce文件(精确{{1 }}不会直接调用Cython编译器-稍后会在执行cythonize时发生,但是为了得到这个答案,我们假装setup =调用Cython编译器)

  2. 在调用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.pathsys.pathinclude_directories(至少在最多current versions中)。


有趣的是,如果使用了没有显式调用sys.path的setuptools,那么Cython和C编译器都会使用Cython/Includes,即:

cythonize

Cython和C编译器同时使用include_dirsfrom 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