首页 > 后端开发 > C++ > 如何将 CMake 集成到 setup.py 中以构建 Python 扩展?

如何将 CMake 集成到 setup.py 中以构建 Python 扩展?

Susan Sarandon
发布: 2024-10-27 12:11:02
原创
803 人浏览过

How to Integrate CMake into setup.py for Building Python Extensions?

如何在 setup.py 中集成 CMake 以实现 setuptools 扩展

构建 Python 扩展以及对 CMake 的需求

何时CMake 开发集成 C 库的 Python 扩展,提供了用于管理构建过程的综合工具。但是,典型的工作流程涉及在运行 setup.py bdist_wheel 之前使用 CMake 手动编译库。这可能不方便且耗时。

在 setup.py 中调用 CMake

为了解决这个问题,可以将 CMake 合并到 setup.py 构建过程中。关键是创建一个自定义的 build_ext 命令,利用 CMake 来配置和构建扩展。

自定义 build_ext 命令

在 setup.py 文件中,覆盖build_ext 命令类并将其注册到命令类中。在您的自定义实现中,配置并调用 CMake 来构建扩展模块。

示例项目和设置脚本

为了演示这个概念,请考虑一个带有 C 语言的简单项目扩展名 (foo) 和一个 Python 模块 (spam.eggs)。 setup.py 脚本利用 CMakeExtension 类来封装扩展,而不调用原始的 build_ext。 build_cmake 方法处理 CMake 配置和构建步骤。

<code class="python">import os
import pathlib

from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext_orig

class CMakeExtension(Extension):

    def __init__(self, name):
        # don't invoke the original build_ext for this special extension
        super().__init__(name, sources=[])

class build_ext(build_ext_orig):

    def run(self):
        for ext in self.extensions:
            self.build_cmake(ext)
        super().run()

    def build_cmake(self, ext):
        cwd = pathlib.Path().absolute()

        # these dirs will be created in build_py, so if you don't have
        # any python sources to bundle, the dirs will be missing
        build_temp = pathlib.Path(self.build_temp)
        build_temp.mkdir(parents=True, exist_ok=True)
        extdir = pathlib.Path(self.get_ext_fullpath(ext.name))
        extdir.mkdir(parents=True, exist_ok=True)

        # example of cmake args
        config = 'Debug' if self.debug else 'Release'
        cmake_args = [
            '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + str(extdir.parent.absolute()),
            '-DCMAKE_BUILD_TYPE=' + config
        ]

        # example of build args
        build_args = [
            '--config', config,
            '--', '-j4'
        ]

        os.chdir(str(build_temp))
        self.spawn(['cmake', str(cwd)] + cmake_args)
        if not self.dry_run:
            self.spawn(['cmake', '--build', '.'] + build_args)

setup(
    name='spam',
    version='0.1',
    packages=['spam'],
    ext_modules=[CMakeExtension('spam/foo')],
    cmdclass={
        'build_ext': build_ext,
    }
)</code>
登录后复制

测试和验证

通过构建项目的轮子并安装它,您可以验证该库是否是成功安装并正常运行。从 spam.eggs 模块运行包装函数应该会产生预期的输出。

以上是如何将 CMake 集成到 setup.py 中以构建 Python 扩展?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板