关于python:cython-编译问题-和-chatGPT-QA-日志

48次阅读

共计 2443 个字符,预计需要花费 7 分钟才能阅读完成。

Q: python setup.py build_ext --inplace --debug 会学生成 c 文件吗?

A: 在执行 python setup.py build_ext --inplace --debug 命令时,会首先生成 C 文件,而后再将其编译为共享库(通常是扩大模块)。以下是该命令的工作流程:

  1. 生成 C 文件 :当您运行 python setup.py build_ext 时,它会查找我的项目中的 Cython 或 C 扩大模块,而后应用 Cython 编译器将这些扩大模块的.pyx 源文件转换为 C 代码(.c文件)。这些生成的 C 文件将会位于我的项目的构建目录中。
  2. 编译 C 代码:一旦 C 代码生成结束,build_ext 命令将应用 C 编译器(通常是 gcc 或相似工具)将 C 代码编译为共享库(或扩大模块),以便它能够被 Python 导入和应用。
  3. 生成共享库 :生成的共享库文件(通常是.so.dll 等,具体取决于操作系统)会搁置在与源文件雷同的目录中,因为您应用了 --inplace 选项。这意味着不须要将共享库复制到其余中央,您能够间接从当前目录中导入和应用它。
  4. 调试反对:如果您应用了 --debug 选项,编译过程中会包含调试信息,以便在调试 Python 代码时提供更多的信息。

总之,python setup.py build_ext --inplace --debug 命令会在构建过程中生成 C 文件,并将它们编译为共享库或扩大模块,以便在 Python 中应用。

Q:如何指定「指定的构建目录」

A:要指定构建目录,您须要在您的我的项目的 setup.py 文件或者 pyproject.toml 文件中进行配置,具体取决于您应用的构建工具。以下是如何在两种状况下指定构建目录的办法:

在 setup.py 中指定构建目录(应用 setuptools)

如果您应用 setuptools 来构建我的项目,能够在我的项目的 setup.py 文件中指定构建目录。在 setup() 函数中,增加 ext_modules 参数并应用 cythonize() 函数来指定构建目录,如下所示:

from setuptools import setup
from Cython.Build import cythonize

setup(
    # ...
    ext_modules = cythonize("your_module.pyx", build_dir="build"),
    # ...
)

上述示例中,build_dir 参数设置了构建目录为 “build”。您能够将其替换为您想要的任何目录门路。

在 pyproject.toml 中指定构建目录(应用 Poetry 或 PEP 518)

如果您应用 Poetry 或遵循 PEP 518 的我的项目构造,通常会在 pyproject.toml 文件中指定构建目录。编辑 pyproject.toml 文件,增加以下配置:

[build-system]
requires = ["setuptools", "wheel", "cython"]
build-backend = "setuptools.build_meta"

[tool.cython]
build_dir = "build"

在上述配置中,build_dir 参数设置了构建目录为 “build”。您能够依据须要将其替换为您想要的目录门路。

无论您抉择应用 setuptools 还是 Poetry,通过指定构建目录,您能够将生成的 C 文件和共享库隔离到指定的地位,以放弃我的项目的组织构造洁净。


我在编译和钻研 pyav,遇到了一些问题

比方编译 pyav 的时候,为什么会生成 src 文件夹,并且这个 src 文件夹上面都是 c 文件

下面第一个 QA 日志答复第一个问题,因为 cython 编译为 so 文件的,两头须要先整成 c 文件能力,这样能力应用 gcc 等工具来做这件事件,比拟 gcc 只意识 c 文件,不意识 pyx 文件

第二个问题「为什么会生成 src 文件夹」,生成 c 文件默认是在以后门路的,然而编译 pyav 的时候,会对立到 src 文件夹中去,钻研了一下,正如 chatGPT 所说,是因为 pyav 增加了 build_dir="src"

# Construct the modules that we find in the "av" directory.
ext_modules = []
for dirname, dirnames, filenames in os.walk("av"):
    for filename in filenames:
        # We are looking for Cython sources.
        if filename.startswith(".") or os.path.splitext(filename)[1] != ".pyx":
            continue

        pyx_path = os.path.join(dirname, filename)
        base = os.path.splitext(pyx_path)[0]

        # Need to be a little careful because Windows will accept / or \
        # (where os.sep will be \ on Windows).
        mod_name = base.replace("/", ".").replace(os.sep, ".")

        # Cythonize the module.
        ext_modules += cythonize(
            Extension(
                mod_name,
                include_dirs=extension_extra["include_dirs"],
                libraries=extension_extra["libraries"],
                library_dirs=extension_extra["library_dirs"],
                sources=[pyx_path],
            ),
            compiler_directives=dict(
                c_string_type="str",
                c_string_encoding="ascii",
                embedsignature=True,
                language_level=2,
            ),
            build_dir="src",
            include_path=["include"],
        )

正文完
 0