Icon Ressource

Deuglyfying C/C++, Teil 1 : Der Projektstart

In diesem HowTo werden 9 für den Aufbau von Open-Source-Projekten in C/C++ essentielle Fragen gestellt, und jeweils in der Erfahrung sinnvolle Antworten auf diese oft übersehenen Designentscheidungen gegeben, die in Kombination zu einem guten Projektdesign führen und viele Inkonsistenzen und Fehler von vorn herein ausschließen können.

Es handelt sich hierbei natürlich um eine von Vorurteilen und dem Ethos, gute Programme schreiben zu wollen, gefärbte Perspektive, die keinen Anspruch auf Vollständigkeit der Möglichkeiten erhebt.

0. Welche Versionsverwaltung wird genutzt?

Versionsverwaltungen sind aus der Softwareentwicklung kaum wegzudenken, und darum wird auch hier nicht für ihre Nützlichkeit argumentiert. Zum Erstellen eines neuen Projektes bieten sich vor allem die Versionsverwaltungssysteme git und mercurial an, die beide einen dezentralen Ansatz verfolgen.

In beiden Fällen sollte auch von Beginn an ein sinnvoller Workflow gewählt werden, es bietet sich hier besonders das erprobte Branching-Modell von Vincent Driessen(https://nvie.com/posts/a-successful-git-branching-model) an.

Weiterhin ist die Wahl des Hosters relevant, von denen die bekanntesten Gitlab und GitHub sein dürften, die beide auch viele weitere Appklikationen(wie Wikis oder eine Anbindung an Kontinuierliche Integration) anbieten.

1. Welche Lizenz wird für das Projekt genutzt?

Es gibt viele mögliche Lizenzen für Open-Source-Software, die hier natürlich nicht alle aufgezählt werden können, um eine passende zu wählen bietet sich der license-chooser an(https://choosealicense.com/).

Zur Verwendung der Lizenz ist zu sagen, dass sie als Plain-Text oder Markdown-Datei(LICENSE oder LICENSE.md) im Wurzelverzeichnis des Projektes liegen sollte, und idealerweise noch mittels SPDX-Identifier(https://spdx.org/licenses) im Kopf jeder Datei angegeben wird.

Verfügt ein Projekt nicht über eine Lizenzangabe so gilt der rechliche Normalfall : "All rights reserved", der jedem anderen jede Nutzung des Codes verbietet.

2. Welches Versionsschema wird genutzt?


Eine oft vollkommen übersehene Frage ist die der konsistenten Versionsnummern für ein Projekt, nicht selten enden dadurch Projekte komplett ohne Versionen oder nach 10 Jahren Entwicklungszeit mit Version 0.1-SNAPSHOT.
Ein klares Versionierungsschema hilft insbesondere bei klaren TODOs und dem Setzen von Zielen, und macht Zusicherungen an die Nutzer, beispielsweise über Änderungen der API.
Ein beliebtes Versionierungsschema ist die semantische Versionierung(https://semver.org).

3. Wie werden die Dateien des Projektes organisiert?

Diese Frage befasst sich mit dem Layout der zum Projekt gehörenden Dateien auf dem Dateisystem. Hierbei ist vor allem ein konsistentes Layout zu beachten, das gut mit dem verwendeten Buildsystem harmoniert. Neben klassischen Layouts wie der Trennung in src/ und include/-Pfade, die lange Zeit verwendet wurde, bietet sich hier vor allem die von Boris Kolpackov vorgeschlagene kanonische Projektstruktur an, bei der im Fall von C++ der Ordnerpfad die verwendeten Namespaces wiederspiegeln sollte(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1204r0.html).

Weiterhin sollten zu jedem Projekt noch Dateien gehören, die die Verwendung von Tools bestimmen(und im Regelfall im Wurzelverzeichnis des Projektes liegen sollten, wie die Konfigurationsdateien für CI, Buildsystem oder static analyzer) und solche, die der Projektbeschreibung für Menschen dienen.

Zu zweiterer Gruppe gehören für typische GitHub-Projekte vor allem die in Plaintext oder Markdown abgefassten Dateien README(.md), CONTRIBUTING(.md), LICENSE(.md) und TODO(.md).

Die LICENSE Datei beinhaltet den Volltext der für das Projekt verwendeten Lizenz, inklusive des Urhebers oder der Urheber des Projektes.

Das README ist das Aushängeschild des Projektes: es gibt die Abhängigkeiten an, eine Kurzbeschreibung des Projektes, zeigt die Verwendung(einschließlich bauen und testen) und beinhaltet Idealerweise auch die derzeit aktuelle Release-Version und Informationen über den Erfolg des Kompilationsprozesses mit dem CI-Tool.

Das TODO zeigt, welche der Ziele des Projektes erfüllt sind, welche Teilziele noch zu erfüllen sind, zeigt eine wesentliche Roadmap für die Entwickler und gibt einen Überblick über den Status des Projektes für Außenstehende.

CONTRIBUTING ist eine Datei, die genaueren Aufschluss über die Entwicklung gibt, und als solcher der richtige Ort, um unter Anderem Versionierungs- und Git-Schemata, verwendete Coding-Standards, den Code of Conduct des Projektes und den Pull-Request-Prozess zu erklären, und dient damit als integraler Bestandteil der Entwicklerdokumentation.

4. Welcher Sprachstandard wird verwendet und was ist das Zielsystem?


Viele Projekte scheitern an einer unklaren Spezifikation des Zielsystems, daher ist es im Rahmen der Projekterstellung integral, die unterstützten Zielsysteme und Compiler zu spezifizieren, aber auch den verwendeten Sprachstandard und ob Compiler-spezifische Erweiterungen verwendet werden dürfen.

Im Allgemeinen sollte hier der neueste mögliche Sprachstandard ohne Vendor-spezifische Erweiterungen verwendet werden, und das Projekt auf allen gebräuchlichen Compilern, Betriebssystemen und Prozessorarchitekturen funktionstüchtig sein.
Hiervon sollte nur mit gutem Grund abgewichen werden(Gegenbeispiel ist hier zum Beispiel ein Treiber für Linux). Entsprechend sollten auch die verwendeten Bibliotheken gewählt werden, Portabilität sollte nicht als Feature, sondern als integraler Anspruch an Software verstanden werden.

5. Welches Buildsystem wird verwendet?


Ein Buildsystem ist die Software, die unter Verwendung von Compiler und Linker die Programmdateien des Projektes in Binärdateien, wie Bibliotheken oder Executables, übersetzt. Zu den besonderen Features gehört bei ihnen, dass sie nur die Dateien jeweils neu bauen, die geändert wurden, die Verfügbarkeit von Features in Bibliotheken prüfen können, das Testen unterstützen, und vieles mehr.

Auch bei der Wahl des Buildsystems sollte auf Portabilität geachtet werden, da seine Portabilität und sein ordnungsgemäßes Funktionieren für die Portabilität des gesamten Programmes der erste Schritt ist.

Ein übliches Buildsystem das diese Anforderungen erfüllt ist CMake, das auch gleichzeitig durch hohe Verbreitung und eine große Community glänzt, im Unix- und Linux-Umfeld sind darüber hinaus verschiedenste Versionen von make oder mk verbreitet.

6. Welches Tool für Kontinuierliche Integration wird verwendet?


Eine für viele Projekte weniger offensichtliche Wahl ist die eines Werkzeugs für kontinuierliche Integration(CI), das oft als nicht notwendig abgetan wird, aber auch in Hobbyprojekten erhebliches Potential hat, die Codequalität und Portabilität zu verbessern.

Generell beschreibt CI den Prozess, regelmäßig und kontinuierlich(üblicherweise beim Einchecken in die Versionsverwaltung oder zu bestimmten Zeiten) das Gesamtsystem neu zu bauen, Tests durchzuführen und ggf. Performancemetriken zu messen, üblicherweise automatisiert.
Dies hat vor allem deshalb erhebliches Potential, weil zu jedem Zeitpunkt klar ist, ob die Software die Tests und Metriken erfüllt, und weil es das einfache Ausführen von Tests auf verschiedenen Systemen und mit verschiedenen Parametern ermöglicht, von denen keiner der Rechner des Entwicklers ist.

Erweitert werden kann dieses Modell um das continuous delivery, bei dem basierend auf den Ergebnissen der CI das Paketieren und Ausliefern der Software(zum Beispiel das hochladen auf einem FTP-Server oder das einpflegen in ein Repository) auch automatisiert wird.

Unter den verbreiteten CI-Lösungen seien hier, wegen ihrer einfachen Integration, vor allem Travis CI für GitHub und Gitlab CI für Gitlab empfohlen.

7. Welchen Guidelines folgt das Projekt?


Sowohl C als auch C++ sind Programmiersprachen, bei denen das Befolgen von Guidelines nahezu unumgänglich ist, um Bugs zu vermeiden und les- und wartbaren Code zu erzeugen. Es gibt viele derartige Standards, daher seien besonders für C++, wo diese Notwendigkeit noch viel stärker ist, die LLVM Coding Standards und die CppCoreGuidelines empfohlen, sowie die Verwendung von Code-Formattern und statischen Analyzern zur Umsetzung dieser Standards(unter ihnen sind clang-format, clang-tidy und cppcheck).

8. Wie werden Dependencies verwaltet?


Beinahe jedes größere C- oder C++-Projekt verwendet externe Bibliotheken, die das Portieren erheblich erschweren(manchmal selbst das Portieren auf eine andere Linux-Distribution). Daher ist es unumgänglich, sich früh zu entscheiden, auf welchem Wege Dependencies verwaltet werden. Hierfür bieten sich neben unportablen Lösungen wie Paketmanagern gebräuchlicher Linux-Distributionen vor allem Paketmanager für C/C++, wie conan oder buckaroo, an.
Autor
Lowl3v3l
Aufrufe
157
Erstellt am
Letzte Bearbeitung
Bewertung
0,00 Stern(e) 0 Bewertung(en)
Oben Unten