Heim >Backend-Entwicklung >C++ >Wie integriere ich CMake in setup.py zum Erstellen von Python-Erweiterungen?
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!