Development

Aus TuxBoxWIKI
Wechseln zu: Navigation, Suche

Dieser Artikel versucht interessierten Entwicklern oder diejenigen die zur Verbesserung der Tuxbox-oder Coolstream-Software beitragen wollen, Informationen über den Entwicklungsprozess der Software zu geben und Fragen von neuen Entwicklern zu beantworten. Wenn Du uns beim Programmieren helfen willst, aber noch nicht die notwendigen Kenntnisse hast, dürfte dies eine gute Anlaufstelle sein. Bei Fragen hierzu bitte auch die Supportforen oder Mailinglisten verwenden.

Source-Code


Build Documentation

Programmiersprachen

Vorwiegend wird C/C++ verwendet. Für diverse Software oder Tools, die nicht direkt mit der Software oder Treibern für die unterstützen Receivertypen zu tun haben, kann natürlich jede nach Bedarf benötige Sprache verwendet werden. Dies würde beispielsweise einige Tools betreffen, die unter Hostapps im CVS abgelegt worden sind.


Codingstyle

Der Sourcecode von Neutrino ist inzwischen in die Jahre gekommen. Viele Programmierer haben Hand am Source angelegt. Da es nie Maintainer oder besondere Sourcecode Formatierungsregeln gab, ist der Quellcode von Neutrino, und auch der daraus entstandene Quellcode von Neutrino-HD, in unterschiedlichster Weise formatiert. Dies ist für die Lesbarkeit und für das Verständnis des Quellcodes nicht von Vorteil.

Zustand

Der Source der Neutrino Quellen ist zum größten Teil in C++ geschrieben. Es wird aber auch C-Code verwendet. Da teilweise viele Personen an ein und derselben Datei gearbeitet haben kann es innerhalb ein und der selben Datei die unterschiedlichsten Formatierungen geben.
In den sonstigen Dateien wiederum (Shellscripte z.B.) gibt es keine besonderen Unterschiede in den Styles und Formatierungen.

Strukturierung

Für das Formatieren von C/C++ gibt es leicht unterschiedliche Einrückungsstile. Um die Lesbarkeit des Quellcodes zu verbessern sollten Programmierer die in den diversen Dateien arbeiten sich an bestimmte Standards halten. Dies ist kein absolutes Muss, ist aber sehr zuträglich für das Projekt. In anderen GNU Projekten ist die Einhaltung projektspezifischer Standards wegen der Größe dieser Projekte wiederum Pflicht. So zum Beispiel bei der Linuxkernelentwicklung oder beim KDE Projekt.

Modelines

Mit sogenannten Modelines kann man dem Editor seiner Wahl Bearbeitungsoptionen und Anzeigeoptionen mitgeben, sofern dieser dieses Feature unterstützt. Diese Modelines müssen entweder direkt in den bis zu ersten drei Zeilen oder in der letzten Zeile vorhanden sein, allgemein üblich ist am Beginn der Datei. Da historisch bedingt die ersten Editoren reine Text basierende Programme waren bezieht sich der Syntax in der Regel auf Vi/Vim. Eine Modeline (im Beispiel nur in der ersten Zeile) sieht dann z.B. so aus.

// vim:filetype=c:ai:expandtab:tabstop=4:textwidth=72:
//
// file foo.cpp
// The file foo.cpp implements various helper functions.
//
// include <iostream>
// ...
Erläuterung zu den Modeline Angaben
Modelineargument Erklärung
vim: Start der Modelineanweisungen
filetype=c Angabe des Dateityp, hier C Quelletxt
ai autointend, bei Zeilenumbruch automatisierte Einrückung (funktioniert je nach Editor nicht automatisch)
expandtab automatische Erweiterung von Tabulatoranschlägen mit Leerzeichen
tabstop=4 Anzahl von Zeichen die beim benutzen der Tabulatortaste benutzt werden
textwidth=72 automatisierter Umbruch nach dem 72. Zeichen (Tabs werden aufgelöst)

Die Anweisungen der Modeline beginnen im Beispiel mit vim: und werden immer mit einem Doppelpunkt oder auch Leerzeichen getrennt. Zwischen den Kommentarzeichen und dem Beginn der Modeline muss mindestens ein Leerzeichen sich befinden. Genaueres zum Aufbau der Modelines findet man im Wiki vom Vim.

Quelltextformatierungen

Da an Neutrino wohl fast nur Freiwillige arbeiten, ist so eine Forderung nur schwer umzusetzen. Man kann so etwas aber sehr wohl als erstrebenswertes Optimum ansehen und jeder der mitarbeitet, sollte sich so weit es geht an solche Wunschvorgaben halten.

Als ein guter Kompromiss zwischen Lesbarkeit und Platzbedarf hat sich der Stil 1TBS/K&C („One True Brace Style“ von Kernighan und Ritchie) erwiesen. Kurz und kompakt bedeutet das folgendes:

Beispiel Funktionsdeklaration

  • Die öffnende Klammer einer Funktion steht immer an einem Zeilenanfang.
void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
{
...
}
  • Bei vielen Funktionsübergabeparametern sollten an diesen jeweils möglichst die Zeile umgebrochen werden. Eine Zeile sollte nicht mehr wie 72 Zeichen enthalten.
unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
	unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
	unsigned int *offset, enum xfer_buf_dir dir)
{
...
}

Beispiel Schleifen

  • Schleifen können genauso eingefasst werden. Dies kostet aber relativ viel Platz bei zahlreichen einfachen Aktionen, darum folgende Empfehlung die öffnenden Klammer direkt nach der Bedingung von Schleifen, if...then...else...-Steuerpaaren usw. zu setzen mit der schließenden Klammer vor der nächsten Bedingung. Dieser Stil wird auch in der Kernelentwicklung angewandt und ist sehr gebräuchlich.
if(( hp = gethostbyname( host )) != NULL ) {
	memmove( &taddr->sin_addr, hp->h_addr_list[0], sizeof( taddr->sin_addr ));
	taddr->sin_port = 0;
	taddr->sin_family = AF_INET;
} else if ( inet_aton( host, &taddr->sin_addr ) == 0 ) {
	return -1;
}
  • Das Gegenstück dazu ist, jede Klammer separat in eine Zeile zu setzen was zwar nicht platz sparend ist, aber die Lesbarkeit des Quellcodes welcher logisch zusammen gehört, wird dabei erhöht. Der selbe Quellcode würde dann so aussehen.
if(( hp = gethostbyname( host )) != NULL )
{
	memmove( &taddr->sin_addr, hp->h_addr_list[0], sizeof( taddr->sin_addr ));
	taddr->sin_port = 0;
	taddr->sin_family = AF_INET;
}
else if( inet_aton( host, &taddr->sin_addr ) == 0 )
{
	return -1;
}
  • Letztendlich gilt aber auch hier: Benutzt den Stil den Ihr in der Datei vorfindet!
  • Die Einrückungstiefe (Tabulator) sollte aus vier Zeichen bestehen. Acht Zeichen sind allerdings auch o.k. Innerhalb einer Datei sollte aber immer die selbe Einrückungstiefe benutzt werden.
  • Hier ist zu beachten das je nach verwendeten Editor und dessen Einstellungen unterschiedliche Effekte auftreten können. Die meisten Editoren bieten an eine Tabeinrückung mit der entsprechenden Leerzeichenanzahl aufzufüllen . Kontrolliert Eure Einstellung im Editor.
  • Massives oder sogar vollständiges Verändern von Dateien, nur um die obigen Punkte zu erreichen (z.B. durch Tools wie astyle), sind daher grundsätzlich zu vermeiden! Dadurch geht die komplette Historie zu dieser Datei zwar nicht verloren, wird aber stark beeinträchtigt, so dass z.B. Blame-Tools unter Umständen wenig oder keine brauchbaren Daten liefern könnten. Die Historie ist aber bei der Einkreisung von Programmierfehlern teilweise sehr hilfreich! Es sollten daher nur die Stellen vereinzelt nebenher verändert werden, an denen man gerade Veränderungen durchführen will.

Kommentare

Kommentare sind wichtige Bestandteile des Quellcodes! Nutzt diese Möglichkeit der Informationsweitergabe.

Gemessen an vielen C++ Projekten wie sie zB. auf Openhub (früher Ohloh) analysiert werden, sind durchschnittlich 22% aller Quellcode-Zeilen Kommentare. Für Neutrino-HD liegt dieser Wert nur bei 12% und hat damit eine der niedrigsten Quoten, die offiziell bestätigt sind.

Eine hohe Anzahl von Kommentaren könnte darauf hindeuten, dass der Code gut dokumentiert und organisiert ist, und könnte ein Zeichen für teamfähige Mitglieder, ein hilfreiches und diszipliniertes Entwicklungsteam sein.

Leider sind Kommentare in Neutrino und Neutrino-HD aktuell in der Tat sehr spärlich im Code. Es muss nicht jede Subroutine erklärt werden, aber ein Kommentar zu einer Funktion, der Funktionsweise und deren Rückgabewerte sollte aber selbstverständlich sein.

  • In internationalen Projekten sind Kommentare in Landessprache des Entwickler verpönt! Üblich und eine von jeden Programmierer verstandene Sprache ist Englisch, also bitte alle Kommentare in Englisch verfassen.
  • Kommentare über mehr wie eine Zeile sollten mit /* ... */ eingefasst und einzeilige Kommentare können mit // begonnen werden, üblich ist aber auch wieder die Einfassung mit /* ... */. Kommentare sollten entweder der einzige Inhalt einer Zeile sein oder am Ende einer Codezeile stehen aber niemals mitten im Code (was theoretisch auch geht).
/*
 * draw_line
 * 
 * args:
 * x1    StartCol
 * y1    StartRow
 * x2    EndCol
 * y1    EndRow
 * state LCD_PIXEL_OFF/LCD_PIXEL_ON/LCD_PIXEL_INV
 * 
 */

oder

if ((fd = open(LCD_DEVICE, O_RDWR)) < 0) {
	perror("LCD (" LCD_DEVICE ")"); //giving out an error message
...

folgendes ist auch gebräuchlich

if ((fd = open(LCD_DEVICE, O_RDWR)) < 0) {
	perror("LCD (" LCD_DEVICE ")"); /* giving out an error message */
...

Debugausgaben

Ausgabe von Debugmeldungen sind ein wichtiges Hilfsmittel bei der Entwicklung. Für den normalen Betrieb sind diese Debugausgaben jedoch auf die wichtigsten Meldungen zu minimieren. Gerade hier kann Neutrino-HD noch deutlich verbessert werden. Einfache printf Ausgaben sind für die eigene Entwicklung o.k. sollten aber nicht in ein Versionsverwaltungssystem eingecheckt werden.


Bugtracking

Code Changes/Source code Repositories

Aktuelle Änderungen lassen sich in den jeweiligen Mailinglisten verfolgen oder in den Logs der jeweiligen Repositories (siehe folgende Liste).

Buildsysteme

Neutrino-HD

Libs

Multiplatform


Coolstream


Driver

Coolstream


Tuxbox-SD

Dokumentation

Die Dokumentation, die vor allem dem Benutzer die Funktionsweise der Betriebssoftware vermitteln soll, findet sinvollerweise hier im TuxBoxWIKI statt.


Jeder Entwickler ist daher angehalten, entsprechende Änderungen, Ergänzungen usw. zeitnah zu den eingetragenen Änderungen zu dokumentieren, oder zumindest einem TuxBoxWIKI-Autor oder Sysop mitzuteilen, damit diese den Weg auch zum Benutzer findet und keine Lücken entstehen!.

Die Quellcode-Dokumentation sollte direkt im Sourcecode-erfolgen. Dies ist in der Vergangenheit leider nicht immer in dem Maße erfolgt, wie man es gerne gehabt hätte, so dass es hier leider nicht immer so einfach ist, möglichst schnell einzusteigen. Einen wesentlichen Schritt zur Verbesserung im dBox2-Bereich trug die Einführung von Newmake bei, wodurch zumindest der Aufbau einer Entwicklungsumgebung besser gelingen sollte. Im Coolstream-Bereich wurde zumindest im Bereich der Buildsysteme gute Arbeit geleistet. Im Bereich Neutrino-HD gibt es Nachholbedarf.


CVS/GIT Zugang


Stop hand.png Bitte beachten!
Bei den Git-Repositories sind Anfragen zu Schreibzugängen nicht zwingend notwendig, da man dort dank der dezentralen Struktur von Git, üblicherweise formatierte Patche erzeugt oder in bestimmten Fällen Merge-Requests macht, welche man direkt dem Maintainer der jeweiligen Repos oder einem Entwickler per EMail zukommen lassen kann. Bei Gitorious gibt es diese Funktion direkt auf der Web-Oberfläche bzw. kann seine Änderungen direkt per E-Mail dorthin verschicken! Nähere Informationen, wie man solche Patch-E-Mails erstellt findest Du hier. Aus diesem Grund ist es üblich, dass sich jeder Entwickler mit gültigen EMail-Adressen in seinen Commits zu erkennen gibt. Fake-Adressen oder Aliaseinträge sind eher schlechter Stil [1]'

Coolstream-GIT

GIT-Buildsysteme:

GIT-Novatux


Patch einreichen

Wer einen Patch zur Verfügung stellen möchte, kann dies natürlich gerne tun. Hierfür kannst du die Anhangsfunktion in den Boards, Mailinglisten oder Upload-Server nutzen. Bitte auch entsprechende Erläuterungen dazu machen (sollte klar sein). Eine Patchdatei sollte auch so benannt werden, dass man sie auch zuordnen kann. Dies kann mit einem Zeitstempel und/oder der Revisionsnummer und den Namen der damit zu patchenden Dateien erfolgen.

Siehe dazu auch Git Patch erstellen!

Beispiele:

  • Ordner src:
src-diff-2011-10-05-10-40-09.patch
  • Dateien neutrino.cpp und neutrino.h
neutrino.cpp_neutrino.h-diff-2011-10-05-10-40-09.patch

Einige IDE's oder auch SCM-UI's bieten die Möglichkeit an, passende Namen erzeugen zu lassen. Man kann sich auch eigene Scripte dafür anfertigen, die das übernehmen. Mit Git werden Patche meist aus Git-Commits mit eigenen Tools erzeugt und speziell formatiert, so dass das Handling hier generell einfacher sein dürfte.

Mailinglisten


Stop hand.png Bitte beachten, die internen Listen sind privat geführt und auch als solche zu verstehen. Es ist zwar möglich sich dort anzumelden, aber man wird nicht in jedem Fall registriert!

Öffentlich

Intern

Boards


Weblinks