aboutsummaryrefslogtreecommitdiff
path: root/de_DE.ISO8859-1/books/developers-handbook/tools/chapter.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'de_DE.ISO8859-1/books/developers-handbook/tools/chapter.sgml')
-rw-r--r--de_DE.ISO8859-1/books/developers-handbook/tools/chapter.sgml2644
1 files changed, 2644 insertions, 0 deletions
diff --git a/de_DE.ISO8859-1/books/developers-handbook/tools/chapter.sgml b/de_DE.ISO8859-1/books/developers-handbook/tools/chapter.sgml
new file mode 100644
index 0000000000..a9ceeff439
--- /dev/null
+++ b/de_DE.ISO8859-1/books/developers-handbook/tools/chapter.sgml
@@ -0,0 +1,2644 @@
+<!--
+ The FreeBSD Documentation Project
+ The FreeBSD German Documentation Project
+
+ $FreeBSD$
+ $FreeBSDde: de-docproj/books/developers-handbook/tools/chapter.sgml,v 1.11 2011/05/12 17:36:17 bcr Exp $
+ basiert auf: 1.52
+-->
+
+<chapter id="tools">
+ <chapterinfo>
+ <authorgroup>
+ <author>
+ <firstname>James</firstname>
+ <surname>Raynard</surname>
+ <contrib>Contributed by </contrib>
+ </author>
+ <author>
+ <firstname>Murray</firstname>
+ <surname>Stokely</surname>
+ </author>
+ </authorgroup>
+ <authorgroup>
+ <author>
+ <firstname>Dirk</firstname>
+ <surname>Arlt</surname>
+ <contrib>&Uuml;bersetzt von </contrib>
+ </author>
+ <author>
+ <firstname>Fabian</firstname>
+ <surname>Borschel</surname>
+ </author>
+ </authorgroup>
+ </chapterinfo>
+
+ <title>Werkzeuge zur Programmierung</title>
+
+ <sect1 id="tools-synopsis">
+ <title>&Uuml;berblick</title>
+
+ <para>Dieses Kapitel ist eine Einf&uuml;hrung in die Benutzung
+ einiger der Werkzeuge zur Programmierung die mit FreeBSD
+ ausgeliefert werden. Trotzdem ist vieles auch auf verschiedene
+ andere Versionen von &unix; &uuml;bertragbar. Dieses Kapitel
+ soll <emphasis>kein</emphasis> Versuch sein Programmierung
+ detailliert zu beschreiben. Der gr&ouml;&szlig;te Teil dieses
+ Kapitels setzt wenige oder gar keine Programmierkenntnisse
+ voraus, dennoch sollten die meisten Programmierer etwas
+ Sinnvolles darin finden.</para>
+ </sect1>
+
+ <sect1 id="tools-intro">
+ <title>Zusammenfassung</title>
+
+ <para>FreeBSD bietet eine exzellente Entwicklungsumgebung.
+ Compiler f&uuml;r C und C++, sowie ein Assembler sind im
+ Basissystem enthalten. Nat&uuml;rlich finden
+ sich auch klassische &unix;-Werkzeuge wie <command>sed</command>
+ und <command>awk</command>. Sollte das nicht genug sein, finden sich
+ zahlreiche weitere Compiler und Interpreter in der Ports-Sammlung.
+ Der folgende Abschnitt, <link
+ linkend="tools-programming">Einf&uuml;hrung in die Programmierung</link>,
+ z&auml;hlt ein paar der verf&uuml;gbaren Optionen auf. FreeBSD ist
+ kompatibel zu vielen Standards wie <acronym>&posix;</acronym>
+ und <acronym>ANSI</acronym> C, sowie zu seinem eigenen BSD Erbe. So
+ ist es m&ouml;glich Anwendungen zu schreiben, welche ohne oder
+ zumindest ohne wesentliche &Auml;nderungen auf einer
+ gro&szlig;en Zahl an Plattformen kompilieren und laufen
+ werden.</para>
+
+ <para>Allerdings k&ouml;nnen all diese M&ouml;glichkeiten
+ anfangs etwas &uuml;berw&auml;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&szlig; dieses Dokument ihnen ausreichend
+ Basiswissen vermittelt und die weitergehende Dokumentation
+ sinnvoll nutzen zu k&ouml;nnen.</para>
+
+ <para>Der gr&ouml;&szlig;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 vorausgesetzt!</para>
+ </sect1>
+
+ <sect1 id="tools-programming">
+ <title>Einf&uuml;hrung in die Programmierung</title>
+
+ <para>Ein Programm ist eine Zusammenstellung von Anweisungen, die
+ den Computer auffordern verschiedenste Dinge zu tun. Dieser
+ Abschnitt gibt ihnen einen &Uuml;berblick &uuml;ber die beiden
+ wesentlichen Methoden diese Anweisungen oder
+ <quote>Befehle</quote>, wie man diese Anweisungen
+ &uuml;blicherweise nennt, zu geben. Die eine Methode nutzt einen
+ <firstterm>Interpreter</firstterm>, die andere einen
+ <firstterm>Compiler</firstterm>. Da menschliche Sprachen
+ f&uuml;r einen Computer nicht unmissverst&auml;ndlich sind,
+ werden diese Befehle in einer Sprache geschrieben die speziell
+ f&uuml;r diesen Zweck gedacht ist.</para>
+
+ <sect2>
+ <title>Interpreter</title>
+
+ <para>Mit einem Interpreter ist die Sprache vielmehr eine
+ Umgebung, in der Sie ein Kommando an der Kommandozeile
+ eingeben welches dann von der Umgebung ausgef&uuml;hrt wird.
+ F&uuml;r kompliziertere Programme k&ouml;nnen Sie die Befehle
+ in eine Datei schreiben und den Interpreter dazu bringen diese
+ Datei zu laden und die enthaltenen Befehle auszuf&uuml;hren.
+ Falls etwas schief geht werden viele Interpreter Sie an einen
+ Debugger weiterleiten.</para>
+
+ <para>Der Vorteil hierbei ist, das Sie das Ergebnis ihres
+ Befehls direkt sehen und Fehler sofort korrigiert werden
+ k&ouml;nnen. Der gr&ouml;&szlig;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 wie dieser zu bedienen ist.
+ Zudem werden Benutzer es nicht begr&uuml;&szlig;en sich in
+ einem Debugger wiederzufinden, wenn Sie einmal die falsche
+ Taste dr&uuml;cken! Bei einem Blick auf die
+ Leistungsf&auml;higkeit brauchen Interpreter oftmals viel
+ Speicher und erzeugen den Code nicht so effizient wie
+ Compiler.</para>
+
+ <para>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&ouml;nnte auch sagen,
+ dass die &unix; Shell (<command>sh</command>,
+ <command>csh</command>) f&uuml;r sich bereits einen
+ Interpreter darstellt und viele Leute schreiben
+ tats&auml;chlich Shell <quote>Scripten</quote> um sich bei
+ einigen <quote>Haushaltsaufgaben</quote> auf ihren Maschinen
+ helfen zu lassen. Tats&auml;chlich war es ein wesentlicher
+ Teil der originalen &unix; Philosophie eine gro&szlig;e Zahl
+ an kleinen Hilfsprogrammen zur Verf&uuml;gung zu stellen,
+ welche mittels eines Shellskripts miteinander kombiniert werden
+ um bestimmte Aufgaben zu &uuml;bernehmen.</para>
+ </sect2>
+
+ <sect2>
+ <title>F&uuml;r FreeBSD verf&uuml;gbare Interpreter</title>
+
+ <para>Im folgenden eine Liste der &uuml;ber die &os;
+ Ports-Sammlung verf&uuml;gbaren Interpreter
+ einschlie&szlig;lich einer kurzen Er&ouml;rterung der
+ popul&auml;ren interpretierten Sprachen.</para>
+
+ <para>Anleitungen wie man Anwendungen aus der Ports-Sammlung
+ erh&auml;lt und installiert k&ouml;nnen Sie dem Kapitel <ulink
+ url="&url.books.handbook;/ports-using.html">Benutzen der
+ Ports-Sammlung</ulink> aus dem FreeBSD Handbuch
+ entnehmen.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><acronym>BASIC</acronym></term>
+
+ <listitem>
+ <para>Kurz f&uuml;r Beginner's All-purpose Symbolic
+ Instruction Code. Entwickelt in den 50er Jahren um
+ Studenten in Programmierung zu unterrichten, wurde
+ <acronym>BASIC</acronym> in den 80er Jahren mit jedem
+ anst&auml;ndigen Personal Computer ausgeliefert und war
+ f&uuml;r viele Programmierer die erste
+ Programmiersprache. <acronym>BASIC</acronym> ist auch
+ die Grundlage f&uuml;r Visual Basic.</para>
+
+ <para>Der Bywater Basic Interpreter findet sich in der
+ Ports-Sammlung unter <filename
+ role="package">lang/bwbasic</filename> und Phil
+ Cockroft's Basic Interpreter (auch bekannt als Rabbit
+ Basic) findet sich unter <filename
+ role="package">lang/pbasic</filename>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Lisp</term>
+
+ <listitem>
+ <para>Diese Sprache wurde in den sp&auml;ten 50er Jahren
+ als Alternative zu den, zu dieser Zeit popul&auml;ren,
+ <quote>zahlenverarbeitenden</quote> Sprachen entwickelt.
+ Anstelle auf Zahlen basiert Lisp auf Listen;
+ tats&auml;chlich ist der Name Lisp eine Kurzform
+ f&uuml;r <quote>List Processing</quote> (Listen
+ abarbeiten). Sehr popul&auml;r f&uuml;
+ <acronym>AI</acronym> (Artificial Intelligence/
+ k&uuml;nstliche Intelligez) (Fach-) Kreisen.</para>
+
+ <para>Lisp ist eine extrem kraftvolle und durchdachte
+ Sprache, kann aber auch recht gro&szlig; und unhandlich
+ sein.</para>
+
+ <para>Zahlreiche Ausformungen von Lisp, die auf &unix;
+ Systemen laufen sind &uuml;ber die Ports-Sammlung
+ verf&uuml;gbar. GNU Common Lisp befindet sich in
+ <filename role="package">lang/gcl</filename>. CLISP von
+ Bruno Haible und Michael Stoll ist in <filename
+ role="package">lang/clisp</filename> zu finden. F&uuml;r
+ CMUCL, welches auch einen hoch-optimierten Compiler
+ enth&auml;lt, oder einfachere Ausformungen wie SLisp,
+ das die meisten g&auml;ngigen Lisp Konstrukte in wenigen
+ hundert Zeilen C Code enth&auml;lt sind in <filename
+ role="package">lang/cmucl</filename> und <filename
+ role="package">lang/slisp</filename> ebenfalls
+ enthalten.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Perl</term>
+
+ <listitem>
+ <para>Unter Systemadministratoren zum Schreiben von
+ Skripten sehr beliebt; wird h&auml;ufig auch auf World
+ Wide Web Servern verwendet, um
+ <acronym>CGI</acronym>-Skripte zu schreiben.</para>
+
+ <para>Perl ist in der Ports-Sammlung unter <filename
+ role="package">lang/perl5.8</filename> f&uuml;r alle
+ &os;-Versionen verf&uuml;gbar, und wird im Basissystem
+ von 4.x als <command>/usr/bin/perl</command>
+ installiert.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Scheme</term>
+
+ <listitem>
+ <para>Ein Dialekt von Lisp, der kompakter und sauberer
+ als Common Lisp ist. Dieser Dialekt ist an
+ Universit&auml;ten sehr beliebt, da er zum einen
+ f&uuml;r den Unterricht im Grundstudium einfach genug
+ ist, und zum anderen ein ausreichend hohes
+ Abstraktionsniveau f&uuml;r den Einsatz in der Forschung
+ bietet.</para>
+
+ <para>Scheme ist in der Ports-Sammlung in Form des Elk
+ Scheme Interpreters als <filename
+ role="package">lang/elk</filename> verf&uuml;gbar. Den
+ MIT Scheme Interpreter findet man unter <filename
+ role="package">lang/mit-scheme</filename>, und den SCM
+ Scheme Interpreter unter <filename
+ role="package">lang/scm</filename>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Icon</term>
+
+ <listitem>
+ <para>Icon ist eine Hochsprache mit ausgereiften
+ M&ouml;glichkeiten zur Verarbeitung von Zeichenketten
+ und Strukturen. Die unter &os; verf&uuml;gbare Version
+ von Icon steht in der Ports-Sammlung unter <filename
+ role="package">lang/icon</filename> zur
+ Verf&uuml;gung.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Logo</term>
+
+ <listitem>
+ <para>Logo ist eine leicht zu erlernende
+ Programmiersprache, welche in vielen Kursen als
+ einf&uuml;hrende Programmiersprache gew&auml;hlt wird.
+ Sie ist ein ideales Arbeitswerkzeug beim Unterricht mit
+ jungen Menschen, da mit ihr die Erstellung komplizierter
+ geometrischer Oberfl&auml;chen selbst f&uuml;r kleine
+ Kinder einfach ist.</para>
+
+ <para>Die f&uuml;r &os; aktuellste, verf&uuml;gbare
+ Version findet man in der Ports-Sammlung unter <filename
+ role="package">lang/logo</filename>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Python</term>
+
+ <listitem>
+ <para>Python ist eine objektorientierte, interpretierte
+ Programmiersprache. Die Verfechter von Python
+ argumentieren, da&szlig; sie eine der besten
+ Programmiersprachen f&uuml;r Programmieranf&auml;nger
+ sei, da sie einfach zu erlernen ist, und anderen
+ popul&auml;ren interpretierten Programmiersprachen,
+ welche zur Entwicklung gro&szlig;er und komplexer
+ Anwendungen verwendet werden, in nichts nachsteht (Perl
+ und Tcl sind zwei solcher bekannten
+ Programmiersprachen).</para>
+
+ <para>Die aktuellste Version von Python ist in der
+ Ports-Sammlung unter <filename
+ role="package">lang/python</filename>
+ verf&uuml;gbar.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Ruby</term>
+
+ <listitem>
+ <para>Ruby ist eine interpretierte und rein
+ objektorientierte Programmiersprache. Sie wurde wegen
+ ihrer leicht verst&auml;ndlichen Syntax, ihrer
+ Flexibilit&auml;t und der M&ouml;glichkeit, gro&szlig;e und
+ komplexe Programme einfach zu entwickeln und zu pflegen,
+ popul&auml;r.</para>
+
+ <para>Ruby ist in der Ports-Sammlung unter <filename
+ role="package">lang/ruby18</filename>
+ verf&uuml;gbar.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Tcl und Tk</term>
+
+ <listitem>
+ <para>Tcl ist eine einbettbare, interpretierte
+ Programmiersprache, welche aufgrund ihrer Portierbarkeit
+ auf viele unterschiedliche Plattformen eine weite
+ Verbreitung erfahren hat. Sie kann sowohl f&uuml;r die
+ schnelle Entwicklung kleinerer Prototypen, als auch (in
+ Verbindung mit Tk, einem GUI Toolkit) vollwertiger,
+ ausgereifter Programme verwendet werden.</para>
+
+ <para>Es sind mehrere Versionen von Tcl als Ports
+ f&uuml;r &os; verf&uuml;gbar. Die aktuellste Version,
+ Tcl 8.5, ist unter <filename
+ role="package">lang/tcl85</filename>
+ verf&uuml;gbar.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Compiler</title>
+
+ <para>Compiler sind eher anders. Zuerst schreibt man seinen
+ Code unter Verwendung eines Editors in eine Datei (oder
+ mehrere Dateien). Anschlie&szlig;end ruft man den Compiler auf
+ um zu sehen, ob dieser das Programm annimmt. Wenn das Programm
+ nicht kompiliert werden konnte, mu&szlig; man die Z&auml;hne
+ zusammenbeissen und wieder zum Editor zur&uuml;ckkehren; falls
+ das Programm kompiliert und eine ausf&uuml;hrbare Anwendung
+ erzeugt wurde, kann man diese &uuml;ber eine
+ Eingabeaufforderung oder &uuml;ber einen Debugger aufrufen um
+ zu sehen, ob sie auch funktioniert.
+
+ <footnote>
+ <para>Wenn die Anwendung &uuml;ber eine Eingabeaufforderung
+ gestartet wird k&ouml;nnte bei Auftreten eines
+ Programmfehlers dieses abgebrochen und ein Speicherabbild
+ erzeugt werden.</para>
+ </footnote>
+ </para>
+
+ <para>Offensichtlich ist diese Art der Programmierung nicht
+ so direkt wie die Verwendung eines Interpreters. Jedoch sind
+ auf diese Weise viele Dinge m&ouml;glich, die mit einem
+ Interpreter nur sehr schwer oder &uuml;berhaupt nicht
+ realisierbar w&auml;ren, wie z.B. das Schreiben von Code, der
+ sehr eng mit dem Betriebsystem zusammen arbeitet&mdash;oder
+ das Schreiben eines eigenen Betriebsystems selbst! Des
+ weiteren ist so das Erzeugen von sehr effizientem Code
+ m&ouml;glich, da sich der Compiler f&uuml;r die Optimierung
+ Zeit nehmen kann, was bei einem Interpreter inakzeptabel
+ w&auml;re. Ferner ist das Verbreiten von Programmen, welche
+ f&uuml;r einen Compiler geschrieben wurden, einfacher als
+ welche, die f&uuml;r einen Interpreter geschrieben
+ wurden&mdash;man muss in ersterem Fall nur die
+ ausf&uuml;hrbare Datei verbreiten, vorausgesetzt, da&szlig; das
+ gleiche Betriebssystem verwendet wird.</para>
+
+ <para>Programmiersprachen, die kompiliert werden, sind unter
+ anderem Pascal, C und C++. C und C++ sind eher unbarmherzige
+ Programmiersprachen und daher eher f&uuml;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&uuml;tzung f&uuml;r
+ Pascal, stellt jedoch &uuml;ber die Ports-Sammlung den
+ Free Pascal Compiler unter <filename
+ role="package">lang/fpc</filename> zur Verf&uuml;gung.</para>
+
+ <para>Da der editier-kompilier-ausf&uuml;hr-debug-Kreislauf
+ unter Verwendung mehrerer Programme eher m&uuml;hsam ist haben
+ viele Hersteller von Compilern integrierte
+ Entwicklungsumgebungen (Integrated Development Environment;
+ auch kurz <acronym>IDE</acronym>) entwickelt. FreeBSD bietet
+ zwar im Basissystem keine IDE an, stellt jedoch &uuml;ber die
+ Ports-Sammlung IDEs wie <filename
+ role="package">devel/kdevelop</filename> oder
+ <application>Emacs</application> zur Verf&uuml;gung, wobei
+ letztere weit verbreitet ist. Die Verwendung von
+ <application>Emacs</application> als IDE wird unter <xref
+ linkend="emacs"> diskutiert.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="tools-compiling">
+ <title>Kompilieren mit dem <command>cc</command></title>
+
+ <para>Dieser Abschnitt behandelt ausschlie&szlig;lich den GNU
+ Compiler f&uuml;r C und C++, da dieser bereits im Basissystem
+ von FreeBSD enthalten ist. Er kann mittels <command>cc</command>
+ oder <command>gcc</command> aufgerufen werden. Die Details zur
+ Erstellung einer Anwendung mit einem Interpreter variieren
+ zwischen verschiedenen Interpretern mehr oder weniger stark, und
+ werden meist ausf&uuml;hrlich in der zugeh&ouml;rigen
+ Dokumentation oder Online-Hilfe beschrieben.</para> <para>Sobald
+ Sie Ihr Meisterwerk fertig geschrieben haben besteht der
+ n&auml;chste Schritt darin, dieses (hoffentlich!) unter FreeBSD
+ zum Laufen zu bekommen. Dies beinhaltet &uuml;blicherweise
+ mehrere Schritte, wobei jeder einzelne Schritt von einem
+ separaten Programm durchgef&uuml;hrt wird.</para>
+
+ <procedure>
+ <step>
+ <para>Aufbereiten Ihres Quelltextes durch Entfernen von
+ Kommentaren, sowie weiteren Tricks wie das Ersetzen von
+ Macros in C.</para>
+ </step>
+
+ <step>
+ <para>&Uuml;berpr&uuml;fen der Syntax Ihres Quelltextes, um
+ die Einhaltung der Sprachregeln sicherzustellen. Wenn Sie
+ diese verletzt haben werden entsprechende Fehlermeldungen
+ Ihnen dies mitteilen!</para>
+ </step>
+
+ <step>
+ <para>&Uuml;bersetzen des Quelltextes in Assemblersprache
+ &mdash;diese ist dem eigentlichen Maschinencode schon sehr
+ nahe, jedoch immer noch f&uuml;r Menschen lesbar.
+ Angeblich.
+
+ <footnote>
+ <para>Um genau zu sein &uuml;bersetzt der
+ <command>cc</command> den Quelltext an dieser Stelle
+ nicht in Assemblersprache, sondern in seine eigene,
+ maschinenunabh&auml;ngige Sprache namens
+ <firstterm>p-code</firstterm>.</para>
+ </footnote>
+ </para>
+ </step>
+
+ <step>
+ <para>&Uuml;bersetzen der Assemblersprache in
+ Maschinencode&mdash;genau, wir sprechen hier von Bits und
+ Bytes, Einsen und Nullen.</para>
+ </step>
+
+ <step>
+ <para>&Uuml;berpr&uuml;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.</para>
+ </step>
+
+ <step>
+ <para>Wenn aus mehreren Quelltextdateien eine
+ ausf&uuml;hrbare Datei erstellt werden soll wird
+ herausgefunden, wie die einzelnen Codeteile
+ zusammengef&uuml;gt werden m&uuml;ssen.</para>
+ </step>
+
+ <step>
+ <para>Ausarbeiten, wie das Programm aussehen muss, damit
+ der Lader zur Laufzeit des Systems dieses in den Speicher
+ laden und ausf&uuml;hren kann.</para>
+ </step>
+
+ <step>
+ <para>Endg&uuml;ltiges Schreiben der ausf&uuml;hrbaren Datei
+ in das Dateisystem.</para>
+ </step>
+ </procedure>
+
+ <para>Das Wort <firstterm>kompilieren</firstterm> wird h&auml;ufig
+ f&uuml;r die Schritte 1 bis 4 verwendet&mdash;die anderen werden
+ mit dem Wort <firstterm>verlinken</firstterm> zusammengefasst.
+ Manchmal wird Schritt 1 auch als
+ <firstterm>Pre-Processing</firstterm> und die Schritte 3-4 als
+ <firstterm>assemblieren</firstterm> bezeichnet.</para>
+
+ <para>Gl&uuml;cklicherweise werden alle diese Details vor Ihnen
+ verborgen, da <command>cc</command> ein Frontend ist, welches
+ sich um die Ausf&uuml;hrung all dieser Programme mit den
+ richtigen Argumenten f&uuml;r Sie k&uuml;mmert; einfaches
+ eingeben von</para>
+
+ <screen>&prompt.user; <userinput>cc foobar.c</userinput></screen>
+
+ <para>f&uuml;hrt zur &Uuml;bersetzung von
+ <filename>foobar.c</filename> durch alle bereits erw&auml;hnten
+ Schritte. Wenn Sie mehr als eine Datei &uuml;bersetzen wollen
+ m&uuml;ssen Sie etwas wie folgt eingeben</para>
+
+ <screen>&prompt.user; <userinput>cc foo.c bar.c</userinput></screen>
+
+ <para>Beachten Sie, da&szlig; die &Uuml;berpr&uuml;fung der Syntax
+ genau dies tut&mdash;das reine &Uuml;berpr&uuml;fen der Syntax.
+ Es findet keine &Uuml;berpr&uuml;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.
+
+ <footnote>
+ <para>Falls Sie es nicht wu&szlig;ten, Binary Sort ist, im
+ Gegensatz zu Bubble Sort, eine effektive M&ouml;glichkeit,
+ Dinge zu sortieren.</para>
+ </footnote>
+ </para>
+
+ <para>Es gibt haufenweise Optionen f&uuml;r <command>cc</command>,
+ die alle in der zugeh&ouml;rigen Manualpage beschrieben werden.
+ Im Folgenden werden ein paar der wichtigsten Optionen mit
+ Beispielen ihrer Anwendung gezeigt.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-o <replaceable>filename</replaceable></option></term>
+
+ <listitem>
+ <para>Die Name der Ausgabedatei. Wenn Sie diese Option nicht
+ verwenden erstellt <command>cc</command> eine Datei mit
+ dem Namen <filename>a.out</filename>.
+
+ <footnote>
+ <para>Der Grund daf&uuml;r ist im Haufen der Geschichte
+ begraben.</para>
+ </footnote>
+ </para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc foobar.c</userinput> <lineannotation>executable is <filename>a.out</filename></lineannotation>
+&prompt.user; <userinput>cc -o foobar foobar.c</userinput> <lineannotation>executable is <filename>foobar</filename></lineannotation>
+ </screen>
+ </informalexample>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+
+ <listitem>
+ <para>Dies kompiliert die Datei nur, verlinkt sie jedoch
+ nicht. N&uuml;tzlich f&uuml;r Spielereien, um die Syntax
+ auf Korrektheit zu &uuml;berpr&uuml;fen, oder falls Sie
+ ein <filename>Makefile</filename> verwenden.</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -c foobar.c</userinput>
+ </screen>
+ </informalexample>
+
+ <para>Dieser Befehl erzeugt eine
+ <firstterm>Objektdatei</firstterm> (nicht ausf&uuml;hrbar)
+ mit den Namen <filename>foobar.o</filename>. Diese kann
+ mit anderen Objektdateien zusammen zu einer
+ ausf&uuml;hrbaren Datei verlinkt werden.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-g</option></term>
+
+ <listitem>
+ <para>Diese Option erzeugt die Debug-Version einer
+ ausf&uuml;hrbaren Datei. Dabei f&uuml;gt der Compiler
+ zus&auml;tzliche Informationen dar&uuml;ber, welcher
+ Funktionsaufruf zu welcher Zeile im Quelltext geh&ouml;rt,
+ der ausf&uuml;hrbaren Datei hinzu. Ein Debugger kann Ihnen
+ mit Hilfe dieser Information den zugeh&ouml;rigen
+ Quelltext anzeigen, w&auml;hrend Sie den Programmverlauf
+ schrittweise verfolgen, was <emphasis>sehr</emphasis>
+ hilfreich sein kann; der Nachteil dabei ist, da&szlig;
+ durch die zus&auml;tzlichen Informationen das Programm
+ viel gr&ouml;&szlig;er wird. Normalerweise verwendet man
+ die Option <option>-g</option> w&auml;hrend der
+ Entwicklung eines Programms, und f&uuml;r die
+ <quote>Release-Version</quote>, wenn man von der
+ Korrektheit des Programms &uuml;berzeugt ist, kompiliert
+ man das Programm dann ohne diese Option.</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -g foobar.c</userinput>
+ </screen>
+ </informalexample>
+
+ <para>Mit diesem Befehl wird eine Debug-Version des
+ Programms erzeugt.
+
+ <footnote>
+ <para>Beachten Sie, da&szlig; an dieser Stelle die
+ Option <option>-o</option> zum Festlegen des Namens
+ der ausf&uuml;hrbaren Datei nicht verwendet wurde,
+ weswegen an dieser Stelle die erzeugte Datei
+ <filename>a.out</filename> hei&szlig;t. Die Erzeugung
+ einer Debug-Version namens <filename>foobar</filename>
+ ist als &Uuml;bung dem Leser &uuml;berlassen!</para>
+ </footnote>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O</option></term>
+
+ <listitem>
+ <para>Diese Option erzeugt eine optimierte Version der
+ ausf&uuml;hrbaren Datei. Der Compiler verwendet einige
+ clevere Tricks, um das erzeugte Programm schneller zu
+ machen. Sie k&ouml;nnen hinter der Option
+ <option>-O</option> eine Zahl angeben, um eine
+ h&ouml;heres Level der Optimierung festzulegen. Dadurch
+ wird jedoch h&auml;ufig eine fehlerhafte Optimierung
+ seitens des Compilers aufgedeckt. Zum Beispiel erzeugte
+ die Version des <command>cc</command>, welche mit dem
+ FreeBSD Release 2.1.0 mitgeliefert wurde, bei Verwendung
+ der Option <option>-O2</option> unter bestimmten
+ Umst&auml;nden falschen Code.</para>
+
+ <para>Optimierungen werden normalerweise nur beim
+ Kompilieren von Release-Versionen aktiviert.</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -O -o foobar foobar.c</userinput>
+ </screen>
+ </informalexample>
+
+ <para>Durch diesen Befehl wird eine optimierte Version von
+ <filename>foobar</filename> erzeugt.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Die folgenden drei Flags zwingen den <command>cc</command>
+ dazu, Ihren Code auf die Einhaltung der internationalen
+ Standards hin zu &uuml;berpr&uuml;fen, welche h&auml;ufig als
+ <acronym>ANSI</acronym> Standards bezeichnet werden, obwohl sie
+ streng genommen zum <acronym>ISO</acronym> Standard
+ geh&ouml;ren.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-Wall</option></term>
+
+ <listitem>
+ <para>Aktivieren aller Warnmeldungen, die die Autoren des
+ <command>cc</command> f&uuml;r wichtig halten. Trotz des
+ Namens dieser Option werden dadurch nicht s&auml;mtliche
+ Warnungen ausgegeben, die der <command>cc</command>
+ ausgeben k&ouml;nnte.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-ansi</option></term>
+
+ <listitem>
+ <para>Deaktivieren der meisten, jedoch nicht aller,
+ nicht-<acronym>ANSI</acronym>&nbsp;C Eigenschaften, die
+ der <command>cc</command> bietet. Trotz des Namens ist
+ durch diese Option nicht sichergestellt, da&szlig; Ihr
+ Code diese Standards auch vollst&auml;ndig
+ einh&auml;lt.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-pedantic</option></term>
+
+ <listitem>
+ <para>Deaktivieren <emphasis>aller</emphasis> Eigenschaften
+ des <command>cc</command>, welche nicht konform zu
+ <acronym>ANSI</acronym>&nbsp;C sind.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Ohne diese Flags wird Ihnen der <command>cc</command> die
+ Verwendung eigener Erweiterungen des Standards erlauben. Einige
+ dieser Erweiterungen sind zwar sehr n&uuml;tzlich, werden jedoch
+ nicht von anderen Compilern unterst&uuml;tzt&mdash;eigentlich
+ ist eines der Hauptziele des Standards, das Leute Code so
+ schreiben k&ouml;nnen, da&szlig; dieser mit jedem Compiler auf
+ beliebigen Systemen funktioniert. Dies wird h&auml;ufig als
+ <firstterm>portabler Code</firstterm> bezeichnet.</para>
+
+ <para>Im Allgemeinen sollten Sie versuchen, Ihren Code so portabel
+ wie m&ouml;glich zu schreiben, da Sie ansonsten eventuell das
+ gesamte Programm noch einmal neu schreiben m&uuml;ssen, falls
+ dieser in einer anderen Umgebung laufen soll&mdash;und wer
+ wei&szlig; schon was er in ein paar Jahren verwenden
+ wird?</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
+ </informalexample>
+
+ <para>Durch diesen Befehl wird eine ausf&uuml;hrbare Datei namens
+ <filename>foobar</filename> erzeugt, nachdem
+ <filename>foobar.c</filename> auf die Einhaltung der Standards
+ &uuml;berpr&uuml;ft wurde.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-l<replaceable>library</replaceable></option></term>
+
+ <listitem>
+ <para>Mit dieser Option kann eine Bibliothek mit Funktionen
+ angegeben werden, die w&auml;hrend des Verlinkens
+ verwendet wird.</para>
+
+ <para>Das am h&auml;ufigsten auftretende Beispiel dieser
+ Option ist die &Uuml;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&uuml;ssen.</para>
+
+ <para>Angenommen eine Bibliothek hei&szlig;t
+ <filename>lib<replaceable>irgendwas</replaceable>.a</filename>,
+ dann m&uuml;ssen Sie dem <command>cc</command> als
+ Argument
+ <option>-l<replaceable>irgendwas</replaceable></option>
+ &uuml;bergeben. Zum Beispiel hei&szlig;t die
+ Mathematik-Bibliothek <filename>libm.a</filename>, und
+ daher m&uuml;ssen Sie dem <command>cc</command> als
+ Argument <option>-lm</option> &uuml;bergeben. Ein
+ typisches <quote>Manko</quote> der Mathematik-Bibliothek
+ ist, da&szlig; diese immer die letzte Bibliothek auf der
+ Kommandozeile sein mu&szlig;.</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput>
+ </screen>
+ </informalexample>
+
+ <para>Durch diesen Befehl werden die Funktionen aus der
+ Mathematik-Bibliothek in <filename>foobar</filename>
+ gelinkt.</para>
+
+ <para>Wenn Sie C++-Code kompilieren wollen, m&uuml;ssen Sie
+ <option>-lg++</option>, bzw. <option>-lstdc++</option>
+ falls Sie FreeBSD 2.2 oder neuer verwenden, zu Ihrer
+ Kommandozeile hinzuf&uuml;gen, um Ihr Programm gegen die
+ Funktionen der C++ Bibliothek zu linken. Alternativ
+ k&ouml;nnen Sie anstatt <command>cc</command> auch
+ <command>c++</command> aufrufen, welcher dies f&uuml;r Sie
+ erledigt. <command>c++</command> kann unter FreeBSD auch
+ als <command>g++</command> aufgerufen werden.</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>Bei FreeBSD 2.1.6 oder &auml;lter</lineannotation>
+&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>Bei FreeBSD 2.2 und neuer</lineannotation>
+&prompt.user; <userinput>c++ -o foobar foobar.cc</userinput>
+ </screen>
+ </informalexample>
+
+ <para>Beide Varianten erzeugen eine ausf&uuml;hrbare
+ <filename>foobar</filename> aus der C++ Quelltextdatei
+ <filename>foobar.cc</filename>. Beachten Sie bitte,
+ da&szlig; auf &unix; Systemen C++ Quelltextdateien
+ &uuml;blicherweise auf <filename>.C</filename>,
+ <filename>.cxx</filename> oder <filename>.cc</filename>
+ enden, und nicht wie bei &ms-dos; auf
+ <filename>.cpp</filename> (welche schon anderweitig
+ benutzt wurde). Der <command>gcc</command> hat
+ normalerweise anhand dieser Information entschieden,
+ welcher Compiler f&uuml;r die Quelltextdatei zum Einsatz
+ kommen soll; allerdings gilt diese Einschr&auml;nkung
+ jetzt nicht mehr, und Sie k&ouml;nnen Ihre C++-Dateien
+ ungestraft auf <filename>.cpp</filename> enden
+ lassen!</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect2>
+ <title>H&auml;ufig auftretende <command>cc</command>-Fragen und
+ -Probleme</title>
+
+ <qandaset>
+ <qandaentry>
+ <question>
+ <para>Ich versuche ein Programm zu schreiben, welches die
+ Funktion <function>sin()</function> verwendet, erhalte
+ jedoch eine Fehlermeldung. Was bedeutet diese?</para>
+
+ <informalexample>
+ <screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment
+ </screen>
+ </informalexample>
+ </question>
+
+ <answer>
+ <para>Wenn Sie mathematische Funktionen wie
+ <function>sin()</function> verwenden wollen, m&uuml;ssen
+ Sie den <command>cc</command> anweisen, die
+ Mathematik-Bibliothek wie folgt zu verlinken:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput>
+ </screen>
+ </informalexample>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>So, ich habe jetzt dieses einfache Programm als
+ &Uuml;bung f&uuml;r <option>-lm</option> geschrieben.
+ Alles was es macht ist, 2.1 hoch 6 zu berechnen.</para>
+
+ <informalexample>
+ <programlisting>#include &lt;stdio.h&gt;
+
+int main() {
+ float f;
+
+ f = pow(2.1, 6);
+ printf("2.1 ^ 6 = %f\n", f);
+ return 0;
+}
+ </programlisting>
+ </informalexample>
+
+ <para>und ich habe es wie folgt kompiliert:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc temp.c -lm</userinput>
+ </screen>
+ </informalexample>
+
+ <para>wie mir gesagt wurde. Allerdings bekomme ich jetzt
+ bei der Ausf&uuml;hrung die folgende Ausgabe:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>./a.out</userinput>
+2.1 ^ 6 = 1023.000000
+ </screen>
+ </informalexample>
+
+ <para>Das ist <emphasis>nicht</emphasis> die richtige
+ Antwort! Was ist hier los?</para>
+ </question>
+
+ <answer>
+ <para>Wenn der Compiler Ihren Funktionsaufruf sieht,
+ &uuml;berpr&uuml;ft er, ob er schon einmal einen
+ Prototypen f&uuml;r diese gesehen hat. Wenn nicht nimmt
+ er als R&uuml;ckgabewert den Typ <type>int</type> an,
+ was sicherlich nicht das ist, was Sie an dieser Stelle
+ wollen.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Wie kann ich das korrigieren?</para>
+ </question>
+
+ <answer>
+ <para>Die Prototypen der mathematischen Funktionen
+ befinden sich in der Datei <filename>math.h</filename>.
+ Wenn Sie diese Datei in Ihrem Quelltext includen ist der
+ Compiler in der Lage, den Prototypen zu finden, und wird
+ aufh&ouml;ren, seltsame Dinge mit Ihrer Berechnung zu
+ machen!</para>
+
+ <informalexample>
+ <programlisting>#include &lt;math.h&gt;
+#include &lt;stdio.h&gt;
+
+int main() {
+...
+ </programlisting>
+ </informalexample>
+
+ <para>Nach erneutem Compilieren sollte das Folgende bei
+ der Ausf&uuml;hrung ausgegeben werden:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>./a.out</userinput>
+2.1 ^ 6 = 85.766121
+ </screen>
+ </informalexample>
+
+ <para>Wenn Sie irgendwelche mathematischen Funktionen
+ verwenden sollten Sie <emphasis>immer</emphasis> die
+ Datei <filename>math.h</filename> includen und nicht
+ vergessen, Ihr Programm gegen die Mathematik-Bibliothek
+ zu verlinken.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Ich habe eine Datei mit dem Namen
+ <filename>foobar.c</filename> kompiliert, kann jedoch
+ nirgends eine ausf&uuml;hrbare Datei namens
+ <filename>foobar</filename> finden. Wo befindet sich
+ diese?</para>
+ </question>
+
+ <answer>
+ <para>Denken Sie daran, da&szlig; der
+ <command>cc</command> die ausf&uuml;hrbare Datei
+ <filename>a.out</filename> nennt, wenn Sie nicht
+ explizit einen Namen angeben. Verwenden Sie in solch
+ einem Fall die Option
+ <option>-o&nbsp;<replaceable>filename</replaceable></option>:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -o foobar foobar.c</userinput>
+ </screen>
+ </informalexample>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>OK, ich habe eine ausf&uuml;hrbare Datei namens
+ <filename>foobar</filename>, ich kann sie sehen, wenn
+ ich <command>ls</command> aufrufe. Gebe ich jedoch
+ <command>foobar</command> in die Kommandozeile ein wird
+ mir gesagt, da&szlig; eine Datei mit diesem Namen nicht
+ existiert. Warum kann die Datei nicht gefunden
+ werden?</para>
+ </question>
+
+ <answer>
+ <para>Im Gegensatz zu &ms-dos; sucht &unix; nicht im
+ aktuellen Verzeichnis nach einem ausf&uuml;hrbaren
+ Programm, das Sie versuchen auszuf&uuml;hren, solange
+ Sie dies nicht explizit mit angeben. Sie k&ouml;nnen
+ entweder <command>./foobar</command> eingeben, was
+ soviel bedeutet wie <quote>f&uuml;hre eine Datei namens
+ <filename>foobar</filename> im aktuellen Verzeichnis
+ aus</quote>, oder Sie k&ouml;nnen Ihre Umgebungsvariable
+ <envar>PATH</envar> so erweitern, da&szlig; sie
+ &auml;hnlich wie folgt aussieht</para>
+
+ <informalexample>
+ <screen>bin:/usr/bin:/usr/local/bin:.
+ </screen>
+ </informalexample>
+
+ <para>Der Punkt am Ende bedeutet <quote>siehe im aktuellen
+ Verzeichnis nach, wenn es in keinem der anderen zu
+ finden war</quote>.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Ich habe meine ausf&uuml;hrbare Datei
+ <filename>test</filename> genannt, allerdings passiert
+ nichts wenn ich diese aufrufe. Was ist hier los?</para>
+ </question>
+
+ <answer>
+ <para>Bei den meisten &unix;-Systeme existiert bereits
+ ein Programm mit dem Namen <command>test</command> im
+ Verzeichnis <filename>/usr/bin</filename>, und die Shell
+ nimmt dieses, bevor sie im aktuellen Verzeichnis
+ nachsieht. Sie k&ouml;nnen entweder den folgenden Befehl
+ eingeben:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>./test</userinput>
+ </screen>
+ </informalexample>
+
+ <para>oder Sie k&ouml;nnen einen geeigneteren Namen
+ f&uuml;r Ihr Programm w&auml;hlen!</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Ich habe mein Programm kompiliert und bei dessen
+ Aufruf sah zuerst alles gut aus. Jedoch gab es dann eine
+ Fehlermeldung, welche irgendetwas mit <errorname>core
+ dumped</errorname> lautete. Was bedeutet das?</para>
+ </question>
+
+ <answer>
+ <para>Der Name <firstterm>core dump</firstterm> stammt
+ noch aus sehr fr&uuml;hen Zeiten von &unix;, als die
+ Maschinen noch Kernspeicher zum Speichern von Daten
+ verwendeten. Einfach ausgedr&uuml;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
+ <filename>core</filename> geschrieben, welche der
+ Programmierer dann n&auml;her untersuchen konnte, um die
+ Ursache des Fehlers herauszufinden.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Faszinierendes Zeugs, aber was soll ich jetzt
+ machen?</para>
+ </question>
+
+ <answer>
+ <para>Verwenden Sie den <command>gdb</command>, um das
+ Speicherabbild zu untersuchen (siehe <xref
+ linkend="debugging">).</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Als mein Programm den core dump erzeugt hat, sagte
+ es etwas von einem <errorname>segmentation
+ fault</errorname>. Was ist das?</para>
+ </question>
+
+ <answer>
+ <para>Diese Meldung hei&szlig;t im Prinzip, da&szlig; Ihr
+ Programm eine illegale Operation mit dem Speicher
+ durchf&uuml;hren wollte; &unix; wurde so entworfen,
+ da&szlig; es das andere Programme und das Betriebssystem
+ selbst vor wildgewordenen Programmen
+ sch&uuml;tzt.</para>
+
+ <para>H&auml;ufige Ursachen hierf&uuml;r sind:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Der Versuch, einen <symbol>NULL</symbol>-Zeiger
+ zu beschreiben, z.B.</para>
+
+ <programlisting>char *foo = NULL;
+strcpy(foo, "bang!");
+ </programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Einen Zeiger zu verwenden, welcher noch nicht
+ initialisiert wurde, z.B.</para>
+
+ <programlisting>char *foo;
+strcpy(foo, "bang!");
+ </programlisting>
+
+ <para>Der Zeiger hat einen zuf&auml;lligen Wert,
+ welcher mit etwas Gl&uuml;ck in einen Bereich des
+ Speichers zeigt, der f&uuml;r Ihr Programm nicht
+ verf&uuml;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&auml;ndert dort ihre eigenen Datenstrukturen,
+ was zu sehr seltsamen Fehlern Ihres Programmes
+ f&uuml;hrt.</para>
+ </listitem>
+
+ <listitem>
+ <para>Der Versuch, auf Daten au&szlig;erhalb eines
+ Arrays zuzugreifen, z.B.</para>
+
+ <programlisting>int bar[20];
+bar[27] = 6;
+ </programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Der Versuch, Daten in eine Speicherbereich zu
+ schreiben, der nur lesbar ist, z.B.</para>
+
+ <programlisting>char *foo = "My string";
+strcpy(foo, "bang!");
+ </programlisting>
+
+ <para>&unix;-Compiler speichern h&auml;ufig feste
+ Zeichenketten wie <literal>"My string"</literal> in
+ nur lesbaren Speicherbereichen ab.</para>
+ </listitem>
+
+ <listitem>
+ <para>Wenn man unerlaubte Operationen mit
+ <function>malloc()</function> und
+ <function>free()</function> ausf&uuml;hrt,
+ z.B.</para>
+
+ <programlisting>char bar[80];
+free(bar);
+ </programlisting>
+
+ <para>oder</para>
+
+ <programlisting>char *foo = malloc(27);
+free(foo);
+free(foo);
+ </programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <para>Einzelne solcher Fehler f&uuml;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&uuml;rzen.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Wenn ich einen core dump erhalte erscheint
+ manchmal die Meldung <errorname>bus error</errorname>.
+ In meinem &unix;-Buch steht, da&szlig; die Ursache ein
+ Hardwareproblem sei. Der Computer scheint aber weiterhin
+ zu funktionieren. Ist dies wahr?</para>
+ </question>
+
+ <answer>
+ <para>Nein, gl&uuml;cklicherweise nicht (es sei denn Sie
+ haben wirklich ein Hardwareproblem&hellip;).
+ &Uuml;blicherweise ist dies ein Weg Ihnen mitzuteilen,
+ da&szlig; Sie auf Speicher in einer Weise zugegriffen
+ haben, in der Sie dies nicht tun sollten.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Diese Sache mit den core dumps h&ouml;rt sich sehr
+ n&uuml;tzlich an, wenn ich so etwas selber an beliebiger
+ Stelle bewirken k&ouml;nnte. Kann ich das tun, oder
+ mu&szlig; ich warten bis ein Fehler auftritt?</para>
+ </question>
+
+ <answer>
+ <para>Ja, nehmen sie einfach eine andere Konsole oder
+ XTerm und f&uuml;hren Sie</para>
+
+ <screen>&prompt.user; <userinput>ps</userinput>
+ </screen>
+
+ <para>aus, um die Prozess-ID Ihres Programms
+ herauszufinden. F&uuml;hren Sie
+ anschlie&szlig;end</para>
+
+ <screen>&prompt.user; <userinput>kill -ABRT <replaceable>pid</replaceable></userinput>
+ </screen>
+
+ <para>aus, wobei
+ <parameter><replaceable>pid</replaceable></parameter>
+ die Prozess-ID ist, die Sie vorher ermittelt
+ haben.</para>
+
+ <para>Dies ist n&uuml;tzlich, wenn sich Ihr Programm z.B.
+ in einer Endlosschleife verfangen hat. Sollte Ihr
+ Programm das Signal <symbol>SIGABRT</symbol> abfangen,
+ gibt es noch andere M&ouml;glichkeiten, die denselben
+ Effekt haben.</para>
+
+ <para>Alternativ k&ouml;nnen Sie einen core dump aus
+ Ihrem Programm heraus erstellen, indem Sie die Funktion
+ <function>abort()</function> aufrufen. Weitere
+ Informationen dar&uuml;ber k&ouml;nnen Sie in der
+ Manualpage &man.abort.3; nachlesen.</para>
+
+ <para>Wenn Sie einen core dump von au&szlig;erhalb Ihres
+ Programms erzeugen wollen, ohne dabei den Prozess
+ abzubrechen, k&ouml;nnen Sie das Programm
+ <command>gcore</command> verwenden. Weitere
+ Informationen dazu finden Sie in der zugeh&ouml;rigen
+ Manualpage &man.gcore.1;.</para>
+
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </sect2>
+ </sect1>
+
+ <sect1 id="tools-make">
+ <title>Make</title>
+
+ <sect2>
+ <title>Was ist <command>make</command>?</title>
+
+ <para>Wenn Sie an einem einfachen Programm mit nur einer oder
+ zwei Quelltextdateien arbeiten, ist die Eingabe von</para>
+
+ <screen>&prompt.user; <userinput>cc file1.c file2.c</userinput></screen>
+
+ <para>zwar nicht aufwendig, wird aber mit zunehmender Anzahl
+ der Quelltextdateien sehr l&auml;stig&mdash;und auch das
+ Kompilieren kann eine Weile dauern.</para>
+
+ <para>Eine M&ouml;glichkeit dies zu umgehen besteht in der
+ Verwendung von Objektdateien, wobei man nur die
+ Quelltextdateien neu kompiliert, die ver&auml;ndert wurden. So
+ k&ouml;nnten wir etwa folgendes erhalten:</para>
+
+ <screen>&prompt.user; <userinput>cc file1.o file2.o</userinput> &hellip; <userinput>file37.c</userinput> &hellip;</screen>
+
+ <para>falls wir seit dem letzten Kompiliervorgang nur die Datei
+ <filename>file37.c</filename> ver&auml;ndert haben. Dadurch
+ k&ouml;nnte der Kompiliervorgang um einiges beschleunigt
+ werden, es mu&szlig; jedoch immer noch alles von Hand
+ eingegeben werden.</para>
+
+ <para>Oder wir k&ouml;nnten uns ein Shell Skript schreiben.
+ Dieses w&uuml;rde jedoch alles immer wieder neu kompilieren,
+ was bei einem gro&szlig;en Projekt sehr ineffizient
+ w&auml;re.</para>
+
+ <para>Was ist, wenn wir hunderte von Quelltextdateien
+ h&auml;tten? Was ist, wenn wir in einem Team mit anderen
+ Leuten arbeiten w&uuml;rden, die vergessen uns Bescheid zu
+ sagen, falls sie eine der Quelltextdateien ver&auml;ndert
+ haben, die wir ebenfalls benutzen?</para>
+
+ <para>Vielleicht k&ouml;nnten wir beide L&ouml;sungen
+ kombinieren und etwas wie ein Shell Skript schreiben, welches
+ eine Art magische Regel enthalten w&uuml;rde, die feststellt,
+ welche Quelltextdateien neu kompiliert werden m&uuml;ssten.
+ Alles was wir br&auml;uchten w&auml;re ein Programm, das diese
+ Regeln verstehen k&ouml;nnte, da diese Aufgabe etwas zu
+ kompliziert f&uuml;r eine Shell ist.</para>
+
+ <para>Dieses Programm hei&szlig;t <command>make</command>. Es
+ liest eine Datei namens <firstterm>makefile</firstterm>,
+ welche ihm sagt, wie unterschiedliche Dateien voneinander
+ abh&auml;ngen, und berechnet, welche Dateien neu kompiliert
+ werden m&uuml;ssen und welche nicht. Zum Beispiel k&ouml;nnte
+ eine Regel etwas sagen wie <quote>wenn
+ <filename>fromboz.o</filename> &auml;lter als
+ <filename>fromboz.c</filename> ist, bedeutet dies, da&szlig;
+ jemand die Datei <filename>fromboz.c</filename> ver&auml;ndert
+ haben mu&szlig;, und diese daher neu kompiliert werden
+ mu&szlig;.</quote> Das makefile enth&auml;lt au&szlig;erdem
+ Regeln die make sagen, <emphasis>wie</emphasis> die
+ Quelltextdatei neu kompiliert werden mu&szlig;, was dieses
+ Tool noch sehr viel m&auml;chtiger macht.</para>
+
+ <para>Makefiles werden normalerweise im selben Verzeichnis
+ wie die Quelltextdateien abgelegt, zu denen sie geh&ouml;ren,
+ und kann <filename>makefile</filename>,
+ <filename>Makefile</filename> oder
+ <filename>MAKEFILE</filename> hei&szlig;en. Die meisten
+ Programmierer verwenden den Namen
+ <filename>Makefile</filename>, da diese Schreibweise
+ daf&uuml;r sorgt, da&szlig; die Datei gut lesbar ganz oben in
+ der Verzeichnisliste aufgef&uuml;hrt wird.
+
+ <footnote>
+ <para>Verwenden Sie nicht <filename>MAKEFILE</filename> mit
+ lauter Gro&szlig;buchstaben, da diese Schreibweise
+ h&auml;ufig f&uuml;r Dokumentationsdateien wie
+ <filename>README</filename> benutzt wird.</para>
+ </footnote>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Beispielhafte Verwendung von <command>make</command></title>
+
+ <para>Hier ist eine sehr einfache make Datei:</para>
+
+ <programlisting>foo: foo.c
+ cc -o foo foo.c</programlisting>
+
+ <para>Sie besteht aus zwei Zeilen, einer
+ Abh&auml;ngigkeitszeile und einer Erzeugungszeile.</para>
+
+ <para>Die Abh&auml;ngigkeitszeile hier besteht aus dem Namen
+ des Programms (auch <firstterm>Ziel</firstterm> genannt),
+ gefolgt von einem Doppelpunkt und einem Leerzeichen, und
+ anschlie&szlig;end dem Namen der Quelltextdatei. Wenn
+ <command>make</command> diese Zeile liest &uuml;berpr&uuml;ft
+ es die Existenz von <filename>foo</filename>; falls diese
+ Datei existiert vergleicht es das Datum der letzten
+ &Auml;nderung von <filename>foo</filename> mit der von
+ <filename>foo.c</filename>. Falls <filename>foo</filename>
+ nicht existiert, oder &auml;lter als
+ <filename>foo.c</filename> ist, liest es die Erzeugungszeile
+ um herauszufinden, was zu tun ist. Mit anderen Worten, dies
+ ist die Regel die festlegt, wann <filename>foo.c</filename>
+ neu kompiliert werden mu&szlig;.</para>
+
+ <para>Die Erzeugungszeile beginnt mit einem <token>tab</token>
+ (dr&uuml;cken Sie dazu die <keycap>tab</keycap>-Taste) gefolgt
+ von dem Befehl, mit dem Sie <filename>foo</filename> manuell
+ erzeugen w&uuml;rden. Wenn <filename>foo</filename> veraltet
+ ist, oder nicht existiert, f&uuml;hrt <command>make</command>
+ diesen Befehl aus, um die Datei zu erzeugen. Mit anderen
+ Worten, dies ist die Regel die make sagt, wie
+ <filename>foo.c</filename> kompiliert werden mu&szlig;.</para>
+
+ <para>Wenn Sie also <userinput>make</userinput> eingeben wird
+ dieses sicherstellen, da&szlig; <filename>foo</filename> bzgl.
+ Ihrer letzten &Auml;nderungen an <filename>foo.c</filename>
+ auf dem neuesten Stand ist. Dieses Prinzip kann auf
+ <filename>Makefile</filename>s mit hunderten von
+ Zielen&mdash;es ist bei FreeBSD praktisch m&ouml;glich, das
+ gesamte Betriebssystem zu kompilieren, indem man nur
+ <userinput>make world</userinput> im richtigen Verzeichnis
+ eingibt!</para>
+
+ <para>Eine weitere n&uuml;tzliche Eigenschaft der makefiles
+ ist, da&szlig; die Ziele keine Programme sein m&uuml;ssen. Wir
+ k&ouml;nnten zum Beispiel eine make Datei haben, die wie folgt
+ aussieht:</para>
+
+ <programlisting>foo: foo.c
+ cc -o foo foo.c
+
+install:
+ cp foo /home/me</programlisting>
+
+ <para>Wir k&ouml;nnen make sagen welches Ziel wir erzeugt haben
+ wollen, indem wir etwas wie folgt eingeben:</para>
+
+ <screen>&prompt.user; <userinput>make <replaceable>target</replaceable></userinput></screen>
+
+ <para><command>make</command> wird dann nur dieses Ziel
+ beachten und alle anderen ignorieren. Wenn wir zum Beispiel
+ <userinput>make foo</userinput> mit dem obigen makefile
+ eingeben, dann wird make das Ziel
+ <maketarget>install</maketarget> ignorieren.</para>
+
+ <para>Wenn wir nur <userinput>make</userinput> eingeben wird
+ make immer nur nach dem ersten Ziel suchen und danach mit dem
+ Suchen aufh&ouml;ren. Wenn wir hier also nur
+ <userinput>make</userinput> eingegeben h&auml;tten, w&uuml;rde
+ es nur zu dem Ziel <maketarget>foo</maketarget> gehen,
+ gegebenenfalls <filename>foo</filename> neu kompilieren, und
+ danach einfach aufh&ouml;ren, ohne das Ziel
+ <maketarget>install</maketarget> zu beachten.</para>
+
+ <para>Beachten Sie, da&szlig; das <maketarget>install</maketarget>-Ziel
+ von nichts anderem abh&auml;ngt! Dies bedeutet, da&szlig; der
+ Befehl in der nachfolgenden Zeile immer ausgef&uuml;hrt wird,
+ wenn wir dieses Ziel mittels <userinput>make
+ install</userinput> aufrufen. In diesem Fall wird die Datei
+ <filename>foo</filename> in das Heimatverzeichnis des
+ Benutzers kopiert. Diese Vorgehensweise wird h&auml;ufig bei
+ makefiles von Anwendungen benutzt, damit die Anwendung nach
+ erfolgreicher Kompilierung in das richtige Verzeichnis
+ installiert werden kann.</para>
+
+ <para>Dieser Teil ist etwas schwierig zu erkl&auml;ren. Wenn
+ Sie immer noch nicht so richtig verstanden haben, wie
+ <command>make</command> funktioniert, w&auml;re es das Beste,
+ sie erstellen sich selber ein einfaches Programm wie
+ <quote>hello world</quote> und eine make Datei wie die weiter
+ oben angegebene, und experimentieren damit selber ein bi&szlig;chen
+ herum. Als n&auml;chstes k&ouml;nnten Sie mehrere
+ Quelltextdateien verwenden, oder in Ihrer Quelltextdatei eine
+ Header-Datei includen. Der Befehl <command>touch</command> ist
+ an dieser Stelle ganz hilfreich&mdash;er ver&auml;ndert das
+ Datum einer Datei, ohne das Sie diese extra editieren
+ m&uuml;ssen.</para>
+ </sect2>
+
+ <sect2>
+ <title>Make und include-Dateien</title>
+
+ <para>C-Code beginnt h&auml;ufig mit einer Liste von Dateien,
+ die included werden sollen, zum Beispiel stdio.h. Manche
+ dieser Dateien sind include-Dateien des Systems, andere
+ geh&ouml;ren zum aktuellen Projekt, an dem Sie gerade
+ arbeiten:</para>
+
+ <programlisting>#include &lt;stdio.h&gt;
+#include "foo.h"
+
+int main(....</programlisting>
+
+ <para>Um sicherzustellen, da&szlig; diese Datei neu kompiliert
+ wird, wenn <filename>foo.h</filename> ver&auml;ndert wurde,
+ m&uuml;ssen Sie diese Datei Ihrem
+ <filename>Makefile</filename> hinzuf&uuml;gen:</para>
+
+ <programlisting>foo: foo.c foo.h</programlisting>
+
+ <para>Sobald Ihr Projekt gr&ouml;&szlig;er wird und Sie mehr
+ und mehr eigene include-Dateien verwalten m&uuml;ssen wird es
+ nur noch sehr schwer m&ouml;glich sein, die &Uuml;bersicht
+ &uuml;ber alle include-Dateien und Dateien, die von diesen
+ abh&auml;ngen, beizubehalten. Falls Sie eine include-Datei
+ ver&auml;ndern, jedoch das erneute Kompilieren aller Dateien,
+ die von dieser Datei abh&auml;ngen, vergessen, werden die
+ Folgen verheerend sein. Der <command>gcc</command> besitzt
+ eine Option, bei der er Ihre Dateien analysiert und eine Liste
+ aller include-Dateien und deren Abh&auml;ngigkeiten erstellt:
+ <option>-MM</option>.</para>
+
+ <para>Wenn Sie das Folgende zu Ihrem Makefile
+ hinzuf&uuml;gen:</para>
+
+ <programlisting>depend:
+ gcc -E -MM *.c &gt; .depend</programlisting>
+
+ <para>und <userinput>make depend</userinput> ausf&uuml;hren,
+ wird die Datei <filename>.depend</filename> mit einer Liste
+ von Objekt-Dateien, C-Dateien und den include-Dateien
+ auftauchen:</para>
+
+ <programlisting>foo.o: foo.c foo.h</programlisting>
+
+ <para>Falls Sie <filename>foo.h</filename> ver&auml;ndern
+ werden beim n&auml;chsten Aufruf von <command>make</command>
+ alle Dateien, die von <filename>foo.h</filename>
+ abh&auml;ngen, neu kompiliert.</para>
+
+ <para>Vergessen Sie nicht jedes mal
+ <command>make depend</command> aufzurufen, wenn Sie eine
+ include-Datei zu einer Ihrer Dateien hinzugef&uuml;gt
+ haben.</para>
+ </sect2>
+
+ <sect2>
+ <title>FreeBSD Makefiles</title>
+
+ <para>Makefiles k&ouml;nnen eher schwierig zu schreiben sein.
+ Gl&uuml;cklicherweise kommen BSD-basierende Systeme wie
+ FreeBSD mit einigen sehr m&auml;chtigen solcher Dateien als
+ Teil des Systems daher. Ein sehr gutes Beispiel daf&uuml;r ist
+ das FreeBSD Portssystem. Hier ist der grundlegende Teil eines
+ typischen <filename>Makefile</filename>s des
+ Portssystems:</para>
+
+ <programlisting>MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
+DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz
+
+.include &lt;bsd.port.mk&gt;</programlisting>
+
+ <para>Wenn wir jetzt in das Verzeichnis dieses Ports wechseln
+ und <userinput>make</userinput> aufrufen, passiert das
+ Folgende:</para>
+
+ <procedure>
+ <step>
+ <para>Es wird &uuml;berpr&uuml;ft, ob sich der Quelltext
+ f&uuml;r diesen Port bereits auf Ihrem System
+ befindet.</para>
+ </step>
+
+ <step>
+ <para>Falls dies nicht der Fall ist wird eine
+ FTP-Verbindung zu der URL in <symbol>MASTER_SITES</symbol>
+ aufgebaut und der Quelltext heruntergeladen.</para>
+ </step>
+
+ <step>
+ <para>Die Checksumme f&uuml;r den Quelltext wird berechnet
+ und mit der schon bekannten und f&uuml;r sicher und gut
+ empfundenen verglichen. Damit wird sichergestellt,
+ da&szlig; der Quelltext bei der &Uuml;bertragung nicht
+ besch&auml;digt wurde.</para>
+ </step>
+
+ <step>
+ <para>S&auml;mtliche Anpassungen, die n&ouml;tig sind,
+ damit der Quelltext unter FreeBSD funktioniert, werden
+ vorgenommen&mdash;dieser Vorgang wird auch
+ <firstterm>patchen</firstterm> genannt.</para>
+ </step>
+
+ <step>
+ <para>Alle speziellen Konfigurationen, die am Quelltext
+ n&ouml;tig sind, werden vorgenommen. (Viele &unix;
+ Programmdistributionen versuchen herauszufinden, auf
+ welcher &unix;-Version sie kompiliert werden sollen und
+ welche optionalen &unix;-Features vorhanden sind&mdash;an
+ dieser Stelle erhalten sie die Informationen im FreeBSD
+ Ports Szenario).</para>
+ </step>
+
+ <step>
+ <para>Der Quelltext f&uuml;r das Programm wird kompiliert.
+ Im Endeffekt wechseln wir in das Verzeichnis, in das der
+ Quelltext entpackt wurde, und rufen
+ <command>make</command> auf&mdash;die eigene make-Datei
+ des Programms besitzt die n&ouml;tigen Informationen um
+ dieses zu bauen.</para>
+ </step>
+
+ <step>
+ <para>Wir haben jetzt eine kompilierte Version des
+ Programmes. Wenn wir wollen k&ouml;nnen wir dieses jetzt
+ testen; wenn wir &uuml;berzeugt vom Programm sind,
+ k&ouml;nnen wir <userinput>make install</userinput>
+ eingeben. Dadurch werden das Programm sowie alle
+ zugeh&ouml;rigen Dateien an die richtige Stelle kopiert;
+ es wird auch ein Eintrag in der
+ <database>Paketdatenbank</database> erzeugt, soda&szlig;
+ der Port sehr einfach wieder deinstalliert werden kann,
+ falls wir unsere Meinung &uuml;ber dieses ge&auml;ndert
+ haben.</para>
+ </step>
+ </procedure>
+
+ <para>Ich glaube jetzt werden Sie mit mir &uuml;bereinstimmen,
+ da&szlig; dies ziemlich eindrucksvoll f&uuml;r ein Skript mit
+ vier Zeilen ist!</para>
+
+ <para>Das Geheimnis liegt in der letzten Zeile, die
+ <command>make</command> anweist, in das makefile des Systems
+ mit dem Namen <filename>bsd.port.mk</filename> zu sehen. Man
+ kann diese Zeile zwar leicht &uuml;bersehen, aber hierher
+ kommt all das klevere Zeugs&mdash;jemand hat ein makefile
+ geschrieben, welches <command>make</command> anweist, alle
+ weiter oben beschriebenen Schritte durchzuf&uuml;hren (neben
+ vielen weiteren Dingen, die ich nicht angesprochen habe,
+ einschlie&szlig;lich der Behandlung s&auml;mtlicher Fehler,
+ die auftreten k&ouml;nnten) und jeder kann darauf
+ zur&uuml;ckgreifen, indem er eine einzige Zeile in seine
+ eigene make-Datei einf&uuml;gt!</para>
+
+ <para>Falls Sie einen Blick in die makefiles des Systems werfen
+ m&ouml;chten, finden Sie diese in
+ <filename>/usr/share/mk</filename>. Es ist aber wahrscheinlich
+ besser, wenn Sie damit noch warten, bis Sie ein bi&szlig;chen 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!)</para>
+ </sect2>
+
+ <sect2>
+ <title>Fortgeschrittene Verwendung von
+ <command>make</command></title>
+
+ <para><command>Make</command> ist ein sehr m&auml;chtiges
+ Werkzeug und kann noch sehr viel mehr als die gezeigten
+ einfachen Beispiele weiter oben. Bedauerlicherweise gibt es
+ mehrere verschiedene Versionen von <command>make</command>,
+ und sie alle unterscheiden sich betr&auml;chtlich voneinander.
+ Der beste Weg herauszufinden was sie k&ouml;nnen ist
+ wahrscheinlich deren Dokumentation zu lesen&mdash;hoffentlich
+ hat diese Einf&uuml;hrung Ihnen gen&uuml;gend Grundkenntnisse
+ vermitteln k&ouml;nnen, damit Sie dies tun k&ouml;nnen.</para>
+
+ <para>Die Version von make, die in FreeBSD enthalten ist, ist
+ <application>Berkeley make</application>; es gibt eine
+ Anleitung dazu in
+ <filename>/usr/share/doc/psd/12.make</filename>. Um sich diese
+ anzusehen, m&uuml;ssen Sie</para>
+
+ <screen>&prompt.user; <userinput>zmore paper.ascii.gz</userinput></screen>
+
+ <para>in diesem Verzeichnis ausf&uuml;hren.</para>
+
+ <para>Viele Anwendungen in den Ports verwenden
+ <application>GNU make</application>, welches einen sehr guten
+ Satz an <quote>info</quote>-Seiten mitbringt. Falls Sie
+ irgendeinen dieser Ports installiert haben wurde
+ <application>GNU make</application> automatisch als
+ <command>gmake</command> mit installiert. Es ist auch als
+ eigenst&auml;ndiger Port und Paket verf&uuml;gbar.</para>
+
+ <para>Um sich die Info-Seiten f&uuml;r
+ <application>GNU make</application> anzusehen m&uuml;ssen Sie
+ die Datei <filename>dir</filename> in
+ <filename>/usr/local/info</filename> um einen entsprechenden
+ Eintrag erweitern. Dies beinhaltet das Einf&uuml;gen einer
+ Zeile wie</para>
+
+ <programlisting> * Make: (make). The GNU Make utility.</programlisting>
+
+ <para>in die Datei. Nachdem Sie dies getan haben k&ouml;nnen
+ Sie <userinput>info</userinput> eingeben und dann den
+ Men&uuml;eintrag <guimenuitem>make</guimenuitem>
+ ausw&auml;hlen (oder Sie k&ouml;nnen in
+ <application>Emacs</application> die Tastenkombination
+ <userinput>C-h i</userinput> verwenden).</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="debugging">
+ <title>Debuggen</title>
+
+ <sect2>
+ <title>Der Debugger</title>
+
+ <para>Der Debugger bei FreeBSD hei&szlig;t
+ <command>gdb</command> (<application>GNU
+ debugger</application>). Sie k&ouml;nnen Ihn durch die Eingabe
+ von</para>
+
+ <screen>&prompt.user; <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
+
+ <para>starten, wobei viele Leute ihn vorzugsweise
+ innerhalb von <application>Emacs</application> aufrufen. Sie
+ erreichen dies durch die Eingabe von:</para>
+
+ <screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen>
+
+ <para>Die Verwendung eines Debuggers erlaubt Ihnen Ihr
+ Programm unter kontrollierteren Bedingungen ausf&uuml;hren zu
+ k&ouml;nnen. Typischerweise k&ouml;nnen Sie so Zeile f&uuml;r
+ Zeile durch Ihr Programm gehen, die Werte von Variablen
+ untersuchen, diese ver&auml;ndern, dem Debugger sagen er soll
+ das Programm bis zu einem bestimmten Punkt ausf&uuml;hren und
+ dann anhalten, und so weiter und so fort. Sie k&ouml;nnen
+ damit sogar ein schon laufendes Programm untersuchen, oder
+ eine Datei mit einem Kernspeicherabbild laden um
+ herauszufinden, warum das Programm abgest&uuml;rzt ist. Es ist
+ sogar m&ouml;glich damit den Kernel zu debuggen, wobei dies
+ etwas trickreicher als bei den Benutzeranwendungen ist, welche
+ wir in diesem Abschnitt behandeln werden.</para>
+
+ <para>Der <command>gdb</command> besitzt eine recht gute
+ Online-Hilfe, sowie einen Satz von Info-Seiten, weshalb sich
+ dieser Abschnitt auf ein paar grundlegende Befehle
+ beschr&auml;nken wird.</para>
+
+ <para>Falls Sie den textbasierten Kommandozeilen-Stil
+ absto&szlig;end finden gibt es ein graphisches Front-End
+ daf&uuml;r (<filename
+ role="package">devel/xxgdb</filename>) in der Ports-Sammlung.</para>
+
+ <para>Dieser Abschnitt ist als Einf&uuml;hrung in die
+ Verwendung des <command>gdb</command> gedacht und beinhaltet
+ nicht spezielle Themen wie das Debuggen des Kernels.</para>
+ </sect2>
+
+ <sect2>
+ <title>Ein Programm im Debugger ausf&uuml;hren</title>
+
+ <para>Sie m&uuml;ssen das Programm mit der Option
+ <option>-g</option> kompiliert haben um den
+ <command>gdb</command> effektiv einsetzen zu k&ouml;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&ouml;rigen Quelltext. Falls Sie eine
+ Meldung wie die folgende sehen:</para>
+
+ <screen>&hellip; (no debugging symbols found) &hellip;</screen>
+
+ <para>wenn der <command>gdb</command> gestartet wird, dann
+ wissen Sie, da&szlig; das Programm nicht mit der Option
+ <option>-g</option> kompiliert wurde.</para>
+
+ <para>Geben Sie in der Eingabeaufforderung des
+ <command>gdb</command> <userinput>break main</userinput> ein.
+ Dies weist den Debugger an, dass Sie nicht daran interessiert sind,
+ den einleitenden Schritten beim Programmstart zuzusehen und dass
+ am Anfang Ihres Codes die Ausf&uuml;hrung beginnen soll. Geben Sie
+ nun <userinput>run</userinput> ein, um das Programm zu starten -
+ es wird starten und beim Aufruf von <function>main()</function> vom
+ Debugger angehalten werden. (Falls Sie sich jemals gewundert haben von
+ welcher Stelle <function>main()</function> aufgerufen wird, dann
+ wissen Sie es jetzt!).</para>
+
+ <para>Sie k&ouml;nnen nun Schritt f&uuml;r Schritt durch Ihr
+ Programm gehen, indem Sie <command>n</command> dr&uuml;cken.
+ Wenn Sie zu einem Funktionsaufruf kommen k&ouml;nnen Sie diese
+ Funktion durch dr&uuml;cken von <command>s</command> betreten.
+ Sobald Sie sich in einem Funktionsaufruf befinden k&ouml;nnen
+ Sie diesen durch dr&uuml;cken von <command>f</command> wieder
+ verlassen. Sie k&ouml;nnen auch <command>up</command> und
+ <command>down</command> verwenden, um sich schnell den
+ Aufrufer einer Funktion anzusehen.</para>
+
+ <para>Hier ist ein einfaches Beispiel, wie man mit Hilfe des
+ <command>gdb</command> einen Fehler in einem Programm findet.
+ Dies ist unser eigenes Programm (mit einem absichtlich
+ eingebauten Fehler):</para>
+
+ <programlisting>#include &lt;stdio.h&gt;
+
+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;
+}</programlisting>
+
+ <para>Dieses Programm setzt <symbol>i</symbol> auf den Wert
+ <literal>5</literal> und &uuml;bergibt dies einer Funktion
+ <function>bazz()</function>, welche den Wert ausgibt, den Sie
+ von uns erhalten hat.</para>
+
+ <para>Wenn wir das Programm kompilieren und ausf&uuml;hren
+ erhalten wir</para>
+
+ <screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
+&prompt.user; <userinput>./temp</userinput>
+This is my program
+anint = 4231</screen>
+
+ <para>Das ist nicht was wir erwartet hatten! Es ist Zeit,
+ da&szlig; wir sehen was hier passiert!</para>
+
+ <screen>&prompt.user; <userinput>gdb temp</userinput>
+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) <userinput>break main</userinput> <lineannotation>Skip the set-up code</lineannotation>
+Breakpoint 1 at 0x160f: file temp.c, line 9. <lineannotation><command>gdb</command> puts breakpoint at <function>main()</function></lineannotation>
+(gdb) <userinput>run</userinput> <lineannotation>Run as far as <function>main()</function></lineannotation>
+Starting program: /home/james/tmp/temp <lineannotation>Program starts running</lineannotation>
+
+Breakpoint 1, main () at temp.c:9 <lineannotation><command>gdb</command> stops at <function>main()</function></lineannotation>
+(gdb) <userinput>n</userinput> <lineannotation>Go to next line</lineannotation>
+This is my program <lineannotation>Program prints out</lineannotation>
+(gdb) <userinput>s</userinput> <lineannotation>step into <function>bazz()</function></lineannotation>
+bazz (anint=4231) at temp.c:17 <lineannotation><command>gdb</command> displays stack frame</lineannotation>
+(gdb)</screen>
+
+ <para>Halt mal! Wieso hat denn <symbol>anint</symbol> den Wert
+ <literal>4231</literal>? Haben wir dieser Variablen nicht in
+ <function>main()</function> den Wert <literal>5</literal>
+ zugewiesen? Gehen wir mal zur&uuml;ck zu
+ <function>main()</function> und schauen dort nach.</para>
+
+ <screen>(gdb) <userinput>up</userinput> <lineannotation>Move up call stack</lineannotation>
+#1 0x1625 in main () at temp.c:11 <lineannotation><command>gdb</command> displays stack frame</lineannotation>
+(gdb) <userinput>p i</userinput> <lineannotation>Show us the value of <symbol>i</symbol></lineannotation>
+$1 = 4231 <lineannotation><command>gdb</command> displays <literal>4231</literal></lineannotation></screen>
+
+ <para>Oh! Anscheinend haben wir vergessen <symbol>i</symbol> zu
+ initialisieren. Wir wollten eigentlich</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
+main() {
+ int i;
+
+ i = 5;
+ printf("This is my program\n");
+<lineannotation>&hellip;</lineannotation></programlisting>
+
+ <para>schreiben, haben aber die Zeile mit
+ <literal>i=5;</literal> vergessen. Da wir <symbol>i</symbol>
+ 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
+ <literal>4231</literal> war.</para>
+
+ <note>
+ <para>Der <command>gdb</command> zeigt jedes mal, wenn wir
+ eine Funktion betreten oder verlassen, den Inhalt des
+ Stack-Rahmens an, selbst wenn wir uns mit
+ <command>up</command> und <command>down</command> im
+ Aufruf-Stack umher bewegen. Dabei wird der Name der Funktion
+ sowie der &uuml;bergebenen Argumente angezeigt, was uns
+ dabei hilft, die &Uuml;bersicht zu behalten. (Der Stack ist
+ ein Speicherbereich, in dem ein Programm Informationen
+ &uuml;ber die an eine Funktion &uuml;bergebenen Argumente
+ ablegt, sowie die R&uuml;cksprungadresse eines
+ Funktionsaufrufes).</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Eine Kernspeicherdatei untersuchen</title>
+
+ <para>Eine Kernspeicherdatei ist im Prinzip eine Datei, die den
+ vollst&auml;ndigen Zustand eines Prozesses enth&auml;lt, als
+ dieses abgest&uuml;rzt ist. In <quote>den guten alten
+ Zeiten</quote> mu&szlig;ten Programmierer hexadezimale Listen
+ der Kernspeicherdatei ausdrucken und &uuml;ber
+ Maschinencodehandb&uuml;chern schwitzen, aber heutzutage ist
+ das Leben etwas einfacher geworden. Zuf&auml;lligerweise wird
+ die Kernspeicherdatei unter FreeBSD und anderen
+ 4.4BSD-Systemen
+ <filename><replaceable>progname</replaceable>.core</filename>
+ anstatt einfach nur <filename>core</filename> genannt, um
+ deutlich zu machen, zu welchem Programm eine Kernspeicherdatei
+ geh&ouml;rt.</para>
+
+ <para>Um eine Kernspeicherdatei zu untersuchen m&uuml;ssen Sie
+ den <command>gdb</command> wie gewohnt starten. An Stelle von
+ <command>break</command> oder <command>run</command>
+ m&uuml;ssen Sie das Folgende eingeben</para>
+
+ <screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
+
+ <para>Wenn Sie sich nicht in demselben Verzeichnis befinden wie
+ die Kernspeicherdatei m&uuml;ssen Sie zuerst <userinput>dir
+ /path/to/core/file</userinput> eingeben.</para>
+
+ <para>Sie sollten dann etwas wie folgt sehen:</para>
+
+ <screen>&prompt.user; <userinput>gdb a.out</userinput>
+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) <userinput>core a.out.core</userinput>
+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)</screen>
+
+ <para>In diesem Fall hie&szlig; das Programm
+ <filename>a.out</filename>, weshalb die Kernspeicherdatei den
+ Namen <filename>a.out.core</filename> tr&auml;gt. Wie wir
+ sehen k&ouml;nnen st&uuml;rzte das Programm in einer Funktion
+ namens <function>bazz</function> ab, als es versuchte auf
+ einen Speicherbereich zuzugreifen, der dem Programm nicht zur
+ Verf&uuml;gung stand.</para>
+
+ <para>Manchmal ist es ganz n&uuml;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&ouml;nnte. Der Befehl
+ <command>bt</command> veranla&szlig;t den
+ <command>gdb</command> dazu, einen Backtrace des Aufruf-Stacks
+ auszugeben:</para>
+
+ <screen>(gdb) <userinput>bt</userinput>
+#0 0x164a in bazz (anint=0x5) at temp.c:17
+#1 0xefbfd888 in end ()
+#2 0x162c in main () at temp.c:11
+(gdb)</screen>
+
+ <para>Die Funktion <function>end()</function> wird aufgerufen,
+ wenn ein Programm abst&uuml;rzt; in diesem Fall wurde die
+ Funktion <function>bazz()</function> aus der
+ <function>main()</function>-Funktion heraus aufgerufen.</para>
+ </sect2>
+
+ <sect2>
+ <title>Ein bereits laufendes Programm untersuchen</title>
+
+ <para>Eine der tollsten Features des <command>gdb</command>
+ ist die M&ouml;glichkeit, damit bereits laufende Programme zu
+ untersuchen. Dies bedeutet nat&uuml;rlich, da&szlig; Sie die
+ erforderlichen Rechte daf&uuml;r besitzen. Ein h&auml;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.</para>
+
+ <para>Was Sie an solch einer Stelle machen ist, Sie starten
+ einen weiteren <command>gdb</command>, ermitteln mit Hilfe von
+ <command>ps</command> die Prozess-ID des Kindprozesses, und
+ geben</para>
+
+ <screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
+
+ <para>im <command>gdb</command> ein, und k&ouml;nnen dann wie
+ &uuml;blich mit der Fehlersuche fortfahren.</para>
+
+ <para><quote>Das ist zwar alles sehr sch&ouml;n,</quote> werden
+ Sie jetzt vielleicht denken, <quote>aber in der Zeit, in der
+ ich diese Schritte durchf&uuml;hre, ist der Kindprozess schon
+ l&auml;ngst &uuml;ber alle Berge</quote>. F&uuml;rchtet euch
+ nicht, edler Leser, denn Ihr m&uuml;&szlig;t wie folgt
+ vorgehen (freundlicherweise zur Verf&uuml;gung gestellt von
+ den Info-Seite des <command>gdb</command>):</para>
+
+ <screen><lineannotation>&hellip;</lineannotation>
+if ((pid = fork()) &lt; 0) /* _Always_ check this */
+ error();
+else if (pid == 0) { /* child */
+ int PauseMode = 1;
+
+ while (PauseMode)
+ sleep(10); /* Wait until someone attaches to us */
+ <lineannotation>&hellip;</lineannotation>
+} else { /* parent */
+ <lineannotation>&hellip;</lineannotation></screen>
+
+ <para>Alles was Sie jetzt noch tun m&uuml;ssen ist, sich an
+ den Kindprozess ranzuh&auml;ngen, <symbol>PauseMode</symbol>
+ auf <literal>0</literal> zu setzen und auf den
+ <function>sleep()</function> Funktionsaufruf zu warten, um
+ zur&uuml;ckzukehren!</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="emacs">
+ <title>Emacs als Entwicklungsumgebung verwenden</title>
+
+ <sect2>
+ <title>Emacs</title>
+
+ <para>Leider 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.
+
+ <footnote>
+ <para>Es gibt jetzt einige m&auml;chtige und freie IDEs in
+ der Ports-Sammlung wie etwa KDevelop.</para>
+ </footnote>
+
+ Trotzdem ist es m&ouml;glich, seine eigene
+ Entwicklungsumgebung aufzusetzen. Diese wird vielleicht nicht
+ so h&uuml;bsch und integriert sein, aber daf&uuml;r
+ k&ouml;nnen Sie sie Ihren eigenen W&uuml;nschen anpassen. Und
+ sie ist frei. Und Sie haben die Quelltexte davon.</para>
+
+ <para>Der Schl&uuml;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&ouml;ren bef&uuml;rchte ich,
+ da&szlig; dieser Abschnitt Ihnen wenig interessantes zu bieten
+ hat. Des weiteren ben&ouml;tigen Sie eine angemessene Menge an
+ freiem Speicher, um ihn zu benutzen&mdash;ich w&uuml;rde 8MB
+ f&uuml;r den Textmodus und 16MB unter X als absolutes Minimum
+ empfehlen, um eine halbwegs brauchbare Performance zu
+ erhalten.</para>
+
+ <para>Emacs ist im Prinzip ein extrem anpassbarer Editor&mdash;
+ in der Tat ist er so stark ver&auml;nderbar, da&szlig; 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.</para>
+
+ <para>Es ist nicht einmal m&ouml;glich alles hier
+ zusammenzufassen, was man mit dem Emacs machen kann. Im
+ Folgenden werden einige Features aufgelistet, die f&uuml;r
+ einen Entwickler interessant sein k&ouml;nnten:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Sehr m&auml;chtiger Editor, der suchen-und-ersetzen
+ mit Zeichenfolgen und regul&auml;ren Ausdr&uuml;cken
+ (Pattern) sowie das direkte Anspringen von Anfang/Ende von
+ Blockausdr&uuml;cken erlaubt, etc, etc.</para>
+ </listitem>
+
+ <listitem>
+ <para>Pull-Down Men&uuml;s und eine Online-Hilfe.</para>
+ </listitem>
+
+ <listitem>
+ <para>Sprachunabh&auml;ngige Syntaxhervorhebung und
+ automatische Einr&uuml;ckung.</para>
+ </listitem>
+
+ <listitem>
+ <para>Vollst&auml;ndig konfigurierbar.</para>
+ </listitem>
+
+ <listitem>
+ <para>Sie k&ouml;nnen Programme im Emacs kompilieren und
+ debuggen.</para>
+ </listitem>
+
+ <listitem>
+ <para>Bei Kompilationsfehlern k&ouml;nnen Sie direkt zu der
+ entsprechenden Zeile im Quelltext springen.</para>
+ </listitem>
+
+ <listitem>
+ <para>Benutzerfreundliches Front-End f&uuml;r das
+ <command>info</command>-Programm, um die GNU Hypertext
+ Dokumentation inklusive der Dokumentation des Emacs
+ selber.</para>
+ </listitem>
+
+ <listitem>
+ <para>Benutzerfreundliches Front-End f&uuml;r den
+ <command>gdb</command> um sich beim Verfolgen der
+ Programmanweisungen den zugeh&ouml;rigen Quelltext
+ anzeigen zu lassen.</para>
+ </listitem>
+
+ <listitem>
+ <para>Sie k&ouml;nnen E-Mails und News im Usenet lesen,
+ w&auml;hrend ihr Programm kompiliert wird.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Und zweifelsfrei viele weitere Punkte, die ich
+ &uuml;bersehen habe.</para>
+
+ <para>Emacs kann unter &os; &uuml;ber den <filename
+ role="package">editors/emacs</filename> Port installiert werden.</para>
+
+ <para>Sobald er installiert ist starten Sie ihn, und geben
+ dann <userinput>C-h t</userinput> ein, um die Einf&uuml;hrung
+ in Emacs zu lesen&mdash;d.h. Sie sollen bei gedr&uuml;ckter
+ <keycap>Strg</keycap>-Taste die <keycap>h</keycap>-Taste
+ dr&uuml;cken, beide wieder loslassen und anschlie&szlig;end
+ <keycap>t</keycap> dr&uuml;cken. (Alternativ k&ouml;nnen Sie
+ mit der Maus den Eintrag <guimenuitem>Emacs
+ Tutorial</guimenuitem> aus dem
+ <guimenu>Hilfe</guimenu>-Men&uuml; ausw&auml;hlen).</para>
+
+ <para>Obwohl der Emacs Men&uuml;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, da&szlig; diese
+ h&auml;ufig nebenbei Ausdr&uuml;cke wie <quote><literal>M-x
+ replace-s RET foo RET bar RET</literal></quote> verwenden,
+ weshalb das Erlernen dieser sehr n&uuml;tzlich ist. Und Emacs
+ hat auf jeden Fall weit mehr n&uuml;tzliche Funktionen als das
+ diese in der Men&uuml;leiste unterzubringen w&auml;ren.</para>
+
+ <para>Zum Gl&uuml;ck ist es sehr einfach die jeweiligen
+ Tastaturkombinationen herauszubekommen, da diese direkt neben
+ den Men&uuml;eintr&auml;gen stehen. Meine Empfehlung
+ w&auml;re, den Men&uuml;eintrag f&uuml;r, sagen wir, das
+ &Ouml;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&auml;chsten
+ Men&uuml;eintrag.</para>
+
+ <para>Falls Sie sich nicht daran erinnern k&ouml;nnen, was eine
+ bestimmte Tastenkombination macht, w&auml;hlen Sie
+ <guimenuitem>Describe Key</guimenuitem> aus dem
+ <guimenu>Hilfe</guimenu>-Men&uuml; aus und geben Sie die
+ Tastenkombination ein&mdash;Emacs sagt Ihnen dann was diese
+ macht. Sie k&ouml;nnen ebenfalls den Men&uuml;eintrag
+ <guimenuitem>Command Apropos</guimenuitem> verwenden, um alle
+ Befehle, die ein bestimmtes Wort enthalten, mit den
+ zugeh&ouml;rigen Tastenkombinationen aufgelistet zu
+ bekommen.</para>
+
+ <para>&Uuml;brigends bedeutet der Ausdruck weiter oben, bei
+ gedr&uuml;ckter <keysym>Meta</keysym>-Taste <keysym>x</keysym>
+ zu dr&uuml;cken, beide wieder loszulassen,
+ <userinput>replace-s</userinput> einzugeben (Kurzversion
+ f&uuml;r <literal>replace-string</literal>&mdash;ein weiteres
+ Feature des Emacs ist, da&szlig; Sie Befehle abk&uuml;rzen
+ k&ouml;nnen), anschlie&szlig;end die
+ <keysym>return</keysym>-Taste zu dr&uuml;cken, dann
+ <userinput>foo</userinput> einzugeben (die Zeichenkette, die
+ Sie ersetzen m&ouml;chten), dann wieder
+ <keysym>return</keysym>, dann die Leertaste zu dr&uuml;cken
+ (die Zeichenkette, mit der Sie <literal>foo</literal> ersetzen
+ m&ouml;chten) und anschlie&szlig;end erneut
+ <keysym>return</keysym> zu dr&uuml;cken. Emacs wird dann die
+ gew&uuml;nschte suchen-und-ersetzen-Operation
+ ausf&uuml;hren.</para>
+
+ <para>Wenn Sie sich fragen was in aller Welt die
+ <keysym>Meta</keysym>-Taste ist, das ist eine spezielle Taste
+ die viele &unix;-Workstations besitzen. Bedauerlicherweise
+ haben PCs keine solche Taste, und daher ist es
+ &uuml;blicherweise die <keycap>alt</keycap>-Taste (oder falls
+ Sie Pech haben die <keycap>Esc</keycap>-Taste).</para>
+
+ <para>Oh, und um den Emacs zu verlassen m&uuml;ssen sie
+ <command>C-x C-c</command> (das bedeutet, Sie m&uuml;ssen bei
+ gedr&uuml;ckter <keysym>Strg</keysym>-Taste zuerst
+ <keysym>x</keysym> und dann <keysym>c</keysym> dr&uuml;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, da&szlig; <command>C-z</command> der
+ &uuml;bliche Weg ist, Emacs zu verlassen&mdash;dadurch wird
+ der Emacs in den Hintergrund geschaltet, was nur n&uuml;tzlich
+ ist, wenn Sie an einem System ohne virtuelle Terminals
+ arbeiten).</para>
+ </sect2>
+
+ <sect2>
+ <title>Emacs konfigurieren</title>
+
+ <para>Emacs kann viele wundervolle Dinge; manche dieser Dinge
+ sind schon eingebaut, andere m&uuml;ssen erst konfiguriert
+ werden.</para>
+
+ <para>Anstelle einer propriet&auml;ren Macrosprache verwendet
+ der Emacs f&uuml;r die Konfiguration eine speziell f&uuml;r
+ Editoren angepa&szlig;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&ouml;chten. Emacs Lisp hat viele Features von Common Lisp
+ obwohl es betr&auml;chtlich kleiner ist (und daher auch
+ einfacher zu beherrschen).</para>
+
+ <para>Der beste Weg um Emacs Lisp zu erlernen besteht darin,
+ sich das <ulink
+ url="ftp://ftp.gnu.org/old-gnu/emacs/elisp-manual-19-2.4.tar.gz">Emacs
+ Tutorial</ulink> herunterzuladen.</para>
+
+ <para>Es ist jedoch keine Kenntnis von Lisp erforderlich, um
+ mit der Konfiguration von Emacs zu beginnen, da ich eine
+ beispielhafte <filename>.emacs</filename>-Datei hier
+ eingef&uuml;gt habe, die f&uuml;r den Anfang ausreichen
+ sollte. Kopieren Sie diese einfach in Ihr Heimverzeichnis und
+ starten Sie den Emacs neu, falls dieser bereits l&auml;uft; er
+ wird die Befehle aus der Datei lesen und Ihnen (hoffentlich)
+ eine brauchbare Grundeinstellung bieten.</para>
+ </sect2>
+
+ <sect2>
+ <title>Eine beispielhafte <filename>.emacs</filename>-Datei</title>
+
+ <para>Bedauerlicherweise gibt es hier viel zu viel, um es im
+ Detail zu erkl&auml;ren; es gibt jedoch ein oder zwei Punkte,
+ die besonders erw&auml;hnenswert sind.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Alles was mit einem <literal>;</literal> anf&auml;ngt
+ ist ein Kommentar und wird von Emacs ignoriert.</para>
+ </listitem>
+
+ <listitem>
+ <para>In der ersten Zeile mit
+ <literal>-*-&nbsp;Emacs-Lisp&nbsp;-*-</literal> sorgt
+ daf&uuml;r, da&szlig; wir die Datei
+ <filename>.emacs</filename> in Emacs selber editieren
+ k&ouml;nnen und uns damit alle tollen Features zum
+ Editieren von Emacs Lisp zur Verf&uuml;gung stehen. Emacs
+ versucht dies normalerweise anhand des Dateinamens
+ auszumachen, was vielleicht bei
+ <filename>.emacs</filename> nicht funktionieren
+ k&ouml;nnte.</para>
+ </listitem>
+
+ <listitem>
+ <para>Die <keysym>Tab</keysym>-Taste ist in manchen Modi
+ an die Einr&uuml;ckungsfunktion gebunden, so da&szlig;
+ beim dr&uuml;cken dieser Taste die aktuelle Zeile
+ einger&uuml;ckt wird. Wenn Sie ein
+ <token>tab</token>-Zeichen in einen Text, welchen auch
+ immer Sie dabei schreiben, einf&uuml;gen wollen,
+ m&uuml;ssen Sie bei gedr&uuml;ckter
+ <keysym>Strg</keysym>-Taste die <keysym>Tab</keysym>-Taste
+ dr&uuml;cken.</para>
+ </listitem>
+
+ <listitem>
+ <para>Diese Datei unterst&uuml;tzt Syntax Highlighting
+ f&uuml;r C, C++, Perl, Lisp und Scheme, indem die Sprache
+ anhand des Dateinamens erraten wird.</para>
+ </listitem>
+
+ <listitem>
+ <para>Emacs hat bereits eine vordefinierte Funktion mit dem
+ Namen <function>next-error</function>. Diese erlaubt es
+ einem, in einem Fenster mit der Kompilierungsausgabe
+ mittels <command>M-n</command> von einem zum n&auml;chsten
+ Kompilierungsfehler zu springen; wir definieren eine
+ komplement&auml;re Funktion
+ <function>previous-error</function>, die es uns erlaubt,
+ mittels <command>M-p</command> von einem zum vorherigen
+ Kompilierungsfehler zu springen. Das sch&ouml;nste Feature
+ von allen ist, da&szlig; mittels <command>C-c
+ C-c</command> die Quelltextdatei, in der der Fehler
+ aufgetreten ist, ge&ouml;ffnet und die betreffende Zeile
+ direkt angesprungen wird.</para>
+ </listitem>
+
+ <listitem>
+ <para>Wir aktivieren die M&ouml;glichkeit von Emacs als
+ Server zu agieren, so da&szlig; wenn Sie etwas
+ au&szlig;erhalb von Emacs machen und eine Datei editieren
+ m&ouml;chten, Sie einfach das folgende eingeben
+ k&ouml;nnen</para>
+
+ <screen>&prompt.user; <userinput>emacsclient <replaceable>filename</replaceable></userinput>
+ </screen>
+
+ <para>und dann die Datei in Ihrem Emacs editieren
+ k&ouml;nnen!
+
+ <footnote>
+ <para>Viele Emacs-Benutzer setzen Ihre
+ <envar>EDITOR</envar>-Umgebungsvariable auf
+ <literal>emacsclient</literal>, so da&szlig; dies
+ immer passiert, wenn sie eine Datei editieren
+ m&uuml;ssen.</para>
+ </footnote>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <example>
+ <title>Eine einfache <filename>.emacs</filename>-Datei</title>
+
+ <programlisting>;; -*-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-&lt;")
+(global-set-key [C-end] "\M-&gt;")
+(global-set-key [C-prior] "\M-&lt;")
+(global-set-key [C-next] "\M-&gt;")
+
+;; 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 &lt;CR&gt; 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 (&gt;= 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 &amp;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) ".")
+ </programlisting>
+ </example>
+ </sect2>
+
+ <sect2>
+ <title>Erweitern des von Emacs unterst&uuml;tzten Sprachbereichs</title>
+
+ <para>Das ist jetzt alles sehr sch&ouml;n wenn Sie
+ ausschlie&szlig;lich in einer der Sprachen programmieren
+ wollen, um die wir uns bereits in der
+ <filename>.emacs</filename>-Datei gek&uuml;mmert haben (C,
+ C++, Perl, Lisp und Scheme), aber was passiert wenn eine neue
+ Sprache namens <quote>whizbang</quote> herauskommt, mit jeder
+ Menge neuen tollen Features?</para>
+
+ <para>Als erstes mu&szlig; festgestellt werden, ob whizbang mit
+ irgendwelchen Dateien daherkommt, die Emacs etwas &uuml;ber
+ die Sprache sagen. Diese enden &uuml;blicherweise auf
+ <filename>.el</filename>, der Kurzform f&uuml;r <quote>Emacs
+ Lisp</quote>. Falls whizbang zum Beispiel ein FreeBSD Port
+ ist, k&ouml;nnten wir diese Dateien mittels</para>
+
+ <screen>&prompt.user; <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
+
+ <para>finden und durch Kopieren in das Emacs-seitige
+ Lisp-Verzeichnis installieren. Unter &os; ist dies
+ <filename>/usr/local/share/emacs/site-lisp</filename>.</para>
+
+ <para>Wenn zum Beispiel die Ausgabe des find-Befehls wie folgt
+ war</para>
+
+ <screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
+
+ <para>k&ouml;nnten wir das folgende tun</para>
+
+ <screen>&prompt.root; <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
+
+ <para>Als n&auml;chstes m&uuml;ssen wir festlegen, welche
+ Dateiendung Quelltextdateien f&uuml;r whizbang haben. Lassen
+ Sie uns um der Argumente Willen annehmen, die Dateiendung sei
+ <filename>.wiz</filename>. Wir m&uuml;ssen dann einen Eintrag
+ unserer <filename>.emacs</filename>-Datei hinzuf&uuml;gen um
+ sicherzustellen, da&szlig; Emacs die Informationen in
+ <filename>whizbang.el</filename> auch verwenden kann.</para>
+
+ <para>Suchen Sie den <symbol>auto-mode-alist Eintrag</symbol>
+ in der <filename>.emacs</filename>-Datei und f&uuml;gen Sie an
+ dieser Stelle eine Zeile wie folgt f&uuml;r whizbang
+ hinzu:</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
+("\\.lsp$" . lisp-mode)
+("\\.wiz$" . whizbang-mode)
+("\\.scm$" . scheme-mode)
+<lineannotation>&hellip;</lineannotation></programlisting>
+
+ <para>Dies bedeutet das Emacs automatisch in den
+ <function>whizbang-mode</function> wechseln wird, wenn Sie
+ eine Datei mit der Dateiendung <filename>.wiz</filename>
+ editieren.</para>
+
+ <para>Direkt darunter werden Sie den Eintrag
+ <symbol>font-lock-auto-mode-list</symbol> finden. Erweitern
+ Sie den <function>whizbang-mode</function> um diesen wie
+ folgt:</para>
+
+ <programlisting>;; 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")</programlisting>
+
+ <para>Dies bedeutet das Emacs immer
+ <function>font-lock-mode</function> (z.B. Syntax Highlighting)
+ aktiviert, wenn Sie eine <filename>.wiz</filename>-Datei
+ editieren.</para>
+
+ <para>Und das ist alles was ben&ouml;tigt wird. Falls es
+ weitere Dinge gibt, die automatisch beim &Ouml;ffnen einer
+ <filename>.wiz</filename>-Datei ausgef&uuml;hrt werden sollen,
+ k&ouml;nnen Sie einen <function>whizbang-mode
+ hook</function>-Eintrag hinzuf&uuml;gen (f&uuml;r ein
+ einfaches Beispiel, welches <function>auto-indent</function>
+ hinzuf&uuml;gt, sehen Sie sich bitte
+ <function>my-scheme-mode-hook</function> an).</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="tools-reading">
+ <title>Weiterf&uuml;hrende Literatur</title>
+
+ <para>F&uuml;r Informationen zum Aufsetzen einer
+ Entwicklungsumgebung, um Fehlerbehebungen an FreeBSD selber
+ beizusteuern sehen Sie sich bitte &man.development.7; an.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Brian Harvey and Matthew Wright
+ <emphasis>Simply Scheme</emphasis>
+ MIT 1994.<!-- <br> -->
+ ISBN 0-262-08226-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Randall Schwartz
+ <emphasis>Learning Perl</emphasis>
+ O'Reilly 1993<!-- <br> -->
+ ISBN 1-56592-042-2</para>
+ </listitem>
+
+ <listitem>
+ <para>Patrick Henry Winston and Berthold Klaus Paul Horn
+ <emphasis>Lisp (3rd Edition)</emphasis>
+ Addison-Wesley 1989<!-- <br> -->
+ ISBN 0-201-08319-1</para>
+ </listitem>
+
+ <listitem>
+ <para>Brian W. Kernighan and Rob Pike
+ <emphasis>The Unix Programming Environment</emphasis>
+ Prentice-Hall 1984<!-- <br> -->
+ ISBN 0-13-937681-X</para>
+ </listitem>
+
+ <listitem>
+ <para>Brian W. Kernighan and Dennis M. Ritchie
+ <emphasis>The C Programming Language (2nd Edition)</emphasis>
+ Prentice-Hall 1988<!-- <br> -->
+ ISBN 0-13-110362-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Bjarne Stroustrup
+ <emphasis>The C++ Programming Language</emphasis>
+ Addison-Wesley 1991<!-- <br> -->
+ ISBN 0-201-53992-6</para>
+ </listitem>
+
+ <listitem>
+ <para>W. Richard Stevens
+ <emphasis>Advanced Programming in the Unix Environment</emphasis>
+ Addison-Wesley 1992<!-- <br> -->
+ ISBN 0-201-56317-7</para>
+ </listitem>
+
+ <listitem>
+ <para>W. Richard Stevens
+ <emphasis>Unix Network Programming</emphasis>
+ Prentice-Hall 1990<!-- <br> -->
+ ISBN 0-13-949876-1</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+</chapter>
+<!--
+ Local Variables:
+ mode: sgml
+ sgml-declaration: "../chapter.decl"
+ sgml-indent-data: t
+ sgml-omittag: nil
+ sgml-always-quote-attributes: t
+ sgml-parent-document: ("../book.sgml" "part" "chapter")
+ End:
+-->