Q: python setup.py build_ext --inplace --debug
会学生成 c 文件吗?
A: 在执行 python setup.py build_ext --inplace --debug
命令时,会首先生成 C 文件,而后再将其编译为共享库(通常是扩大模块)。以下是该命令的工作流程:
- 生成 C 文件 :当您运行
python setup.py build_ext
时,它会查找我的项目中的 Cython 或 C 扩大模块,而后应用 Cython 编译器将这些扩大模块的.pyx
源文件转换为 C 代码(.c
文件)。这些生成的 C 文件将会位于我的项目的构建目录中。 - 编译 C 代码:一旦 C 代码生成结束,
build_ext
命令将应用 C 编译器(通常是 gcc 或相似工具)将 C 代码编译为共享库(或扩大模块),以便它能够被 Python 导入和应用。 - 生成共享库 :生成的共享库文件(通常是
.so
、.dll
等,具体取决于操作系统)会搁置在与源文件雷同的目录中,因为您应用了--inplace
选项。这意味着不须要将共享库复制到其余中央,您能够间接从当前目录中导入和应用它。 - 调试反对:如果您应用了
--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"],
)