Aus Linux-Magazin 07/2006

Dietlibc minimiert den Speicherbedarf von C-Programmen

© photocase.com

Wo jedes Byte zählt, speckt Dietlibc das System ab: Die überschaubare C-Bibliothek ersetzt die Standard-Glibc und macht C-Programme fit für den Einsatz auf Embedded-Systemen mit minimalen Ressourcen.

Auf einer Workstation kommt es auf ein paar hundert KByte mehr oder weniger nicht mehr an. Anders sieht es dagegen aus, wenn minimale Hardware zum Einsatz kommt, ein wichtiger Bereich dafür sind Embedded Systems. Hier stößt man schnell an die Grenzen, einfache Spezialprogramme dürfen daher nicht mehr Speicher beanspruchen, als unbedingt notwendig ist.

Die Basis fast aller Linux-Programme ist die C-Bibliothek des Systems, die fundamentale Ein- und Ausgabefunktionen sowie andere häufig benötigte Operationen bereitstellt. Meist kommt dafür die GNU-C-Library Glibc zum Einsatz, die zwar reich an Funktionalität, aber mit mehr als 2 MByte auch sehr groß ist. Bei dynamisch gelinkten Programmen lädt das System diese 2 MByte vollständig in den Hauptspeicher. Auch statisches Linken bietet keinen wesentlich sparsameren Ausweg, selbst ein klassisches “Hallo Welt” in C verbraucht 400 KByte, obwohl es nur einen kleinen Teil der Glibc-Funktionalität verwendet.

Für Linux gibt es zwei alternative C-Bibliotheken, die deutlich weniger Speicher beanspruchen und sich deshalb besonders für den Einsatz in Embedded-Systemen eignen. Eine davon heißt Uclibc (Micro Clibc, [4]), deren Autoren Code aus bereits existierenden C-Bibliotheken zusammengetragen und optimiert haben. Mit Uclibc erzeugte Binaries fallen zwar deutlich kleiner aus als die der Glibc, sind aber oft immer noch keine Winzlinge.

Bei Dietlibc [1] handelt es sich um ein jüngeres Projekt mit dem Ziel, optimierte Binaries zu erzeugen und dabei übersichtlich und somit wartbar zu bleiben. Dazu haben Felix von Leitner und seine Helfer Dietlibc von Grund auf neu geschrieben. Übersetzt wiegt sie gerade einmal 500 KByte. Der größte Platzgewinn resultiert aus einer sehr geringen Affinität der verschiedenen Module des Dietlibc-Code untereinander: “Hallo Welt” benötigt statisch gelinkt nur noch 1,3 KByte.

Diät für C-Programme

In puncto Funktionalität beschränkt sich Dietlibc auf das Wesentliche. Für den geringen Speicherbedarf sorgen der Verzicht auf komplexe Algorithmen sowie die Minimierung wechselseitiger Abhängigkeiten der unterschiedlichen Funktionen. Darüber hinaus stellen Linker-Tricks sicher, dass ausschließlich die verwendeten Funktionen ins Programm gelangen; damit schrumpft beispielsweise der Exit-Code, falls »atexit()« nicht zum Einsatz kommt.

Als C-Bibliothek hält sich die Dietlibc wie die Glibc an die Ansi-Standards. Deshalb sind die beiden Bibliotheken auch weitgehend austauschbar, die erneute Kompilation der Software vorausgesetzt. Über Ansi C hinaus implementiert Dietlibc auch SUS v2 (Single Unix Specification) und weitere Posix-Standards.

Erweiterungen

Da sich viele Programmierer an BSD-Eigenheiten gewöhnt haben oder sich auf die nicht zum C-Standard gehörenden GNU-Erweiterungen verlassen, bietet Dietlibc zusätzliche Type-Definitionen durch die Defines »_BSD_SOURCE« und »_GNU_SOURCE«. Funktionale Erweiterungen wie »getline()« oder »daemon()« lagert Dietlibc in eine separate Bibliothek namens Libcompat aus. Wer seinen C-Code ohne Modifikationen übersetzen möchte, sollte diese Defines und Libcompat immer einbinden, indem er den Compiler-Optionen die Parameter »-D_BSD_SOURCE«, »-D_GNU_SOURCE« und »-lcompat« hinzufügt.

Weitere Eigenschaften der Dietlibc sind über die Datei »dietfeatures.h« konfigurierbar. Einige Programme verlassen sich darauf, dass »malloc(0)« einen gültigen Pointer liefert, dessen Speicherbereich sich später mit »realloc()« vergrößern lässt. Dies Verhalten entspricht zwar nicht Ansi C 99; wer aber will, aktiviert es mit »WANT_MALLOC_ZERO«. Derartige Erweiterungen des C-Standards haben die Dietlibc-Entwickler in der Voreinstellung ausgeschaltet, damit Programmierer neuer Software sie nicht unwissentlich nutzen und die Portierung ihrer Codebasis erschweren.

Nach dem Entpacken des Dietlibc-Pakets übersetzt »make« den Code. Dabei zeigt sich bereits der Größenunterschied zu Glibc: Der Kompiliervorgang nimmt nur wenige Minuten in Anspruch, bei Glibc selbst auf neuen Rechnern fast eine Stunde. Wer Dietlibc für eine fremde Plattform kompiliert, erreicht das mit:

make ARCH=arm CROSS=arm-linux-

Die Installation erledigt anschließend »make install«. Die Bibliothek und die Headerdateien landen standardmäßig im Verzeichnis »/opt/diet«. Außerdem ist das Programm »diet« enthalten. Dabei handelt es sich um einen Wrapper, der die Include-Pfade, die C-Bibliothek sowie die Start- und Stopp-Objekte einfügt. Letztere kümmern sich um den Startcode sowie den Umgang mit »atexit()« und behandeln – falls konfiguriert – Konstruktoren und Destruktoren in objektorientierten Programmen.

Wer ein neues Programm statt mit Glibc mit Dietlibc verlinken will, verwendet den folgenden Compiler-Aufruf, Abbildung 1 zeigt das Resultat:

diet gcc -Os -o hallo hallo.c

Der Wrapper ist erforderlich, weil der Compiler sonst die systemweite C-Bibliothek verwendet, also gewöhnlich Glibc. Ohne ihn müsste man alle benötigten Optionen bei jedem Compiler-Aufruf manuell hinzufügen oder einen zweiten, entsprechend modifizierten GCC installieren; diesen Weg beschreitet beispielsweise Uclibc.

Bei auf Autoconf basierenden Paketen reicht folgender Aufruf, um ein passendes Makefile zu erzeugen:

CC="diet -Os gcc -D_GNU_SOURCE -D_BSD_USOURCE" ./configure

Für einige Architekturen wie x86, x86-64 und ARM unterstützt die Dietlibc bereits dynamische Bibliotheken. Dazu ist Dietlibc mit »make dyn« zu kompilieren. Nach der Installation steht zusätzlich der Wrapper »dyn-diet« bereit, der äquivalent zu »diet« funktioniert.

Die Unterstützung für dynamische Bibliotheken befindet sich jedoch noch im Experimentierstadium und ist darum mit Vorsicht zu genießen. Damit erzeugte Binaries sollte der Programmierer ausgiebig testen, bevor sie in den produktiven Einsatz kommen.

Auch die mathematische Bibliothek Lib-M ist für einige Architekturen noch nicht vollständig implementiert. Im typischen Einsatzgebiet der Dietlibc, in Embedded-Systemen, spielen ihre Funktionen glücklicherweise ohnehin kaum eine Rolle.

Abbildung 1: Mit Dietlibc kompilierte Programme beanspruchen im Vergleich zu Glibc nur einen Bruchteil des Speichers. Bei Verwendung von »gcc -Wall« weisen Warnings auf mögliches Sparpotenzial hin.

Abbildung 1: Mit Dietlibc kompilierte Programme beanspruchen im Vergleich zu Glibc nur einen Bruchteil des Speichers. Bei Verwendung von »gcc -Wall« weisen Warnings auf mögliches Sparpotenzial hin.

C++ mit Embedded STL

Da die in GCC enthaltene Standard Template Library (STL) für C++ gegen die C-Bibliothek des Systems gelinkt wird, lassen sich C++-Programme allerdings nicht ohne weiteres gegen die Dietlibc linken; dazu müsste man die gesamte STL erneut übersetzen. Eine wesentlich einfachere, aber noch unvollständige Lösung entsteht mit dem Projekt Embedded STL [5]. Analog zur Dietlibc implementiert diese Bibliothek eine minimale Standard Template Library mit geringem Platzbedarf.

Die Konstruktoren und Destruktoren von C++-Objekten funktionieren jedoch nur bei einer mit der Option »WANT_DYNAMIC« kompilierten Dietlibc, auch wenn der Programmierer nur statische Binaries erzeugen will. Zurzeit implementiert Embedded STL jedoch nicht den gesamten Umfang der C++-STL, es fehlen einige Container und Algorithmen. Im Embedded-Bereich kommt sie dennoch schon erfolgreich zum Einsatz. Auch Hotplug++, die C++-Implementation des Hardware-Managers, verwendet Embedded STL bereits.

Für eingebettete Systeme liegen auch optimierte, Ressourcen-sparende Versionen der unumgänglichen Unix-Tools vor. Neben der recht bekannten Sammlung Busybox [6], die die umfangreicheren Binutils ersetzt, gibt es optimierte Versionen von Init-Systemen, HTTP-Servern, Shells, Grep, Sed und vielem mehr. Vollständige Listen enthalten die Seiten von Dietlibc [1] und Uclibc [4].

Wer sich entschieden hat, ein Projekt mit Dietlibc zu realisieren, möge sich auch die Patches des T2-Projekts [3] ansehen. Sie enthalten neben wichtigen Bugfixes auch Korrekturen für exotischere Architekturen sowie Patches für andere Open-Source-Pakete.

Fazit

Dietlibc verringert in Umgebungen mit begrenzten Ressourcen den Bedarf an Speicherplatz sowohl auf dem Datenträger als auch im Hauptspeicher erheblich. Das ermöglicht es, Linux auch auf Systemen mit äußerst knappen Kapazitäten einzusetzen. Auch auf sicherheitskritischen Serversystemen sollten Admins den Einsatz der Dietlibc in Betracht ziehen, da die schlanke C-Bibliothek wegen des geringeren Code-Umfangs einfacher als die Glibc zu evaluieren ist.

Viele Distributionen setzen außerdem in ihren Initial-RAM-Disks (Initrd) und Installationsumgebungen schon länger auf Dietlibc, weil damit kompilierte Programme auch schneller starten als die Glibc-Kollegen. (csc)

Infos

[1] Dietlibc: [http://www.fefe.de/dietlibc]

[2] Weitere Dietlibc-Informationen: [http://www.fefe.de/dietlibc/diet.pdf]

[3] Patch-Sammlung für Dietlibc: [http://www.t2-project.org/packages/dietlibc.html]

[4] Uclibc: [http://www.uclibc.org]

[5] Embedded STL: [http://www.exactcode.de/embeddedSTL]

[6] Busybox: [http://www.busybox.net]

[7] Single Unix Specification: [http://de.wikipedia.org/wiki/Single_Unix_Specification]

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 2 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben