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 setupfrom Cython.Build import cythonizesetup(    # ...    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"],        )