Freetz Build-Prozeß

Vorwort und Motivation

In den HowTos gibt es einige wichtige Informationen darüber, was man mit Make-Targets wie menuconfig, toolchain, precompiled, recover usw. erreichen kann beim Bau einer Freetz-Firmware. Trotzdem gibt es im Forum regelmäßig eine Menge Fragen zum Build-Prozess - meistens, wenn der Prozess nicht durchläuft und der betreffende Benutzer nicht weiß, woran das liegt. Der Grund ist meistens, dass es sich um einen unerfahrenen Benutzer handelt, der mit GNU make keine Erfahrung hat, weil er erstens nicht C/C++-Programmierer ist und/oder zweitens bereits die Linux-Kommandozeile per se ein Buch mit sieben Siegeln für ihn ist. Zumindest Ersteres trifft auf mich auch zu, und deshalb habe ich mich mal oberflächlich eingelesen, um das Makefile von Freetz besser (oder überhaupt) zu verstehen. Das Ergebnis meiner Arbeit dokumentiere ich hier.

Die Probleme der Hilfesuchenden im Forum hören nämlich nicht damit auf, dass der Build manchmal hängen bleibt. Da viele Fragen aus Sicht der Cracks “dumm” klingen, sich häufig wiederholen - nicht jeder ist geschickt darin, die Suchfunktion des Forums oder Google zu benutzen, manche sind auch einfach zu faul - und somit manchen Profis lästig sind, fallen die Antworten entsprechend kurz aus, was wiederum zu Rückfragen und mehr “Müll” im Forum führt. Wenn dann der Hilfesuchende die Ursache des Problems beseitigt hat (Linux-Package nachinstalliert, richtige Option in make menuconfig an-/abgewählt, Patch installiert), bekommt er oftmals den Build trotzdem nicht mehr ans Laufen, weil die Abhängigkeiten nicht hunderprozentig sauber gepflegt sind und er zunächst nochmal ein xy-clean und/oder xy-precompiled aufrufen müsste, ihm das aber keiner gesagt hat, weil es auch schwer vorherzusehen ist.

Der Traum vom perfekten Makefile, das bei jeder Dateiänderung genau das tut, was minimal zu tun wäre, um das aktuelle Target zu bauen, ist grundsätzlich erreichbar, bei uns aber nicht realisiert. Obwohl man sagen muss, daß der Freetz Make-Prozess schon relativ gut ist - nur eben nicht idiotensicher. Das war wohl auch nicht das Ziel, denn ein “Idiot” sollte keine Firmware für seinen DSL-Router bauen wollen. Andererseits ist es aber auch gut für unsere Gemeinschaft, wenn neuen Mitgliedern die Lernkurve etwas angenehmer gestaltet wird. Es ergibt keinen Sinn, dass jeder das Rad neu erfindet und sich alles selbst erarbeitet, nur weil andere das früher hatten tun müssen.

Grundsätzliches

Basis dieser Dokumentation ist Freetz-1.1.4. Da es inzwischen neuere Freetz-Versionen gibt wird an einige Stellen auf Abweichungen hingewiesen.

Was tut make?

Das würde hier wirklich den Rahmen sprengen, daher nur ein paar Links. Sich einzulesen, lohnt sich - Bildung ist nie umsonst:

Woraus besteht Freetz?

Die modifizierte Firmware wird zusammengebaut aus mehreren Komponenten:

Freetz selbst präsentiert sich nach dem Auspacken des entsprechenden Archivs (z.B. freetz-1.1.4.tar.bz2) entsprechend der folgenden alphabetisch, nicht nach Wichtigkeit, sortierten Liste. (Die Unterverzeichnisse build, packages, source werden erst beim ersten Make-Lauf erzeugt.)

Ablauf des Build-Prozesses

Es dürfte allgemein bekannt sein, daß die drei wichtigsten Make-Targets

Daneben gibt es eine beträchtliche Anzahl weiterer Make-Targets, die teilweise nicht direkt im Makefile sichtbar sind, sondern durch automatisierte Ersetzungsvorgänge erzeugt werden. Das hat den Vorteil, daß es z.B. pro Package jeweils die gleichen Sub-Targets gibt und man somit immer die Möglichkeit hat, durch einen Make-Aufruf direkt Einfluß auf einzelne Pakete zu nehmen (z.B. aufräumen, nochmal neu übersetzen). Wenn also make precompiled beispielsweise im Paket mc hängen geblieben ist, weil ein zum Bauen notwendiges Linux-Paket in unserer Distribution gefehlt hat, das wir erst noch per Paketmanager installieren mussten, kann es sein, dass ein erneuter Aufruf des globalen precompiled anschließend trotzdem nicht durchläuft, weil es Inkonsistenzen im Package-Build gibt. Da hilft dann meistens eine Sequenz wie make <Paket>-clean, make <Paket>-precompiled, also z.B. mc-clean und mc-precompiled. Wie die Pakete heißen, sieht man an den Namen der Unterverzeichnisse im Verzeichnis make.

Include-Kette

Es gibt generell zwei Arten, Make für hierarchisch strukturierte Builds zu benutzen. Die eine, althergebrachte, geht von einem Makefile im Hauptverzeichnis und jeweils einem weiteren Makefile pro Unterverzeichnis aus. Daß dies keine gute Idee ist, wird in Recursive Make Considered Harmful überzeugend dargelegt. Die gute Nachricht ist: Freetz verwendet die zweite Methode, und zwar Include-Dateien in den Unterverzeichnissen. D.h., das Makefile lädt die für das aktuelle Target notwendigen Includes dynamisch nach und erzeugt so ein einziges, großes, virtuelles Makefile, welches dann abgearbeitet wird. Das ist schön, führt aber dazu, daß wir im Makefile sehen, wie Dinge aufgerufen und abgearbeitet werden, deren Herkunft nicht ganz so leicht festzustellen ist, wenn man sich nicht im Detail die Verzeichnisstruktur ansieht. Ich versuche hier, das ein wenig transparenter zu machen.

Sonstige Make-Targets

Direkt im Top-Level-Makefile, also nicht inkludiert, sind weitere Targets enthalten.

So, ich hoffe, dieser Artikel bringt dem einen oder anderen Modder etwas. Diskussionen, Feedback, Korrekturen hierzu sind wie immer willkommen und können im zugehörigen Forums-Thread eingebracht werden.

Alexander Kriegisch (kriegaex)
Überarbeitet von Oliver Metz