2009-08-12 8 views
4

Ich habe ziemlich große C++ - Bibliothek mit mehreren Unterbibliotheken, die es unterstützen, und ich muss das Ganze in eine Python-Erweiterung verwandeln. Ich verwende Distutils, weil es plattformübergreifend sein muss, aber wenn es ein besseres Tool gibt, bin ich offen für Vorschläge.Python nicht-triviale C++ Erweiterung

Gibt es eine Möglichkeit, distutils zuerst die Unterbibliotheken zu kompilieren und sie zu verknüpfen, wenn es eine Erweiterung von der Hauptbibliothek erstellt?

Antwort

10

Ich mache das gerade mit einer massiven C++ - Bibliothek in unserem Produkt. Es gibt einige Werkzeuge, die Ihnen helfen können, die Aufgabe zu automatisieren, Bindings zu schreiben: das populärste ist SWIG, das eine Weile gewesen ist, wird in vielen Projekten verwendet und funktioniert im Allgemeinen sehr gut.

Die größte Sache gegen SWIG (meiner Meinung nach) ist, dass die C++ - Codebasis von SWIG selbst wirklich ziemlich unfreundlich ist, gelinde gesagt. Es wurde vor der STL geschrieben und hat sein eigenes semi-dynamisches System, das gerade alt und knarrend ist. Das wird nicht viel ausmachen, es sei denn, du musst dich jemals einmischen und Änderungen am Kern vornehmen (ich habe mal versucht, doxygen hinzuzufügen -> Docstring-Konvertierung), aber wenn du es jemals tust, viel Glück für dich! Die Leute sagen auch, dass SWIG-generierten Code nicht so effizient ist, was wahr sein kann, aber für mich habe ich nie gefunden, dass die SWIG-Aufrufe selbst genug sind, um einen Engpass zu befürchten.

Es gibt andere Tools, die Sie verwenden können, wenn SWIG Ihr Boot nicht schwimmt: boost.python ist auch beliebt und könnte eine gute Option sein, wenn Sie bereits Boost-Bibliotheken in Ihrem C++ Code verwenden. Der Nachteil ist, dass es auf Kompilierzeiten schwer ist, da es so ziemlich alles auf C++ Template basiert.

Diese beiden Werkzeuge erfordern, dass Sie einige Vorarbeiten ausführen, um zu definieren, was belichtet wird und wie es gemacht wird. Für SWIG stellen Sie Schnittstellendateien zur Verfügung, die wie C++ - Header sind, aber mit einigen extra Anweisungen, um SWIG mitzuteilen, wie komplexe Typen zu übersetzen sind. Das Schreiben dieser Interfaces kann mühsam sein, also sollten Sie sich etwas wie pygccxml ansehen, um Ihnen zu helfen Erstellen Sie sie automatisch für Sie.

Der Autor dieses Pakets hat tatsächlich eine andere Erweiterung geschrieben, die Ihnen gefallen könnte: py++. Dieses Paket hat zwei Dinge: es kann automatisch Bindungsdefinitionen erzeugen, die dann boost.python zur Erzeugung von Python-Bindungen zugeführt werden können: im Grunde ist es die vollständige Lösung für die meisten Leute. Vielleicht möchten Sie dort starten, wenn Sie keine besonderen oder schwierigen Anforderungen erfüllen müssen.

einige andere Fragen, die als Referenz nützlich sein könnten:

Sie auch praktisch this comparison von Bindungswerkzeuge für Python finden. Wie Alex in den Kommentaren erwähnt, ist es jetzt ziemlich alt, aber gibt dir wenigstens eine Vorstellung von der Landschaft ...

In Bezug darauf, wie man den Build fährt, solltest du dir ein fortgeschritteneres gebautes Tool ansehen das distuts: Wenn Sie mit Python bleiben möchten, würde ich Waf als Rahmen sehr empfehlen (andere werden Ihnen sagen SCons ist der Weg zu gehen, aber glauben Sie mir, es ist langsam wie die Hölle: Ich war dort und zurück schon!) .. .it braucht ein wenig lernen, aber wenn Sie Ihren Kopf herumkommen, ist es sehr mächtig. Und da es reines Python ist, wird es sich perfekt mit jedem anderen Python-Code integrieren, den Sie als Teil Ihres Build-Prozesses haben (sagen wir zum Beispiel, dass Sie am Ende Py ++ verwenden) ...

+1

Beachten Sie, dass der CERN-Bericht, den Sie als "dieser Vergleich" zitieren, über 6 Jahre alt ist und daher mit einem großen Körnchen Salz (!) Eingenommen werden muss. Vor allem SIP hat sich in diesen vielen Jahren ** sehr entwickelt **, so dass es heute in Betracht kommt. –