CONAN der Erbauer

Manche denken beim Title CONAN an den alten Kinofilm mit Arnold Schwarzenegger, andere erinnern sich an den Anime mit dem Detektiv-Jungen.

Und für einen meiner geschätzten Kollegen ist das Paket-Tool CONAN die Lösung aller Probleme in der C++ Entwicklung.


In der Theorie sieht es so aus:

  • Wir schreiben einzelne C und C++ Dateien
  • CMake fügt mehrere C/C++ Dateien zu einem generischen Projekt zusammen, das dann auf jeder Buildumgebung übersetzt werden kann
  • Und CONAN verwaltet alle Abhängigkeiten von Paketen zwischen Projekten und erstellt automatisch CMake Files um mehrere Projekte unter einen Hut zu bekommen.

Ob das in der Praxis auch so sein wird … das lerne ich gerade im Zuge meiner Arbeit.

Beispiel Szenario

Angenommen wir schreiben ein Programm, das Kompression einsetzt, z.B. durch die gute alte ZLIB.

Jetzt können wir die Sourcen in ein Unterverzeichnis unseres Projektes kopieren und einfach mitkompilieren.
Oder: wir nutzen CONAN und setzen eine Abhängigkeit auf ein CONAN-ZLIB-Paket. Dann brauchen wir nämlich nur noch unsere eigenen Sourcen speichern und ausliefern, und CONAN wird die fehlende ZLIB aus dem Internet (oder einem lokalen Build-Artifactory) herunterladen.

CONAN stellt unterschiedliche Möglichkeiten seiner Nutzung zur Verfügung, einige davon sind:

  • Ein Paket kann alle Sourcen eines Moduls beinhalten und wird dann lokal bei bzw. vor der Nutzung neu kompiliert
  • Ein Paket enthält Header und vorkompilierte Binärdateien. Damit lädt CONAN die fertigen Dateien herunter und stellt sie dem Linker automatisch zur Verfügung.
  • Oder CONAN besteht nur noch aus Binärdateien, die für die Auslieferung benötigt werden und wird so zu einem Setup/Deployment-Builder.

Implementierung

Ist CONAN auf dem System installiert, erweitert man CMAKE um ein paar Zeilen und fügt die Datei conanfile.py hinzu. Dabei handelt es sich um Python-Script, das eine spezielle Klasse implementiert, deren Methoden in den einzelnen Ausführungsschritten das Verhalten von CONAN beieinflussen.

Am wichtigsten sind dabei die Abhängigkeiten, wo wir festlegen, welche anderen Pakete für den Einsatz unseres Pakets benötigen. Diese haben das Format:
name/version@remote/branch

Im Falle des offiziellen ZLIB-Pakets für CONAN lautet der Pfad: zlib/1.2.11@conan/stable

Der remote Parameter ist mit der Installation automatisch auf die Server von conan.io und bintray.com gesetzt. Will man Pakete von anderen bzw. eigenen Servern nutzen, muss ein entsprechender Name registriert und der CONAN-Konfiguration mitgeteilt werden.

Wird nun direkt oder indirekt ein Paket installiert, z.B. mit
conan install zlib/1.2.11@conan/stable
dann lädt CONAN alle benötigten Dateien herunter und speichert sie in einem (zugegeben etwas merkwürdigen) Pfad im Home-Verzeichnis.

Wenn wir dann unser leicht modifiziertes CMAKE nutzen, um Projektdateien zu erzeugen, setzt CONAN automatisch alle Pfade für CMAKE auf die richtigen INCLUDE- und LIB- Verzeichnisse, womit wir unser Projekt kompilieren können, ohne komplexe Such-Routinen in CMAKE implementieren zu müssen.

Denn dass CMAKE alle seine Dateien findet, kann bei größeren Projekten mit mehreren Abhängigkeiten durchaus herausfordernd werden. Und genau diesen Job soll hier CONAN erledigen.

Ein wichtiges Detail ist, dass im Falle von Binärdateien CONAN für jede Plattform und Build-Option ein eigenes Paket erstellt. Für Windows gibt es in der Regel 4 unterschiedliche Pakete für ein Modul, nämlich

  • Debug Win32
  • Release Win32
  • Debug Win64
  • Release Win64

Und CONAN leitet an CMAKE genau die Pfade weiter, die für die gewünschte Build-Konfiguration notwendig ist. Und bei unterschiedlichen Compilern bzw. auf Linux ist das ebenso.

Fazit

Nun, noch ist CONAN für mich ein Novum und die Umstellung eines größeren Projektes (an der ich mitarbeiten darf) ist das teilweise recht aufwendig. Tatsächlich liegt ein ordentlicher Teil des Migrationsaufwandes an jenen Stellen, wo CMAKE Workarounds benutzt wurden um Features zu generieren, die es ohne CONAN eben nicht gibt.
Solche Codes umzuschreiben und durch CONAN-Standards zu ersetzen erfordert also dann doch etwas Programmieraufwand in Python und auch Verzeichnisstrukturen oder Unit-Tests sind unter CONAN anders organisiert, als bei einigen bestehenden Projekten.

Werde ich CONAN im GATE Projekt einsetzen?

Nein, vorerst nicht. Einerseits fehlt mir das Wissen, wie ein “ideales” CONAN Projekt aussehen soll und außerdem sind externe Abhängigkeiten genau das, was GATE vermeiden will. Dennoch bleiben stets ein paar Abhängigkeiten auch bei mir übrig (z.B. GTK unter Linux) und vielleicht werden diese in Zukunft auch durch eine CONAN-Lösung aus dem Weg geräumt werden.

Bis dahin gibt es aber noch viel für mich zu entdecken …


Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!