JamesRaynardContributed by MurrayStokelyDirkArltÜbersetzt von FabianBorschelWerkzeuge zur ProgrammierungÜberblickDieses Kapitel ist eine Einführung in die Benutzung
einiger der Werkzeuge zur Programmierung, welche mit FreeBSD
ausgeliefert werden. Trotzdem ist vieles auch auf verschiedene
andere Versionen von &unix; übertragbar. Dieses Kapitel
soll kein Versuch sein Programmierung
detailliert zu beschreiben. Der größte Teil dieses
Kapitels setzt wenige oder gar keine Programmierkenntnisse
vorraus, dennoch sollten die meisten Programmierer etwas
Sinnvolles darin finden.ZusammenfassungFreeBSD bietet eine exzellente Entwicklungsumgebung.
Compiler für C, C++, sowie für Fortran und ein
Assembler sind im Basissystem enthalten. Natürlich finden
sich auch ein Perl-Interpreter und klassische &unix;-Werkzeuge
wie sed und awk. Sollte
das nicht genug sein, finden sich zahlreiche weitere Compiler
und Interpreter in der Ports-Sammlung. FreeBSD ist kompatibel zu
vielen Standards wie &posix; und
ANSI C, sowie zu seinem eigenen BSD-Erbe. So
ist es möglich Anwendungen zu schreiben, welche ohne oder
zumindest ohne wesentliche Änderungen auf einer
großen Zahl an Plattformen kompilieren und laufen
werden.Allerdings können all diese Möglichkeiten
anfangs etwas überwältigend sein, wenn Sie vorher nie
Programme auf einem &unix;-System geschrieben haben. Dieses
Dokument hat die Zielsetzung ihnen beim Einstieg zu helfen ohne
allzu weit in fortgeschrittene Themen vorzudringen. Die
Intention ist, daß dieses Dokument ihnen ausreichend
Basiswissen vermittelt und die weitergehende Dokumentation
sinnvoll nutzen zu können.Der größte Teil dieses Dokuments erfordert wenige
oder gar keine Kenntnisse in der Programmierung, es werden
trotzdem Basiswissen im Umgang mit &unix; und die Bereitschaft
zu lernen vorrausgesetzt!Einführung in die ProgrammierungEin Programm ist eine Zusammenstellung von Anweisungen, die
den Computer auffordern verschiedenste Dinge zu tun. Dieser
Abschnitt gibt ihnen einen Überblick über die beiden
wesentlichen Methoden diese Anweisungen oder
Befehle, wie man diese Anweisungen
üblicherweise nennt, zu geben. Die eine Methode nutzt einen
interpreter, die andere einen
Compiler. Da die menschliche Sprachen
für einen Computer nicht unmissverständlich sind,
werden diese Befehle in einer Sprache geschrieben die speziell
für diesen Zweck gedacht ist.InterpreterMit einem Interpreter ist die die Sprache vielmehr eine
Umgebung, in der Sie ein Kommando an der Kommandozeile
eingeben welches dann von der Umgebung ausgefürt wird.
Für kompliziertere Programme können Sie die Befehle
in eine Datei schreiben und den Interpreter dazu bringen diese
Datei zu laden und die enthaltenen Befehle auszuführen.
Falls etwas schief geht werden viele Interpreter Sie an einen
Debugger weiterleiten.Der Vorteil hierbei ist, das Sie das Ergebnis ihres
Befehls direkt sehen und Fehler sofort korrigiert werden
können. Der größte Nachteil bei dieser Methode
entsteht, wenn Sie ihr Programm mit jemandem teilen wollen.
Diese Person muss den selben Interpreter nutzen wie Sie es tun
und Sie muss wissen wissen wie Sie dieser zu bedienen ist.
Zudem werden Benutzer es nicht begrüßen sich in
einem Debugger wiederzufinden, wenn Sie einmal die falsche
Taste drückten! Bei einem Blick auf die
Leistungsfähigkeit brauchen Interpreter oftmals viel
Speicher und erzeugen den Code nicht so effizient wie
Compiler.Meiner Meinung nach sind interpretierte Sprachen der beste
Anfang, wenn Sie bisher noch nicht programmiert haben. Diese
Art von Umgebung findet man typischerweise bei Sprachen wie
Lisp, Smalltalk, Perl und Basic. Man köte auch sagen,
dass die &unix; Shell (sh,
csh) für sich bereits einen
Interpreter darstellt und viele Leute schreiben
tatsächlich Shell Scripten um sich bei
einigen Haushaltsaufgaben auf ihren Maschinen
helfen zu lassen. Tatsächlich war es ein wesentlicher
Teil der originalen &unix; Philosophie eine große Zahl
an kleinen Hilfsprogrammen zur Verügung zu stellen,
welche mittels eines Shell Sripts miteinander kombinter werden
um bestimmte Aufgaben zu übernehmen.Für FreeBSD verfügbare InterpreterIm folgenden eine Liste der über die &os;
Ports-Sammlung verfügbaren Interpreter
einschlißlich einer kurzen Erörterung der
populären interpretierten Sprachen.Anleitungen wie man Anwendungen aus der Ports-Sammlung
erhät und installiert können Sie dem Kapitel Benutzen der
Ports-Sammlung aus dem FreeBSD Handbuch
entnehmen.BASICKurz für Beginner's All-purpose Symbolic
Instruction Code. Entwickelt in den 50er Jahren um
Studenten in Programmierung zu unterichten, wurde
BASIC in den 80er Jahren mit jedem
anständigen Personal Computer ausgeliefert und war
für vielee Programmierer die erste
Programmiersprache. BASIC ist auch
die Grundlage für Visual Basic.Der Bywater Basic Interpreter findet sich in der
Ports-Sammlung unter lang/bwbasic und Phil
Cockroft's Basic Interpreter (auch bekannt als Rabbit
Basic) findet sich unter lang/pbasic.LispDiese Sprache wurde in den späten 50er Jahren
als Alternative zu den, zu dieser Zeit polpulären,
zahlenverarbeitenden Sprachen entwickelt.
Anstelle auf Zahlen basiert Lisp auf Listen;
tatsächlich ist der Name Lips eine Kurzform
für List Processing (Listen
abarbeiten). Sehr populär fü
AI (Artificial Intelligence/
künstliche Intelligez) (Fach-) Kreisen.Lisp ist eine extrem kraftvolle und durchdachte
Sprache, kann aber auch recht gross und unhandlich
sein.Zahlreiche Ausformungen von Lisp, die auf &unix;
Systemen laufen sind über die Ports-Sammlung
verfügbar. GNU Common Lisp befindet sich in
lang/gcl. CLISP von
Bruno Haible und Michael Stoll ist in lang/clisp zu finden. Für
CMUCL, welches auch einen hoch-optimierten Kompiler
enthält, oder einfachere Ausformungen wie SLisp,
das die meisten gängigen Lisp Konstrukte in wenigen
hundert Zeilen C Code enthält sind in lang/cmucl und lang/slisp ebenfalls
enthalten.PerlUnter Systemadministratoren zum Schreiben von
Skripten sehr beliebt; wird häufig auch auf World
Wide Web Servern verwendet, um
CGI-Skripte zu schreiben.Perl ist in der Ports-Sammlung unter lang/perl5 für alle
&os;-Versionen verfügbar, und wird im Basissystem
von 4.x als /usr/bin/perl
installiert.SchemeEin Dialekt von Lisp, der kompakter und sauberer
als Common Lisp ist. Dieser Dialekt ist an
Universitäten sehr beliebt, da er zum einen
für den Unterricht im Grundstudium einfach genug
ist, und zum anderen ein ausreichend hohes
Abstraktionsniveau für den Einsatz in der Forschung
bietet.Scheme ist in der Ports-Sammlung in Form des Elk
Scheme Interpreters als lang/elk verfügbar. Den
MIT Scheme Interpreter findet man unter lang/mit-scheme, und den SCM
Scheme Interpreter unter lang/scm.IconIcon ist eine Hochsprache mit ausgereiften
Möglichkeiten zur Verarbeitung von Zeichenketten
und Strukturen. Die unter &os; verfügbare Version
von Icon steht in der Ports-Sammlung unter lang/icon zur
Verfügung.LogoLogo ist eine leicht zu erlernende
Programmiersprache, welche in vielen Kursen als
einführende Programmiersprache gewählt wird.
Sie ist ein ideales Arbeitswerkzeug beim Unterricht mit
jungen Menschen, da mit ihr die Erstellung komplizierter
geometrischer Oberflächen selbst für kleine
Kinder einfach ist.Die für &os; aktuellste, verfügbare
Version findet man in der Ports-Sammlung unter lang/logo.PythonPython ist eine objektorientierte, interpretierte
Programmiersprache. Die Verfechter von Python
argumentieren, daß sie eine der besten
Programmiersprachen für Programmieranfänger
sei, da sie einfach zu erlernen ist, und anderen
populären interpretierten Programmiersprachen,
welche zur Entwicklung großer und komplexer
Anwendungen verwendet werden, in nichts nachsteht (Perl
und Tcl sind zwei solcher bekannten
Programmiersprachen).Die aktuellste Version von Python ist in der
Ports-Sammlung unter lang/python
verfügbar.RubyRuby ist eine interpretierte und rein
objektorientierte Programmiersprache. Sie wurde wegen
ihrer leicht verständlichen Syntax, ihrer
Flexibilität und der Möglichkeit, große und
komplexe Programme einfach zu entwickeln und zu pflegen,
populär.Ruby ist in der Ports-Sammlung unter lang/ruby18
verfügbar.Tcl und TkTcl ist eine einbettbare, interpretierte
Programmiersprache, welche aufgrund ihrer Portierbarkeit
auf viele unterschiedliche Plattformen eine weite
Verbreitung erfahren hat. Sie kann sowohl für die
schnelle Entwicklung kleinerer Prototypen, als auch (in
Verbindung mit Tk, einem GUI Toolkit) vollwertiger,
ausgereifer Programme verwendet werden.Es sind mehrere Versionen von Tcl als Ports
für &os; verfügbar. Die aktuellste Version,
Tcl 8.4, ist unter lang/tcl84
verfügbar.CompilerCompiler sind eher anders. Zuerst schreibt man seinen
Code unter Verwendung eines Editors in eine Datei (oder
mehrere Dateien). Anschließend ruft man den Compiler auf
um zu sehen, ob dieser das Programm annimmt. Wenn das Programm
nicht kompiliert werden konnte, muß man die Zähne
zusammenbeissen und wieder zum Editor zurückkehren; falls
das Programm kompiliert und eine ausführbare Anwendung
erzeugt wurde, kann man diese über eine
Eingabeaufforderung oder über einen Debugger aufrufen um
zu sehen, ob sie auch funktioniert.
Wenn die Anwendung über eine Eingabeaufforderung
gestartet wird könnte bei Auftreten eines
Programmfehlers dieses abgebrochen und ein Speicherabbild
erzeugt werden.Offensichtlich ist diese Art der Programmierung nicht
so direkt wie die Verwendung eines Interpreters. Jedoch sind
auf diese Weise viele Dinge möglich, die mit einem
Interpreter nur sehr schwer oder überhaupt nicht
realisierbar wären, wie z.B. das Schreiben von Code, der
sehr eng mit dem Betriebsystem zusammen arbeitet—oder
das Schreiben eines eigenen Betriebsystems selbst! Des
weiteren ist so das Erzeugen von sehr effizientem Code
möglich, da sich der Compiler für die Optimierung
Zeit nehmen kann, was bei einem Interpreter inakzeptabel
wäre. Ferner ist das Verbreiten von Programmen, welche
für einen Compiler geschrieben wurden, einfacher als
welche, die für einen Interpreter geschrieben
wurden—man muss in ersterem Fall nur die
ausführbare Datei verbreiten, vorrausgesetzt das das
gleiche Betriebssystem verwendet wird.Programmiersprachen, die kompiliert werden, sind unter
anderem Pascal, C und C++. C und C++ sind eher unbarmherzige
Programmiersprachen und daher eher für erfahrene
Programmierer gedacht; Pascal auf der anderen Seite wurde zu
Ausbildungszwecken entworfen, und stellt daher eine
einsteigerfreundliche Programmiersprache dar. FreeBSD
beinhaltet im Basissystem keine Unterstützung für
Pascal, stellt jedoch über die Ports-Sammlung sowohl den
GNU Pascal Compiler (GPC) wie auch den Free Pascal Compiler
unter lang/gpc bzw.
lang/fpc zur
Verfügung.Da der editier-kompilier-ausführ-debug-Kreislauf
unter Verwendung mehrerer Programme eher mühsam ist haben
viele Hersteller von Compilern integrierte
Entwicklungsumgebungen (Integrated Development Environment;
auch kurz IDE) entwickelt. FreeBSD bietet
zwar im Basissystem keine IDE an, stellt jedoch über die
Ports-Sammlung IDEs wie devel/kdevelop oder
Emacs zur Verfügung, wobei
letztere weit verbreitet ist. Die Verwendung von
Emacs als IDE wird unter diskutiert.Kompilieren mit dem ccDieser Abschnitt behandelt ausschließlich den GNU
Compiler für C und C++, da dieser bereits im Basissystem
von FreeBSD enthalten ist. Er kann mittels cc
oder gcc aufgerufen werden. Die Details zur
Erstellung einer Anwendung mit einem Interpreter variieren
zwischen verschiedenen Interpretern mehr oder weniger stark, und
werden meist ausführlich in der zugehörigen
Dokumentation oder Online-Hilfe beschrieben.Sobald
Sie Ihr Meisterwerk fertig geschrieben haben besteht der
nächste Schritt darin, dieses (hoffentlich!) unter FreeBSD
zum Laufen zu bekommen. Dies beinhaltet üblicherweise
mehrere Schritte, wobei jeder einzelne Schritt von einem
separaten Programm durchgeführt wird.Aufbereiten Ihres Quelltextes durch Entfernen von
Kommentaren, sowie weiteren Tricks wie das Ersetzen von
Macros in C.Überprüfen der Syntax Ihres Quelltextes, um
die Einhaltung der Sprachregeln sicherzustellen. Wenn Sie
diese verletzt haben werden entsprechende Fehlermeldungen
Ihnen dies mitteilen!Übersetzen des Quelltextes in Assemblersprache
—diese ist dem eigentlichen Maschinencode schon sehr
nahe, jedoch immer noch für Menschen lesbar.
Angeblich.
Um genau zu sein übersetzt der
cc den Quelltext an dieser Stelle
nicht in Assemblersprache, sondern in seine eigene,
maschinenunabhängige Sprache namens
p-code.Übersetzen der Assemblersprache in
Maschinencode—genau, wir sprechen hier von Bits und
Bytes, Einsen und Nullen.Überprüfen, ob Sie Dinge wie Funktionen und
globale Variablen in einheitlicher Weise verwendet haben.
Wenn Sie z.B. eine nicht existierende Funktion aufgerufen
haben, wird eine entsprechende Fehlermeldung Ihnen dies
mitteilen.Wenn aus mehreren Quelltextdateien eine
ausführbare Datei erstellt werden soll wird
herausgefunden, wie die einzelnen Codeteile
zusammengefügt werden müssen.Ausarbeiten, wie das Programm aussehen muss, damit
der Lader zur Laufzeit des Systems dieses in den Speicher
laden und ausführen kann.Endgültiges Schreiben der ausführbaren Datei
in das Dateisystem.Das Wort kompilieren wird häufig
für die Schritte 1 bis 4 verwendet—die anderen werden
mit dem Wort verlinken zusammengefasst.
Manchmal wird Schritt 1 auch als
Pre-Processing und die Schritte 3-4 als
assemblieren bezeichnet.Glücklicherweise werden alle diese Details vor Ihnen
verborgen, da cc ein Frontend ist, welches
sich um die Ausführung all dieser Programme mit den
richtigen Argumenten für Sie kümmert; einfaches
eingeben von&prompt.user; cc foobar.cführt zur Übersetzung von
foobar.c durch alle bereits erwähnten
Schritte. Wenn Sie mehr als eine Datei übersetzen wollen
müssen Sie etwas wie folgt eingeben&prompt.user; cc foo.c bar.cBeachten Sie, daß die Überprüfung der Syntax
genau dies tut—das reine Überprüfen der Syntax.
Es findet keine Überprüfung bzgl. logischer Fehler
statt, die Sie vielleicht gemacht haben, wie z.B. das Programm
in eine Endlosschleife zu versetzen, oder Bubble Sort zu
verwenden, wenn Sie eigentlich Binary Sort benutzen wollten.
Falls Sie es nicht wußten, Binary Sort ist, im
Gegensatz zu Bubble Sort, eine effektive Möglichkeit,
Dinge zu sortieren.Es gibt haufenweise Optionen für cc,
die alle in der zugehörigen Manualpage beschrieben werden.
Im Folgenden werden ein paar der wichtigesten Optionen mit
Beispielen ihrer Anwendung gezeigt.Die Name der Ausgabedatei. Wenn Sie diese Option nicht
verwenden erstellt cc eine Datei mit
dem Namen a.out.
Der Grund dafür ist im Haufen der Geschichte
begraben.&prompt.user; cc foobar.cexecutable is a.out
&prompt.user; cc -o foobar foobar.cexecutable is foobarDies kompiliert die Datei nur, verlinkt sie jedoch
nicht. Nützlich für Spielereien, um die Syntax
auf Korrektheit zu überprüfen, oder falls Sie
ein Makefile verwenden.&prompt.user; cc -c foobar.cDieser Befehl erzeugt eine
Objektdatei (nicht ausführbar)
mit den Namen foobar.o. Diese kann
mit anderen Objektdateien zusammen zu einer
ausführbaren Datei verlinkt werden.Diese Option erzeugt die Debug-Version einer
ausführbaren Datei. Dabei fügt der Compiler
zusätzliche Informationen darüber, welcher
Funktionsaufruf zu welcher Zeile im Quelltext gehört,
der ausfürbaren Datei hinzu. Ein Debugger kann Ihnen
mit Hilfe dieser Information den zugehörigen
Quelltext anzeigen, während Sie den Programmverlauf
schrittweise verfolgen, was sehr
hilfreich sein kann; der Nachteil dabei ist, daß
durch die zusätzlichen Informationen das Programm
viel größer wird. Normalerweise verwendet man
die Option während der
Entwicklung eines Programms, und für die
Release-Version, wenn man von der
Korrektheit des Programms überzeugt ist, kompiliert
man das Programm dann ohne diese Option.&prompt.user; cc -g foobar.cMit diesem Befehl wird eine Debug-Version des
Programms erzeugt.
Beachten Sie, daß an dieser Stelle die
Option zum Festlegen des Namens
der ausführbaren Datei nicht verwendet wurde,
weswegen an dieser Stelle die erzeugte Datei
a.out heißt. Die Erzeugung
einer Debug-Verion namens foobar
ist als Übung dem Leser überlassen!Diese Option erzeugt eine optimierte Version der
ausführbaren Datei. Der Compiler verwendet einige
clevere Tricks, um das erzeugte Programm schneller zu
machen. Sie können hinter der Option
eine Zahl angeben, um eine
höheres Level der Optimierung festzulegen. Dadurch
wird jedoch häufig eine fehlerhafte Optimierung
seitens des Compilers aufgedeckt. Zum Beispiel erzeugte
die Version des cc, welche mit dem
FreeBSD Release 2.1.0 mitgeliefert wurde, bei Verwendung
der Option unter bestimmten
Umständen falschen Code.Optimierungen werden normalerweise nur beim
Kompilieren von Release-Versionen aktiviert.&prompt.user; cc -O -o foobar foobar.cDurch diesen Befehl wird eine optimierte Version von
foobar erzeugt.Die folgenden drei Flags zwingen den cc
dazu, Ihren Code auf die Einhaltung der internationalen
Standards hin zu überprüfen, welche häufig als
ANSI Standards bezeichnet werden, obwohl sie
streng genommen zum ISO Standard
gehören.Aktivieren aller Warnmeldungen, die die Autoren des
cc für wichtig halten. Trotz des
Namens dieser Option werden dadurch nicht sämtliche
Warnungen ausgegeben, die der cc
ausgeben könnte.Deaktivieren der meisten, jedoch nicht aller,
nicht-ANSI C Eigenschaften, die
der cc bietet. Trotz des Namens ist
durch diese Option nicht sichergestellt, daß Ihr
Code diese Standards auch vollständig
einhält.Deaktivieren aller Eigenschaften
des cc, welche nicht konform zu
ANSI C sind.Ohne diese Flags wird Ihnen der cc die
Verwendung eigener Erweiterungen des Standards erlauben. Einige
dieser Erweiterungen sind zwar sehr nützlich, werden jedoch
nicht von anderen Compilern unterstützt—eigentlich
ist eines der Hauptziele des Standards, das Leute Code so
schreiben können, daß dieser mit jedem Compiler auf
beliebigen Systemen funktioniert. Dies wird häufig als
portabeler Code bezeichnet.Im Allgemeinen sollten Sie versuchen, Ihren Code so portabel
wie möglich zu schreiben, da Sie ansonsten eventuell das
gesamte Programm noch einmal neu schreiben müssen, falls
dieser in einer anderen Umgebung laufen soll—und wer
weiß schon was er in ein paar Jahren verwenden
wird?&prompt.user; cc -Wall -ansi -pedantic -o foobar foobar.cDurch diesen Befehl wird eine ausführbare Datei namens
foobar erzeugt, nachdem
foobar.c auf die Einhaltung der Standards
überprüft wurde.Mit dieser Option kann eine Bibliothek mit Funktionen
angegeben werden, die während des Verlinkens
verwendet wird.Das am häufigsten auftretende Beispiel dieser
Option ist die Übersetzung eines Programmes, welches
einige der mathematischen Funktionen in C verwendet. Im
Gegensatz zu den meisten anderen Plattformen befinden sich
diese Funktionen in einer separaten Bibliothek, deren
Verwendung Sie dem Compiler explizit mitteilen
müssen.Angenommen eine Bibliothek heißt
libirgendwas.a,
dann müssen Sie dem cc als
Argument
übergeben. Zum Beispiel heißt die
Mathematik-Bibliothek libm.a, und
daher müssen Sie dem cc als
Argument übergeben. Ein
typisches Manko der Mathematik-Bibliothek
ist, daß diese immer die letzte Bibliothek auf der
Kommandozeile sein muß.&prompt.user; cc -o foobar foobar.c -lmDurch diesen Befehl werden die Funktionen aus der
Mathematik-Bibliothek in foobar
gelinkt.Wenn Sie C++-Code kompilieren wollen, müssen Sie
, bzw.
falls Sie FreeBSD 2.2 oder neuer verwenden, zu Ihrer
Kommandozeile hinzufügen, um Ihr Programm gegen die
Funktionen der C++ Bibliothek zu linken. Alternativ
können Sie anstatt cc auch
c++ aufrufen, welcher dies für Sie
erledigt. c++ kann unter FreeBSD auch
als g++ aufgerufen werden.&prompt.user; cc -o foobar foobar.cc -lg++Bei FreeBSD 2.1.6 oder älter
&prompt.user; cc -o foobar foobar.cc -lstdc++Bei FreeBSD 2.2 und neuer
&prompt.user; c++ -o foobar foobar.ccBeide Varianten erzeugen eine ausführbare
foobar aus der C++ Quelltextdatei
foobar.cc. Beachten Sie bitte,
daß auf &unix; Systemen C++ Quelltextdateien
üblicherweise auf .C,
.cxx oder .cc
enden, und nicht wie bei &ms-dos; auf
.cpp (welche schon anderweitig
benutzt wurde). Der gcc hat
normalerweise anhand dieser Information entschieden,
welcher Compiler für die Quelltextdatei zum Einsatz
kommen soll; allerdings gilt diese Einschränkung
jetzt nicht mehr, und Sie können Ihre C++-Dateien
ungestraft auf .cpp enden
lassen!Häufig auftretende cc-Fragen und
-ProblemeIch versuche ein Programm zu schreiben, welches die
Funktion sin() verwendet, erhalte
jedoch eine Fehlermeldung. Was bedeutet diese?/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment
Wenn Sie mathematische Funktionen wie
sin() verwenden wollen, müssen
Sie den cc anweisen, die
Mathematik-Bibliothek wie folgt zu verlinken:&prompt.user; cc -o foobar foobar.c -lmSo, ich habe jetzt dieses einfache Programm als
Übung für geschrieben.
Alles was es macht ist, 2.1 hoch 6 zu berechnen.#include <stdio.h>
int main() {
float f;
f = pow(2.1, 6);
printf("2.1 ^ 6 = %f\n", f);
return 0;
}
und ich habe es wie folgt kompiliert:&prompt.user; cc temp.c -lmwie mir gesagt wurde. Allerdings bekomme ich jetzt
bei der Ausführung die folgende Ausgabe:&prompt.user; ./a.out
2.1 ^ 6 = 1023.000000
Das ist nicht die richtige
Antwort! Was ist hier los?Wenn der Compiler Ihren Funktionsaufruf sieht,
überprüft er, ob er schon einmal einen
Prototypen für diese gesehen hat. Wenn nicht nimmt
er als Rückgabewert den Typ int an,
was sicherlich nicht das ist, was Sie an dieser Stelle
wollen.Wie kann ich das korrigieren?Die Prototypen der mathematischen Funktionen
befinden sich in der Datei math.h.
Wenn Sie diese Datei in Ihrem Quelltext includen ist der
Compiler in der Lage, den Prototypen zu finden, und wird
aufhören, seltsame Dinge mit Ihrer Berechnung zu
machen!#include <math.h>
#include <stdio.h>
int main() {
...
Nach erneutem Compilieren sollte das Folgende bei
der Ausführung ausgegeben werden:&prompt.user; ./a.out
2.1 ^ 6 = 85.766121
Wenn Sie irgendwelche mathematischen Funktionen
verwenden sollten Sie immer die
Datei math.h includen und nicht
vergessen, Ihr Programm gegen die Mathematik-Bibliothek
zu verlinken.Ich habe eine Datei mit dem Namen
foobar.c compiliert, kann jedoch
nirgends eine ausführbare Datei namens
foobar finden. Wo befindet sich
diese?Denken Sie daran, daß der
cc die ausführbare Datei
a.out nennt, wenn Sie nicht
explizit einen Namen angeben. Verwenden Sie in solch
einem Fall die Option
:&prompt.user; cc -o foobar foobar.cOK, ich habe eine ausführbare Datei namens
foobar, ich kann sie sehen, wenn
ich ls aufrufe. Gebe ich jedoch
foobar in die Kommandozeile ein wird
mir gesagt, daß eine Datei mit diesem Namen nicht
existiert. Warum kann die Datei nicht gefunden
werden?Im Gegensatz zu &ms-dos; sucht &unix; nicht im
aktuellen Verzeichnis nach einem ausführbaren
Programm, das Sie versuchen auszuführen, solange
Sie dies nicht explizit mit angeben. Sie können
entweder ./foobar eingeben, was
soviel bedeutet wie führe eine Datei namens
foobar im aktuellen Verzeichnis
aus, oder Sie können Ihre Umgebungsvariable
PATH so erweitern, daß sie
ähnlich wie folgt aussiehtbin:/usr/bin:/usr/local/bin:.
Der Punkt am Ende bedeutet siehe im aktuellen
Verzeichnis nach, wenn es in keinem der anderen zu
finden war.Ich habe meine ausführbare Datei
test genannt, allerdings passiert
nichts wenn ich diese aufrufe. Was ist hier los?Bei den meisten &unix;-Systeme existiert bereits
ein Programm mit dem Namen test im
Verzeichnis /usr/bin, und die Shell
nimmt dieses, bevor sie im aktuellen Verzeichnis
nachsieht. Sie können entweder den folgenden Befehl
eingeben:&prompt.user; ./testoder Sie können einen geeigneteren Namen
für Ihr Programm wählen!Ich habe mein Programm kompiliert und bei dessen
Aufruf sah zuerst alles gut aus. Jedoch gab es dann eine
Fehlermeldung, welche irgendetwas mit core
dumped lautete. Was bedeutet das?Der Name core dump stammt
noch aus sehr frühen Zeiten von &unix;, als die
Maschinen noch Kernspeicher zum Speichern von Daten
verwendeten. Einfach ausgedrückt, wenn bei einem
Programm unter bestimmen Bedingungen ein Fehler auftrat,
hat das System den Inhalt des Kernspeichers auf der
Festplatte in eine Datei namens
core geschrieben, welche der
Programmierer dann näher untersuchen konnte, um die
Ursache des Fehlers herauszufinden.Faszinierendes Zeugs, aber was soll ich jetzt
machen?Verwenden Sie den gdb, um das
Speicherabbild zu untersuchen (siehe ).Als mein Programm den core dump erzeugt hat, sagte
es etwas von einem segmentation
fault. Was ist das?Diese Meldung heißt im Prinzip, daß Ihr
Programm eine illegale Operation mit dem Speicher
durchführen wollte; &unix; wurde so entworfen,
dass es das andere Programme und das Betriebssystem
selbst vor wildgewordenen Programmen
schützt.Häufige Ursachen hierfür sind:Der Versuch, einen NULL-Zeiger
zu beschreiben, z.B.char *foo = NULL;
strcpy(foo, "bang!");
Einen Zeiger zu verwenden, welcher noch nicht
initialisiert wurde, z.B.char *foo;
strcpy(foo, "bang!");
Der Zeiger hat einen zufälligen Wert,
welcher mit etwas Glück in einen Bereich des
Speichers zeigt, der für Ihr Programm nicht
verfügbar ist, und der Kernel bricht Ihr
Programm ab, bevor es irgendwelchen Schaden
anrichten kann. Wenn Sie Pech haben zeigt der Zeiger
irgendwo mitten in Ihr eigenes Programm, und
verändert dort ihre eigenen Datenstrukturen,
was zu sehr seltsamen Fehlern Ihres Programmes
führt.Der Versuch, auf Daten außerhalb eines
Arrays zuzugreifen, z.B.int bar[20];
bar[27] = 6;
Der Versuch, Daten in eine Speicherbereich zu
schreiben, der nur lesbar ist, z.B.char *foo = "My string";
strcpy(foo, "bang!");
&unix;-Compiler speichern häufig feste
Zeichenketten wie "My string" in
nur lesbaren Speicherbereichen ab.Wenn man unerlaubte Operationen mit
malloc() und
free() ausführt,
z.B.char bar[80];
free(bar);
oderchar *foo = malloc(27);
free(foo);
free(foo);
Einzelne solcher Fehler führen zwar nicht
immer zu einem Fehlverhalten des Programms, stellen
jedoch immer eine falsche Verwendung dar. Manche Systeme
und Compiler sind toleranter als andere, weshalb
Programme auf dem einen System einwandfrei laufen, auf
dem anderen System jedoch abstürzen.Wenn ich einen core dump erhalte erscheint
manchmal die Meldung bus error.
In meinem &unix;-Buch steht, dass die Ursache ein
Hardwareproblem sei. Der Computer scheint aber weiterhin
zu funktionieren. Ist dies wahr?Nein, glücklicherweise nicht (es sei denn Sie
haben wirklich ein Hardwareproblem…).
Üblicherweise ist dies ein Weg Ihnen mitzuteilen,
dass Sie auf Speicher in einer Weise zugegriffen
haben, in der Sie dies nicht tun sollten.Diese Sache mit den core dumps hört sich sehr
nützlich an, wenn ich so etwas selber an beliebiger
Stelle bewirken könnte. Kann ich das tun, oder
muß ich warten bis ein Fehler auftritt?Ja, nehmen sie einfach eine andere Konsole oder
XTerm und führen Sie&prompt.user; psaus, um die Prozess-ID Ihres Programms
herauszufinden. Führen Sie
anschließend&prompt.user; kill -ABRT pidaus, wobei
pid
die Prozess-ID ist, die Sie vorher ermittelt
haben.Dies ist nützlich, wenn sich Ihr Programm z.B.
in einer Endlosschleife verfangen hat. Sollte Ihr
Programm das Signal SIGABRT abfangen,
gibt es noch andere Möglichkeiten, die denselben
Effekt haben.Alternativ können Sie einen core dump aus
Ihrem Programm heraus erstellen, indem Sie die Funktion
abort() aufrufen. Weitere
Informationen darüber können Sie in der
Manualpage &man.abort.3; nachlesen.Wenn Sie einen core dump von ausßerhalb Ihres
Programms erzeugen wollen, ohne dabei den Prozess
abzubrechen, können Sie das Programm
gcore verwenden. Weitere
Informationen dazu finden Sie in der zugehörigen
Manualpage &man.gcore.1;.MakeWas ist make?Wenn Sie an einem einfachen Programm mit nur einer oder
zwei Quelltextdateien arbeiten, ist die Eingabe von&prompt.user; cc file1.c file2.czwar nicht aufwendig, wird aber mit zunehmender Anzahl
der Quelltextdateien sehr lästig—und auch das
Kompilieren kann eine Weile dauern.Eine Möglichkeit dies zu umgehen besteht in der
Verwendung von Objektdateien, wobei man nur die
Quelltextdateien neu kompiliert, die verändert wurden. So
könnten wir etwa folgendes erhalten:&prompt.user; cc file1.o file2.o … file37.c …falls wir seit dem letzten Kompiliervorgang nur die Datei
file37.c verändert haben. Dadurch
könnte der Kompiliervorgang um einiges beschleunigt
werden, es muß jedoch immer noch alles von Hand
eingegeben werden.Oder wir könnten uns ein Shell Skript schreiben.
Dieses würde jedoch alles immer wieder neu kompilieren,
was bei einem großen Projekt sehr ineffizient
wäre.Was ist, wenn wir hunderte von Quelltextdateien
hätten? Was ist, wenn wir in einem Team mit anderen
Leuten arbeiten würden, die vergessen uns Bescheid zu
sagen, falls sie eine der Quelltextdateien verändert
haben, die wir ebenfalls benutzen?Vielleicht könnten wir beide Lösungen
kombinieren und etwas wie ein Shell Skript schreiben, welches
eine Art magische Regel enthalten würde, die feststellt,
welche Quelltextdateien neu kompiliert werden müssten.
Alles was wir bräuchten wäre ein Programm, das diese
Regeln verstehen könnte, da diese Aufgabe etwas zu
kompliziert für eine Shell ist.Dieses Programm heißt make. Es
liest eine Datei namens makefile,
welche ihm sagt, wie unterschiedliche Dateien voneinander
abhängen, und berechnet, welche Dateien neu kompiliert
werden müssen und welche nicht. Zum Beispiel könnte
eine Regel etwas sagen wie wenn
fromboz.o älter als
fromboz.c ist, bedeutet dies, dass
jemand die Datei fromboz.c verändert
haben muß, und diese daher neu kompiliert werden
muß. Das makefile enthält außerdem
Regeln die make sagen, wie die
Quelltextdatei neu kompiliert werden muß, was dieses
Tool noch sehr viel mächtiger macht.Makefiles werden normalerweise im selben Verzeichnis
wie die Quelltextdateien abgelegt, zu denen sie gehören,
und kann makefile,
Makefile oder
MAKEFILE heißen. Die meisten
Programmierer verwenden den Namen
Makefile, da diese Schreibweise
dafür sorgt, dass die Datei gut lesbar ganz oben in
der Verzeichnisliste aufgeführt wird.
Sie verwenden nicht MAKEFILE mit
lauter Großbuchstaben, da diese Schreibweise
häufig für Dokumentationsdateien wie
README benutzt wird.Beispielhafte Verwendung von makeHier ist eine sehr einfache make Datei:foo: foo.c
cc -o foo foo.cSie besteht aus zwei Zeilen, einer
Abhängigkeitszeile und einer Erzeugungszeile.Die Abhängigkeitszeile hier besteht aus dem Namen
des Programms (auch Ziel genannt),
gefolgt von einem Doppelpunkt und einem Leerzeichen, und
anschließend dem Namen der Quelltextdatei. Wenn
make diese Zeile liest überprüft
es die Existenz von foo; falls diese
Datei existiert vergleicht es das Datum der letzten
Änderung von foo mit der von
foo.c. Falls foo
nicht existiert, oder älter als
foo.c ist, liest es die Erzeugungszeile
um herauszufinden, was zu tun ist. Mit anderen Worten, dies
ist die Regel die festlegt, wann foo.c
neu kompiliert werden muß.Die Erzeugungszeile beginnt mit einem tab
(drücken Sie dazu die tab-Taste) gefolgt
von dem Befehl, mit dem Sie foo manuell
erzeugen würden. Wenn foo veraltet
ist, oder nicht existiert, führt make
diesen Befehl aus, um die Datei zu erzeugen. Mit anderen
Worten, dies ist die Regel die make sagt, wie
foo.c kompiliert werden muß.Wenn Sie also make eingeben wird
dieses sicherstellen, dass foo bzgl.
Ihrer letzten Änderungen an foo.c
auf dem neuesten Stand ist. Dieses Prinzip kann auf
Makefiles mit hunderten von
Zielen—es ist bei FreeBSD praktisch möglich, das
gesamte Betriebssystem zu kompilieren, indem man nur
make world im richtigen Verzeichnis
eingibt!Eine weitere nützliche Eigenschaft der makefiles
ist, dass die Ziele keine Programme sein müssen. Wir
könnten zum Beispiel eine make Datei haben, die wie folgt
aussieht:foo: foo.c
cc -o foo foo.c
install:
cp foo /home/meWir können make sagen welches Ziel wir erzeugt haben
wollen, indem wir etwas wie folgt eingeben:&prompt.user; make targetmake wird dann nur dieses Ziel
beachten und alle anderen ignorieren. Wenn wir zum Beispiel
make foo mit dem obigen makefile
eingeben, dann wird make das Ziel
install ignorieren.Wenn wir nur make eingeben wird
make immer nur nach dem ersten Ziel suchen und danach mit dem
Suchen aufhören. Wenn wir hier also nur
make eingegeben hätten, würde
es nur zu dem Ziel foo gehen,
gegebenenfalls foo neu kompilieren, und
danach einfach aufhören, ohne das Ziel
install zu beachten.Beachten Sie das das install-Ziel
von nichts anderem abhängt! Dies bedeutet, dass der
Befehl in der nachfolgenden Zeile immer ausgeführt wird,
wenn wir dieses Ziel mittels make
install aufrufen. In diesem Fall wird die Datei
foo in das Heimatverzeichnis des
Benutzers kopiert. Diese Vorgehensweise wird häufig bei
makefiles von Anwendungen benutzt, damit die Anwendung nach
erfolgreicher Kompilierung in das richtige Verzeichnis
installiert werden kann.Dieser Teil ist etwas schwierig zu erklären. Wenn
Sie immer noch nicht so richtig verstanden haben, wie
make funktioniert, wäre es das Beste,
sie erstellen sich selber ein einfaches Programm wie
hello world und eine make Datei wie die weiter
oben angegebene, und experimentieren damit selber ein bischen
herum. Als nächstes könnten Sie mehrere
Quelltextdateien verwenden, oder in Ihrer Quelltextdatei eine
Header-Datei includen. Der Befehl touch ist
an dieser Stelle ganz hilfreich—er verändert das
Datum einer Datei, ohne das Sie diese extra editieren
müssen.Make und include-DateienC-Code beginnt häufig mit einer Liste von Dateien,
die included werden sollen, zum Beispiel stdio.h. Manche
dieser Dateien sind include-Dateien des Systems, andere
gehören zum aktuellen Projekt, an dem Sie gerade
arbeiten:#include <stdio.h>
#include "foo.h"
int main(....Um sicherzustellen, dass diese Datei neu kompiliert
wird, wenn foo.h verändert wurde,
müssen Sie diese Datei Ihrem
Makefile hinzufügen:foo: foo.c foo.hSobald Ihr Projekt größer wird und Sie mehr
und mehr eigene include-Dateien verwalten müssen wird es
nur noch sehr schwer möglich sein, die Übersicht
über alle include-Dateien und Dateien, die von diesen
abhängen, beizubehalten. Falls Sie eine include-Datei
verändern, jedoch das erneute Kompilieren aller Dateien,
die von dieser Datei abhängen, vergessen, werden die
Folgen verheerend sein. Der gcc besitzt
eine Option, bei der er Ihre Dateien analysiert und eine Liste
aller include-Dateien und deren Abhängigkeiten erstellt:
.Wenn Sie das Folgende zu Ihrem Makefile
hinzufügen:depend:
gcc -E -MM *.c > .dependund make depend ausführen,
wird die Datei .depend mit einer Liste
von Objekt-Dateien, C-Dateien und den include-Dateien
auftauchen:foo.o: foo.c foo.hFalls Sie foo.h verändern
werden beim nächsten Aufruf von make
alle Dateien, die von foo.h
abhängen, neu kompiliert.Vergessen Sie nicht jedes mal
make depend aufzurufen, wenn Sie eine
include-Datei zu einer Ihrer Dateien hinzugefügt
haben.FreeBSD MakefilesMakefiles können eher schwierig zu schreiben sein.
Glücklicherweise kommen BSD-basierende Systeme wie
FreeBSD mit einigen sehr mächtigen solcher Dateien als
Teil des Systems daher. Ein sehr gutes Beispiel dafür ist
das FreeBSD Portssystem. Hier ist der grundlegende Teil eines
typischen Makefiles des
Portssystems:MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz
.include <bsd.port.mk>Wenn wir jetzt in das Verzeichnis dieses Ports wechseln
und make aufrufen, passiert das
Folgende:Es wird überprüft, ob sich der Quelltext
für diesen Port bereits auf Ihrem System
befindet.Falls dies nicht der Fall ist wird eine
FTP-Verbindung zu der URL in MASTER_SITES
aufgebaut und der Quelltext heruntergeladen.Die Checksumme für den Quelltext wird berechnet
und mit der schon bekannten und für sicher und gut
empfundenen verglichen. Damit wird sichergestellt,
dass der Quelltext bei der Übertragung nicht
beschädigt wurde.Sämtliche Anpassungen, die nötig sind,
damit der Quelltext unter FreeBSD funktioniert, werden
vorgenommen—dieser Vorgang wird auch
patchen genannt.Alle speziellen Konfigurationen, die am Quelltext
nötig sind, werden vorgenommen. (Viele &unix;
Programmdistributionen versuchen herauszufinden, auf
welcher &unix;-Version sie kompiliert werden sollen und
welche optionalen &unix;-Features vorhanden sind—an
dieser Stelle erhalten sie die Informationen im FreeBSD
Ports Szenario).Der Quelltext für das Programm wird kompiliert.
Im Endeffekt wechseln wir in das Verzeichnis, in das der
Quelltext entpackt wurde, und rufen
make auf—die eigene make-Datei
des Programms besitzt die nötigen Informationen um
dieses zu bauen.Wir haben jetzt eine kompilierte Version des
Programmes. Wenn wir wollen können wir dieses jetzt
testen; wenn wir überzeugt vom Programm sind,
können wir make install
eingeben. Dadurch werden das Programm sowie alle
zugehörigen Dateien an die richtige Stelle kopiert;
es wird auch ein Eintrag in der
Paketdatenbank erzeugt, sodass
der Port sehr einfach wieder deinstalliert werden kann,
falls wir unsere Meinung über dieses geändert
haben.Ich glaube jetzt werden Sie mit mir übereinstimmen,
dass dies ziemlich eindrucksvoll für ein Skript mit
vier Zeilen ist!Das Geheimnis liegt in der letzten Zeile, die
make anweist, in das makefile des Systems
mit dem Namen bsd.port.mk zu sehen. Man
kann diese Zeile zwar leicht übersehen, aber hierher
kommt all das klevere Zeugs—jemand hat ein makefile
geschrieben, welches make anweist, alle
weiter oben beschriebenen Schritte durchzuführen (neben
vielen weiteren Dingen, die ich nicht angesprochen habe,
einschließlich der Behandlung sämtlicher Fehler,
die auftreten könnten) und jeder kann darauf
zurückgreifen, indem er eine einzige Zeile in seine
eigene make-Datei einfügt!Falls Sie einen Blick in die makefiles des Systems werfen
möchten, finden Sie diese in
/usr/share/mk. Es ist aber wahrscheinlich
besser, wenn Sie damit noch warten, bis Sie ein bischen mehr
Praxiserfahrung mit makefiles gesammelt haben, da die dortigen
makefiles sehr kompliziert sind (und wenn Sie sich diese
ansehen sollten Sie besser eine Kanne starken Kaffee
griffbereit haben!)Fortgeschrittene Verwendung von
makeMake ist ein sehr mächtiges
Werkzeug und kann noch sehr viel mehr als die gezeigten
einfachen Beispiele weiter oben. Bedauerlicherweise gibt es
mehrere verschiedene Versionen von make,
und sie alle unterscheiden sich beträchtlich voneinander.
Der beste Weg herauszufinden was sie können ist
wahrscheinlich deren Dokumentation zu lesen—hoffentlich
hat diese Einführung Ihnen genügend Grundkenntisse
vermitteln können, damit Sie dies tun können.Die Version von make, die in FreeBSD enthalten ist, ist
Berkeley make; es gibt eine
Anleitung dazu in
/usr/share/doc/psd/12.make. Um sich diese
anzusehen, müssen Sie&prompt.user; zmore paper.ascii.gzin diesem Verzeichnis ausführen.Viele Anwendungen in den Ports verwenden
GNU make, welches einen sehr guten
Satz an info-Seiten mitbringt. Falls Sie
irgendeinen dieser Ports installiert haben wurde
GNU make automatisch als
gmake mit installiert. Es ist auch als
eigenständiger Port und Paket verfügbar.Um sich die Info-Seiten für
GNU make anzusehen müssen Sie
die Datei dir in
/usr/local/info um einen entsprechenden
Eintrag erweitern. Dies beinhaltet das Einfügen einer
Zeile wie * Make: (make). The GNU Make utility.in die Datei. Nachdem Sie dies getan haben können
Sie info eingeben und dann den
Menüeintrag make
auswählen (oder Sie können in
Emacs die Tastenkombination
C-h i verwenden).DebuggenDer DebuggerDer Debugger bei FreeBSD heißt
gdb (GNU
debugger). Sie können Ihn durch die Eingabe
von&prompt.user; gdb prognamestarten, wobei die meisten Leute ihn vorzugsweise
innerhalb von Emacs aufrufen. Sie
erreichen dies durch die Eingabe von:M-x gdb RET progname RETDie Verwendung eines Debuggers erlaubt Ihnen Ihr
Programm unter kontrollierteren Bedingungen ausführen zu
können. Typischerweise können Sie so Zeile für
Zeile durch Ihr Programm gehen, die Werte von Variablen
untersuchen, diese verändern, dem Debugger sagen er soll
das Programm bis zu einem bestimmten Punkt ausführen und
dann anhalten, und so weiter und so fort. Sie können
damit sogar ein schon laufendes Programm untersuchen, oder
eine Datei mit einem Kernspeicherabbild laden um
herauszufinden, warum das Programm abgestürzt ist. Es ist
sogar möglich damit den Kernel zu debuggen, wobei dies
etwas trickreicher als bei den Benutzeranwendungen ist, welche
wir in diesem Abschnitt behandeln werden.Der gdb besitzt eine recht gute
Online-Hilfe, sowie einen Satz von Info-Seiten, weshalb sich
dieser Abschnitt auf ein paar grundlegende Befehle
beschränken wird.Falls Sie den textbasierten Kommandozeilen-Stil
abstoßend finden gibt es ein graphisches Front-End
dafür (xxgdb) in der
Ports-Sammlung.Dieser Abschnitt ist als Einführung in die
Verwendung des gdb gedacht und beinhaltet
nicht spezielle Themen wie das Debuggen des Kernels.Ein Programm im Debugger ausführenSie müssen das Programm mit der Option
kompiliert haben um den
gdb effektiv einsetzen zu können. Es
geht auch ohne diese Option, allerdings werden Sie dann nur
den Namen der Funktion sehen, in der Sie sich gerade befinden,
anstatt direkt den zugehörigen Quelltext. Falls Sie eine
Meldung wie die folgende sehen:… (no debugging symbols found) …wenn der gdb gestartet wird, dann
wissen Sie, dass das Programm nicht mit der Option
kompiliert wurde.Geben Sie in der Eingabeaufforderung des
gdbbreak main ein.
Dies weist den Debugger an die einleitenden Schritte beim
Programmstart zu überspringen und am Anfang Ihres Codes
zu beginnen. Geben Sie nun run ein um
das Programm zu starten—es wird starten und beim Aufruf
von main() vom Debugger angehalten
werden. (Falls Sie sich jemals gewundert haben von welcher
Stelle main() aufgerufen wird, dann
wissen Sie es jetzt!).Sie können nun Schritt für Schritt durch Ihr
Programm gehen, indem Sie n drücken.
Wenn Sie zu einem Funktionsaufruf kommen können Sie diese
Funktion durch drücken von s betreten.
Sobald Sie sich in einem Funktionsaufruf befinden können
Sie diesen durch drücken von f wieder
verlassen. Sie können auch up und
down verwenden, um sich schnell den
Aufrufer einer Funktion anzusehen.Hier ist ein einfaches Beispiel, wie man mit Hilfe des
gdb einen Fehler in einem Programm findet.
Dies ist unser eigenes Programm (mit einem absichtlich
eingebauten Fehler):#include <stdio.h>
int bazz(int anint);
main() {
int i;
printf("This is my program\n");
bazz(i);
return 0;
}
int bazz(int anint) {
printf("You gave me %d\n", anint);
return anint;
}Dieses Programm setzt i auf den Wert
5 und übergibt dies einer Funktion
bazz(), welche den Wert ausgibt, den Sie
von uns erhalten hat.Wenn wir das Programm kompilieren und ausführen
erhalten wir&prompt.user; cc -g -o temp temp.c
&prompt.user; ./temp
This is my program
anint = 4231Das ist nicht was wir erwartet hatten! Es ist Zeit,
dass wir sehen was hier passiert!&prompt.user; gdb temp
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
(gdb) break mainSkip the set-up code
Breakpoint 1 at 0x160f: file temp.c, line 9. gdb puts breakpoint at main()
(gdb) runRun as far as main()
Starting program: /home/james/tmp/temp Program starts running
Breakpoint 1, main () at temp.c:9 gdb stops at main()
(gdb) nGo to next line
This is my program Program prints out
(gdb) sstep into bazz()
bazz (anint=4231) at temp.c:17 gdb displays stack frame
(gdb)Halt mal! Wieso hat denn anint den Wert
4231? Haben wir dieser Variablen nicht in
main() den Wert 5
zugewiesen? Gehen wir mal zurück zu
main() und schauen dort nach.(gdb) upMove up call stack
#1 0x1625 in main () at temp.c:11 gdb displays stack frame
(gdb) p iShow us the value of i
$1 = 4231 gdb displays 4231Oh! Anscheinend haben wir vergessen i zu
initialisieren. Wir wollten eigentlich…
main() {
int i;
i = 5;
printf("This is my program\n");
…schreiben, haben aber die Zeile mit
i=5; vergessen. Da wir i
nicht initialisiert haben hatte diese Variable gerade den
Wert, der in dem ihr zugewiesenen Speicherbereich stand als
wir das Programm gestartet haben, welcher in diesem Fall
4231 war.Der gdb zeigt jedes mal, wenn wir
eine Funktion betreten oder verlassen, den Inhalt des
Stack-Rahmens an, selbst wenn wir uns mit
up und down im
Aufruf-Stack umherbewegen. Dabei wird der Name der Funktion
sowie der übergebenen Argumente angezeigt, was uns
dabei hilft, die Übersicht zu behalten. (Der Stack ist
ein Speicherbereich, in dem ein Programm Informationen
über die an eine Funktion übergebenen Argumente
ablegt, sowie die Rücksprungadresse eines
Funktionsaufrufes).Eine Kernspeicherdatei untersuchenEine Kernspeicherdatei ist im Prinzip eine Datei, die den
vollständigen Zustand eines Prozesses enthält, als
dieses abgestürzt ist. In den guten alten
Zeiten mußten Programmierer hexadezimale Listen
der Kernspeicherdatei ausdrucken und über
Maschinencodehandbüchern schwitzen, aber heutzutage ist
das Leben etwas einfacher geworden. Zufälligerweise wird
die Kernspeicherdatei unter FreeBSD und anderen
4.4BSD-Systemen
progname.core
anstatt einfach nur core genannt, um
deutlich zu machen, zu welchem Programm eine Kernspeicherdatei
gehört.Um eine Kernspeicherdatei zu untersuchen müssen Sie
den gdb wie gewohnt starten. An Stelle von
break oder run
müssen Sie das Folgende eingeben(gdb) core progname.coreWenn Sie sich nicht in demselben Verzeichnis befinden wie
die Kernspeicherdatei müssen Sie zuerst dir
/path/to/core/file eingeben.Sie sollten dann etwas wie folgt sehen:&prompt.user; gdb a.out
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
(gdb) core a.out.core
Core was generated by `a.out'.
Program terminated with signal 11, Segmentation fault.
Cannot access memory at address 0x7020796d.
#0 0x164a in bazz (anint=0x5) at temp.c:17
(gdb)In diesem Fall hieß das Programm
a.out, weshalb die Kernspeicherdatei den
Namen a.out.core trägt. Wie wir
sehen können stürzte das Programm in einer Funktion
namens bazz ab, als es versuchte auf
einen Speicherbereich zuzugreifen, der dem Programm nicht zur
Verfügung stand.Manchmal ist es ganz nützlich zu sehen, wie eine
Funktion aufgerufen wurde, da bei komplexen Programmen das
eigentliche Problem schon sehr viel weiter oben auf dem
Aufruf-Stack aufgetreten sein könnte. Der Befehl
bt veranlaßt den
gdb dazu, einen Backtrace des Aufruf-Stacks
auszugeben:(gdb) bt
#0 0x164a in bazz (anint=0x5) at temp.c:17
#1 0xefbfd888 in end ()
#2 0x162c in main () at temp.c:11
(gdb)Die Funktion end() wird aufgerufen,
wenn ein Programm abstürzt; in diesem Fall wurde die
Funktion bazz() aus der
main()-Funktion heraus aufgerufen.Ein bereits laufendes Programm untersuchenEine der tollsten Features des gdb
ist die Möglichkeit, damit bereits laufende Programme zu
untersuchen. Dies bedeutet natürlich, dass Sie die
erforderlichen Rechte dafür besitzen. Ein häufig
auftretendes Problem ist das Untersuchen eines Programmes,
welches sich selber forkt. Vielleicht will man den Kindprozess
untersuchen, aber der Debugger erlaubt einem nur den Zugriff
auf den Elternprozess.Was Sie an solch einer Stelle machen ist, Sie starten
einen weiteren gdb, ermitteln mit Hilfe von
ps die Prozess-ID des Kindprozesses, und
geben(gdb) attach pidim gdb ein, und können dann wie
üblich mit der Fehlersuche fortfahren.Das ist zwar alles sehr schön, werden
Sie jetzt vielleicht denken, aber in der Zeit, in der
ich diese Schritte durchführe, ist der Kindprozess schon
längst über alle Berge. Fürchtet euch
nicht, edler Leser, denn Ihr müßt wie folgt
vorgehen (freundlicherweise zur Verfügung gestellt von
den Info-Seite des gdb):…
if ((pid = fork()) < 0) /* _Always_ check this */
error();
else if (pid == 0) { /* child */
int PauseMode = 1;
while (PauseMode)
sleep(10); /* Wait until someone attaches to us */
…
} else { /* parent */
…Alles was Sie jetzt noch tun müssen ist, sich an
den Kindprozess ranzuhängen, PauseMode
auf 0 zu setzen und auf den
sleep() Funktionsaufruf zu warten, um
zurückzukehren!Emacs als Entwicklungsumgebung verwendenEmacsLeider werden &unix;-Systeme nicht mit einem
alles-was-du-jemals-brauchst-und-vieles-mehr-megapaket an
integrierten Entwicklungsumgebungen ausgestattet, die bei
anderen Systemen dabei sind.
Es gibt jetzt einige mächtige und freie IDEs in
der Ports-Sammlung wie etwa KDevelop.
Trotzdem ist es möglich, seine eigene
Entwicklungsumgebung aufzusetzen. Diese wird vielleicht nicht
so hübsch und integriert sein, aber dafür
können Sie sie Ihren eigenen Wünschen anpassen. Und
sie ist frei. Und Sie haben die Quelltexte davon.Der Schlüssel zu all dem ist Emacs. Es gibt zwar ein
paar Leute die ihn hassen, es gibt jedoch auch viele die ihn
lieben. Falls Sie zu ersteren gehören befürchte ich,
dass dieser Abschnitt Ihnen wenig interessantes zu bieten
hat. Des weiteren benötigen Sie eine angemessene Menge an
freiem Speicher, um ihn zu benutzen—ich würde 8MB
für den Textmodus und 16MB unter X als absolutes Minimum
empfehlen, um eine halbwegs brauchbare Performance zu
erhalten.Emacs ist im Prinzip ein extrem anpassbarer Editor—
in der Tat ist er so stark veränderbar, dass er eher
einem Betriebssystem als einem Editor gleicht! Viele
Entwickler und Systemadministratoren erledigen praktisch ihre
gesamte Arbeit aus Emacs heraus und beenden ihn nur, um sich
komplett auszuloggen.Es ist nicht einmal möglich alles hier
zusammenzufassen, was man mit dem Emacs machen kann. Im
Folgenden werden einige Features aufgelistet, die für
einen Entwickler interessant sein könnten:Sehr mächtiger Editor, der suchen-und-ersetzen
mit Zeichenfolgen und regulären Ausdrücken
(Pattern) sowie das direkte Anspringen von Anfang/Ende von
Blockausdrücken erlaubt, etc, etc.Pull-Down Menüs und eine Online-Hilfe.Sprachunabhängige Syntaxhervorhebung und
automatische Einrückung.Vollständig konfigurierbar.Sie können Programme im Emacs kompilieren und
debuggen.Bei Kompilationsfehlern können Sie direkt zu der
entsprechenden Zeile im Quelltext springen.Benutzerfreundliches Front-End für das
info-Programm, um die GNU Hypertext
Dokumentation inklusive der Dokumentation des Emacs
selber.Benutzerfreundliches Front-End für den
gdb um sich beim Verfolgen der
Programmanweisungen den zugehörigen Quelltext
anzeigen zu lassen.Sie können E-Mails und News im Usenet lesen,
während ihr Programm kompiliert wird.Und zweifelsfrei viele weitere Punkte, die ich
übersehen habe.Emacs kann unter FreeBSD über den
Emacs Port
installiert werden.Sobald er installiert ist starten Sie ihn, und geben
dann C-h t ein, um die Einführung
in Emacs zu lesen—d.h. Sie sollen bei gedrückter
Strg-Taste die h-Taste
drücken, beide wieder loslassen und anschließend
t drücken. (Alternativ können Sie
mit der Maus den Eintrag Emacs
Tutorial aus dem
Hilfe-Menü auswählen).Obwohl der Emacs Menüs besitzt ist das Erlernen der
Tastaturkombinationen lohnenswert, da man beim Editieren sehr
viel schneller Tastenkombinationen eingeben kann, als die Maus
zu finden und mit dieser dann an der richtigen Stelle zu
klicken. Und wenn Sie sich mit erfahrenen Emacs-Benutzern
unterhalten werden Sie feststellen, dass diese
häufig nebenbei Ausdrücke wie M-x
replace-s RET foo RET bar RET verwenden,
weshalb das Erlernen dieser sehr nützlich ist. Und Emacs
hat auf jeden Fall weit mehr nützliche Funktionen als das
diese in der Menüleiste unterzubringen wären.Zum Glück ist es sehr einfach die jeweiligen
Tastaturkombinationen herauszubekommen, da diese direkt neben
den Menüeinträgen stehen. Meine Empfehlung
wäre, den Menüeintrag für, sagen wir, das
Öffnen einer Datei zu verwenden, bis Sie die
Funktionsweise verstanden haben und sie mit dieser vertraut
sind, und es dann mit C-x C-f versuchen. Wenn Sie damit
zufrieden sind, gehen Sie zum nächsten
Menüeintrag.Falls Sie sich nicht daran erinnern können, was eine
bestimmte Tastenkombination macht, wählen Sie
Describe Key aus dem
Hilfe-Menü aus und geben Sie die
Tastenkombination ein—Emacs sagt Ihnen dann was diese
macht. Sie können ebenfalls den Menüeintrag
Command Apropos verwenden, um alle
Befehle, die ein bestimmtes Wort enthalten, mit den
zugehörigen Tastenkombinationen aufgelistet zu
bekommen.Übrigends bedeutet der Ausdruck weiter oben, bei
gedrückter Meta-Taste x
zu drücken, beide wieder loszulassen,
replace-s einzugeben (Kurzversion
für replace-string—ein weiteres
Feature des Emacs ist, dass Sie Befehle abkürzen
können), anschließend die
return-Taste zu drücken, dann
foo einzugeben (die Zeichenkette, die
Sie ersetzen möchten), dann wieder
return, dann die Leertaste zu drücken
(die Zeichenkette, mit der Sie foo ersetzen
möchten) und anschließend erneut
return zu drücken. Emacs wird dann die
gewünschte suchen-und-ersetzen-Operation
ausführen.Wenn Sie sich fragen was in aller Welt die
Meta-Taste ist, das ist eine spezielle Taste
die viele &unix;-Workstations besitzen. Bedauerlicherweise
haben PCs keine solche Taste, und daher ist es
üblichwerweise die alt-Taste (oder falls
Sie Pech haben die Esc-Taste).Oh, und um den Emacs zu verlassen müssen sie
C-x C-c (das bedeutet, Sie müssen bei
gedrückter Strg-Taste zuerst
x und dann c drücken)
eingeben. Falls Sie noch irgendwelche ungespeicherten Dateien
offen haben wird Emacs Sie fragen ob Sie diese speichern
wollen. (Ignorieren Sie bitte die Stelle der Dokumentation, an
der gesagt wird, dass C-z der
übliche Weg ist, Emacs zu verlassen—dadurch wird
der Emacs in den Hintergrund geschaltet, was nur nützlich
ist, wenn Sie an einem System ohne virtuelle Terminals
arbeiten).Emacs konfigurierenEmacs kann viele wundervolle Dinge; manche dieser Dinge
sind schon eingebaut, andere müssen erst konfiguriert
werden.Anstelle einer proprietären Macrosprache verwendet
der Emacs für die Konfiguration eine speziell für
Editoren angepaßte Version von Lisp, auch bekannt als
Emacs Lisp. Das Arbeiten mit Emacs Lisp kann sehr hilfreich
sein, wenn Sie darauf aufbauend etwas wie Common Lisp lernen
möchten. Emacs Lisp hat viele Features von Common Lisp
obwohl es beträchtlich kleiner ist (und daher auch
einfacher zu beherschen).Der beste Weg um Emacs Lisp zu erlernen besteht darin,
sich das Emacs
Tutorial herunterzuladen.Es ist jedoch keine Kenntnis von Lisp erforderlich, um
mit der Konfiguration von Emacs zu beginnen, da ich eine
beispielhafte .emacs-Datei hier
eingefügt habe, die für den Anfang ausreichen
sollte. Kopieren Sie diese einfach in Ihr Heimverzeichnis und
starten Sie den Emacs neu, falls dieser bereits läuft; er
wird die Befehle aus der Datei lesen und Ihnen (hoffentlich)
eine brauchbare Grundeinstellung bieten.Eine beispielhafte .emacs-DateiBedauerlicherweise gibt es hier viel zu viel, um es im
Detail zu erklären; es gibt jedoch ein oder zwei Punkte,
die besonders erwähnenswert sind.Alles was mit einem ; anfängt
ist ein Kommentar und wird von Emacs ignoriert.In der ersten Zeile mit
-*- Emacs-Lisp -*- sorgt
dafür, dass wir die Datei
.emacs in Emacs selber editieren
können und uns damit alle tollen Features zum
Editieren von Emacs Lisp zur Verfügung stehen. Emacs
versucht dies normalerweise anhand des Dateinamens
auszumachen, was vielleicht bei
.emacs nicht funktionieren
könnte.Die Tab-Taste ist in manchen Modi
an die Einrückungsfunktion gebunden, so dass
beim drücken dieser Taste die aktuelle Zeile
eingerückt wird. Wenn Sie ein
tab-Zeichen in einen Text, welchen auch
immer Sie dabei schreiben, einfügen wollen,
müssen Sie bei gedrückter
Strg-Taste die Tab-Taste
drücken.Diese Datei unterstützt Syntax Highlighting
für C, C++, Perl, Lisp und Scheme, indem die Sprache
anhand des Dateinamens erraten wird.Emacs hat bereits eine vordefinierte Funktion mit dem
Namen next-error. Diese erlaubt es
einem, in einem Fenster mit der Kompilierungsausgabe
mittels M-n von einem zum nächsten
Kompilierungsfehler zu springen; wir definieren eine
komplementäre Funktion
previous-error, die es uns erlaubt,
mittels M-p von einem zum vorherigen
Kompilierungsfehler zu springen. Das schönste Feature
von allen ist, dass mittels C-c
C-c die Quelltextdatei, in der der Fehler
aufgetreten ist, geöffnet und die betreffende Zeile
direkt angesprungen wird.Wir aktivieren die Möglichkeit von Emacs als
Server zu agieren, so dass wenn Sie etwas
außerhalb von Emacs machen und eine Datei editieren
möchten, Sie einfach das folgende eingeben
können&prompt.user; emacsclient filenameund dann die Datei in Ihrem Emacs editieren
können!
Viele Emacs-Benutzer setzen Ihre
EDITOR-Umgebungsvariable auf
emacsclient, so dass dies
immer passiert, wenn sie eine Datei editieren
müssen.Eine einfache .emacs-Datei;; -*-Emacs-Lisp-*-
;; This file is designed to be re-evaled; use the variable first-time
;; to avoid any problems with this.
(defvar first-time t
"Flag signifying this is the first time that .emacs has been evaled")
;; Meta
(global-set-key "\M- " 'set-mark-command)
(global-set-key "\M-\C-h" 'backward-kill-word)
(global-set-key "\M-\C-r" 'query-replace)
(global-set-key "\M-r" 'replace-string)
(global-set-key "\M-g" 'goto-line)
(global-set-key "\M-h" 'help-command)
;; Function keys
(global-set-key [f1] 'manual-entry)
(global-set-key [f2] 'info)
(global-set-key [f3] 'repeat-complex-command)
(global-set-key [f4] 'advertised-undo)
(global-set-key [f5] 'eval-current-buffer)
(global-set-key [f6] 'buffer-menu)
(global-set-key [f7] 'other-window)
(global-set-key [f8] 'find-file)
(global-set-key [f9] 'save-buffer)
(global-set-key [f10] 'next-error)
(global-set-key [f11] 'compile)
(global-set-key [f12] 'grep)
(global-set-key [C-f1] 'compile)
(global-set-key [C-f2] 'grep)
(global-set-key [C-f3] 'next-error)
(global-set-key [C-f4] 'previous-error)
(global-set-key [C-f5] 'display-faces)
(global-set-key [C-f8] 'dired)
(global-set-key [C-f10] 'kill-compilation)
;; Keypad bindings
(global-set-key [up] "\C-p")
(global-set-key [down] "\C-n")
(global-set-key [left] "\C-b")
(global-set-key [right] "\C-f")
(global-set-key [home] "\C-a")
(global-set-key [end] "\C-e")
(global-set-key [prior] "\M-v")
(global-set-key [next] "\C-v")
(global-set-key [C-up] "\M-\C-b")
(global-set-key [C-down] "\M-\C-f")
(global-set-key [C-left] "\M-b")
(global-set-key [C-right] "\M-f")
(global-set-key [C-home] "\M-<")
(global-set-key [C-end] "\M->")
(global-set-key [C-prior] "\M-<")
(global-set-key [C-next] "\M->")
;; Mouse
(global-set-key [mouse-3] 'imenu)
;; Misc
(global-set-key [C-tab] "\C-q\t") ; Control tab quotes a tab.
(setq backup-by-copying-when-mismatch t)
;; Treat 'y' or <CR> as yes, 'n' as no.
(fset 'yes-or-no-p 'y-or-n-p)
(define-key query-replace-map [return] 'act)
(define-key query-replace-map [?\C-m] 'act)
;; Load packages
(require 'desktop)
(require 'tar-mode)
;; Pretty diff mode
(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
(autoload 'ediff-files-remote "ediff"
"Intelligent Emacs interface to diff")
(if first-time
(setq auto-mode-alist
(append '(("\\.cpp$" . c++-mode)
("\\.hpp$" . c++-mode)
("\\.lsp$" . lisp-mode)
("\\.scm$" . scheme-mode)
("\\.pl$" . perl-mode)
) auto-mode-alist)))
;; Auto font lock mode
(defvar font-lock-auto-mode-list
(list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
"List of modes to always start in font-lock-mode")
(defvar font-lock-mode-keyword-alist
'((c++-c-mode . c-font-lock-keywords)
(perl-mode . perl-font-lock-keywords))
"Associations between modes and keywords")
(defun font-lock-auto-mode-select ()
"Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list"
(if (memq major-mode font-lock-auto-mode-list)
(progn
(font-lock-mode t))
)
)
(global-set-key [M-f1] 'font-lock-fontify-buffer)
;; New dabbrev stuff
;(require 'new-dabbrev)
(setq dabbrev-always-check-other-buffers t)
(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
(add-hook 'emacs-lisp-mode-hook
'(lambda ()
(set (make-local-variable 'dabbrev-case-fold-search) nil)
(set (make-local-variable 'dabbrev-case-replace) nil)))
(add-hook 'c-mode-hook
'(lambda ()
(set (make-local-variable 'dabbrev-case-fold-search) nil)
(set (make-local-variable 'dabbrev-case-replace) nil)))
(add-hook 'text-mode-hook
'(lambda ()
(set (make-local-variable 'dabbrev-case-fold-search) t)
(set (make-local-variable 'dabbrev-case-replace) t)))
;; C++ and C mode...
(defun my-c++-mode-hook ()
(setq tab-width 4)
(define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
(define-key c++-mode-map "\C-ce" 'c-comment-edit)
(setq c++-auto-hungry-initial-state 'none)
(setq c++-delete-function 'backward-delete-char)
(setq c++-tab-always-indent t)
(setq c-indent-level 4)
(setq c-continued-statement-offset 4)
(setq c++-empty-arglist-indent 4))
(defun my-c-mode-hook ()
(setq tab-width 4)
(define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
(define-key c-mode-map "\C-ce" 'c-comment-edit)
(setq c-auto-hungry-initial-state 'none)
(setq c-delete-function 'backward-delete-char)
(setq c-tab-always-indent t)
;; BSD-ish indentation style
(setq c-indent-level 4)
(setq c-continued-statement-offset 4)
(setq c-brace-offset -4)
(setq c-argdecl-indent 0)
(setq c-label-offset -4))
;; Perl mode
(defun my-perl-mode-hook ()
(setq tab-width 4)
(define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
(setq perl-indent-level 4)
(setq perl-continued-statement-offset 4))
;; Scheme mode...
(defun my-scheme-mode-hook ()
(define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
;; Emacs-Lisp mode...
(defun my-lisp-mode-hook ()
(define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
(define-key lisp-mode-map "\C-i" 'lisp-indent-line)
(define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
;; Add all of the hooks...
(add-hook 'c++-mode-hook 'my-c++-mode-hook)
(add-hook 'c-mode-hook 'my-c-mode-hook)
(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
(add-hook 'perl-mode-hook 'my-perl-mode-hook)
;; Complement to next-error
(defun previous-error (n)
"Visit previous compilation error message and corresponding source code."
(interactive "p")
(next-error (- n)))
;; Misc...
(transient-mark-mode 1)
(setq mark-even-if-inactive t)
(setq visible-bell nil)
(setq next-line-add-newlines nil)
(setq compile-command "make")
(setq suggest-key-bindings nil)
(put 'eval-expression 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'set-goal-column 'disabled nil)
(if (>= emacs-major-version 21)
(setq show-trailing-whitespace t))
;; Elisp archive searching
(autoload 'format-lisp-code-directory "lispdir" nil t)
(autoload 'lisp-dir-apropos "lispdir" nil t)
(autoload 'lisp-dir-retrieve "lispdir" nil t)
(autoload 'lisp-dir-verify "lispdir" nil t)
;; Font lock mode
(defun my-make-face (face color &optional bold)
"Create a face from a color and optionally make it bold"
(make-face face)
(copy-face 'default face)
(set-face-foreground face color)
(if bold (make-face-bold face))
)
(if (eq window-system 'x)
(progn
(my-make-face 'blue "blue")
(my-make-face 'red "red")
(my-make-face 'green "dark green")
(setq font-lock-comment-face 'blue)
(setq font-lock-string-face 'bold)
(setq font-lock-type-face 'bold)
(setq font-lock-keyword-face 'bold)
(setq font-lock-function-name-face 'red)
(setq font-lock-doc-string-face 'green)
(add-hook 'find-file-hooks 'font-lock-auto-mode-select)
(setq baud-rate 1000000)
(global-set-key "\C-cmm" 'menu-bar-mode)
(global-set-key "\C-cms" 'scroll-bar-mode)
(global-set-key [backspace] 'backward-delete-char)
; (global-set-key [delete] 'delete-char)
(standard-display-european t)
(load-library "iso-transl")))
;; X11 or PC using direct screen writes
(if window-system
(progn
;; (global-set-key [M-f1] 'hilit-repaint-command)
;; (global-set-key [M-f2] [?\C-u M-f1])
(setq hilit-mode-enable-list
'(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
scheme-mode)
hilit-auto-highlight nil
hilit-auto-rehighlight 'visible
hilit-inhibit-hooks nil
hilit-inhibit-rebinding t)
(require 'hilit19)
(require 'paren))
(setq baud-rate 2400) ; For slow serial connections
)
;; TTY type terminal
(if (and (not window-system)
(not (equal system-type 'ms-dos)))
(progn
(if first-time
(progn
(keyboard-translate ?\C-h ?\C-?)
(keyboard-translate ?\C-? ?\C-h)))))
;; Under UNIX
(if (not (equal system-type 'ms-dos))
(progn
(if first-time
(server-start))))
;; Add any face changes here
(add-hook 'term-setup-hook 'my-term-setup-hook)
(defun my-term-setup-hook ()
(if (eq window-system 'pc)
(progn
;; (set-face-background 'default "red")
)))
;; Restore the "desktop" - do this as late as possible
(if first-time
(progn
(desktop-load-default)
(desktop-read)))
;; Indicate that this file has been read at least once
(setq first-time nil)
;; No need to debug anything now
(setq debug-on-error nil)
;; All done
(message "All done, %s%s" (user-login-name) ".")
Erweitern des von Emacs unterstützten SprachbereichsDas ist jetzt alles sehr schön wenn Sie
ausschließlich in einer der Sprachen programmieren
wollen, um die wir uns bereits in der
.emacs-Datei gekümmert haben (C,
C++, Perl, Lisp und Scheme), aber was passiert wenn eine neue
Sprache namens whizbang herauskommt, mit jeder
Menge neuen tollen Features?Als erstes muß festgestellt werden, ob whizbang mit
irgendwelchen Dateien daherkommt, die Emacs etwas über
die Sprache sagen. Diese enden üblicherweise auf
.el, der Kurzform für Emacs
Lisp. Falls whizbang zum Beispiel ein FreeBSD Port
ist, könnten wir diese Dateien mittels&prompt.user; find /usr/ports/lang/whizbang -name "*.el" -printfinden und durch Kopieren in das Emacs-seitige
Lisp-Verzeichnis installieren. Unter FreeBSD 2.1.0-RELEASE ist
dies
/usr/local/share/emacs/site-lisp.Wenn zum Beispiel die Ausgabe des find-Befehls wie folgt
war/usr/ports/lang/whizbang/work/misc/whizbang.elkönnten wir das folgende tun&prompt.root; cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lispAls nächstes müssen wir festlegen, welche
Dateiendung Quelltextdateien für whizbang haben. Lassen
Sie uns um der Argumente Willen annehmen, die Dateiendung sei
.wiz. Wir müssen dann einen Eintrag
unserer .emacs-Datei hinzufügen um
sicherzustellen, dass Emacs die Informationen in
whizbang.el auch verwenden kann.Suchen Sie den auto-mode-alist Eintrag
in der .emacs-Datei und fügen Sie an
dieser Stelle eine Zeile wie folgt für whizbang
hinzu:…
("\\.lsp$" . lisp-mode)
("\\.wiz$" . whizbang-mode)
("\\.scm$" . scheme-mode)
…Dies bedeutet das Emacs automatisch in den
whizbang-mode wechseln wird, wenn Sie
eine Datei mit der Dateiendung .wiz
editieren.Direkt darunter werden Sie den Eintrag
font-lock-auto-mode-list finden. Erweitern
Sie den whizbang-mode um diesen wie
folgt:;; Auto font lock mode
(defvar font-lock-auto-mode-list
(list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
"List of modes to always start in font-lock-mode")Dies bedeutet das Emacs immer
font-lock-mode (z.B. Syntax Highlighting)
aktiviert, wenn Sie eine .wiz-Datei
editieren.Und das ist alles was benötigt wird. Falls es
weitere Dinge gibt, die automatisch beim Öffnen einer
.wiz-Datei ausgeführt werden sollen,
können Sie einen whizbang-mode
hook-Eintrag hinzufügen (für ein
einfaches Beispiel, welches auto-indent
hinzufügt, sehen Sie sich bitte
my-scheme-mode-hook an).Weiterführende LiteraturFür Informationen zum Aufsetzen einer
Entwicklungsumgebung, um Fehlerbehebungen an FreeBSD selber
beizusteuern sehen Sie sich bitte &man.development.7; an.Brian Harvey and Matthew Wright
Simply Scheme
MIT 1994.
ISBN 0-262-08226-8Randall Schwartz
Learning Perl
O'Reilly 1993
ISBN 1-56592-042-2Patrick Henry Winston and Berthold Klaus Paul Horn
Lisp (3rd Edition)
Addison-Wesley 1989
ISBN 0-201-08319-1Brian W. Kernighan and Rob Pike
The Unix Programming Environment
Prentice-Hall 1984
ISBN 0-13-937681-XBrian W. Kernighan and Dennis M. Ritchie
The C Programming Language (2nd Edition)
Prentice-Hall 1988
ISBN 0-13-110362-8Bjarne Stroustrup
The C++ Programming Language
Addison-Wesley 1991
ISBN 0-201-53992-6W. Richard Stevens
Advanced Programming in the Unix Environment
Addison-Wesley 1992
ISBN 0-201-56317-7W. Richard Stevens
Unix Network Programming
Prentice-Hall 1990
ISBN 0-13-949876-1