Heim >Backend-Entwicklung >C++ >Wie integriere ich CMake in setup.py zum Erstellen von Python-Erweiterungen?

Wie integriere ich CMake in setup.py zum Erstellen von Python-Erweiterungen?

Susan Sarandon
Susan SarandonOriginal
2024-10-27 12:11:02800Durchsuche

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

So integrieren Sie CMake in setup.py für die Setuptools-Erweiterung

Erstellen von Python-Erweiterungen und die Notwendigkeit von CMake

Wann CMake entwickelt Python-Erweiterungen, die C-Bibliotheken integrieren, und bietet ein umfassendes Tool zur Verwaltung von Build-Prozessen. Der typische Arbeitsablauf besteht jedoch darin, die Bibliotheken manuell mit CMake zu kompilieren, bevor setup.py bdist_wheel ausgeführt wird. Dies kann unpraktisch und zeitaufwändig sein.

Aufrufen von CMake in setup.py

Um dieses Problem zu beheben, ist es möglich, CMake in den Build-Prozess von setup.py zu integrieren . Der Schlüssel besteht darin, einen benutzerdefinierten build_ext-Befehl zu erstellen, der CMake zum Konfigurieren und Erstellen der Erweiterungen verwendet.

Anpassen des build_ext-Befehls

Überschreiben Sie in der Datei setup.py die Erstellen Sie die Befehlsklasse build_ext und registrieren Sie sie in den Befehlsklassen. Konfigurieren Sie innerhalb Ihrer benutzerdefinierten Implementierung CMake und rufen Sie es auf, um die Erweiterungsmodule zu erstellen.

Beispielprojekt und Setup-Skript

Um das Konzept zu demonstrieren, betrachten Sie ein einfaches Projekt mit einem C Erweiterung (foo) und ein Python-Modul (spam.eggs). Das setup.py-Skript nutzt eine CMakeExtension-Klasse, die die Erweiterung kapselt, ohne die ursprüngliche build_ext aufzurufen. Die build_cmake-Methode verwaltet die CMake-Konfiguration und Build-Schritte.

<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>

Testen und Validieren

Indem Sie das Rad des Projekts erstellen und installieren, können Sie überprüfen, ob die Bibliothek vorhanden ist erfolgreich installiert und funktionsfähig. Das Ausführen einer Wrapper-Funktion aus dem spam.eggs-Modul sollte die erwartete Ausgabe erzeugen.

Das obige ist der detaillierte Inhalt vonWie integriere ich CMake in setup.py zum Erstellen von Python-Erweiterungen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn