diff options
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.sgml | 2644 |
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>Übersetzt von </contrib> + </author> + <author> + <firstname>Fabian</firstname> + <surname>Borschel</surname> + </author> + </authorgroup> + </chapterinfo> + + <title>Werkzeuge zur Programmierung</title> + + <sect1 id="tools-synopsis"> + <title>Überblick</title> + + <para>Dieses Kapitel ist eine Einführung in die Benutzung + einiger der Werkzeuge zur Programmierung die mit FreeBSD + ausgeliefert werden. Trotzdem ist vieles auch auf verschiedene + andere Versionen von &unix; übertragbar. Dieses Kapitel + soll <emphasis>kein</emphasis> Versuch sein Programmierung + detailliert zu beschreiben. Der größ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ür C und C++, sowie ein Assembler sind im + Basissystem enthalten. Natü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ührung in die Programmierung</link>, + zählt ein paar der verfü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öglich Anwendungen zu schreiben, welche ohne oder + zumindest ohne wesentliche Änderungen auf einer + großen Zahl an Plattformen kompilieren und laufen + werden.</para> + + <para>Allerdings können all diese Möglichkeiten + anfangs etwas überwältigend sein, wenn Sie vorher nie + Programme auf einem &unix;-System geschrieben haben. Dieses + Dokument hat die Zielsetzung ihnen beim Einstieg zu helfen ohne + allzu weit in fortgeschrittene Themen vorzudringen. Die + Intention ist, daß dieses Dokument ihnen ausreichend + Basiswissen vermittelt und die weitergehende Dokumentation + sinnvoll nutzen zu können.</para> + + <para>Der größte Teil dieses Dokuments erfordert wenige + oder gar keine Kenntnisse in der Programmierung, es werden + trotzdem Basiswissen im Umgang mit &unix; und die Bereitschaft + zu lernen vorausgesetzt!</para> + </sect1> + + <sect1 id="tools-programming"> + <title>Einfü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 Überblick über die beiden + wesentlichen Methoden diese Anweisungen oder + <quote>Befehle</quote>, wie man diese Anweisungen + üblicherweise nennt, zu geben. Die eine Methode nutzt einen + <firstterm>Interpreter</firstterm>, die andere einen + <firstterm>Compiler</firstterm>. Da menschliche Sprachen + für einen Computer nicht unmissverständlich sind, + werden diese Befehle in einer Sprache geschrieben die speziell + für diesen Zweck gedacht ist.</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ührt wird. + Für kompliziertere Programme können Sie die Befehle + in eine Datei schreiben und den Interpreter dazu bringen diese + Datei zu laden und die enthaltenen Befehle auszuführen. + Falls etwas schief geht werden viele Interpreter Sie an einen + Debugger weiterleiten.</para> + + <para>Der Vorteil hierbei ist, das Sie das Ergebnis ihres + Befehls direkt sehen und Fehler sofort korrigiert werden + können. Der größte Nachteil bei dieser Methode + entsteht, wenn Sie ihr Programm mit jemandem teilen wollen. + Diese Person muss den selben Interpreter nutzen wie Sie es tun + und Sie muss wissen wie dieser zu bedienen ist. + Zudem werden Benutzer es nicht begrüßen sich in + einem Debugger wiederzufinden, wenn Sie einmal die falsche + Taste drücken! Bei einem Blick auf die + Leistungsfä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önnte auch sagen, + dass die &unix; Shell (<command>sh</command>, + <command>csh</command>) für sich bereits einen + Interpreter darstellt und viele Leute schreiben + tatsächlich Shell <quote>Scripten</quote> um sich bei + einigen <quote>Haushaltsaufgaben</quote> auf ihren Maschinen + helfen zu lassen. Tatsächlich war es ein wesentlicher + Teil der originalen &unix; Philosophie eine große Zahl + an kleinen Hilfsprogrammen zur Verfügung zu stellen, + welche mittels eines Shellskripts miteinander kombiniert werden + um bestimmte Aufgaben zu übernehmen.</para> + </sect2> + + <sect2> + <title>Für FreeBSD verfügbare Interpreter</title> + + <para>Im folgenden eine Liste der über die &os; + Ports-Sammlung verfügbaren Interpreter + einschließlich einer kurzen Erörterung der + populären interpretierten Sprachen.</para> + + <para>Anleitungen wie man Anwendungen aus der Ports-Sammlung + erhält und installiert kö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ü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ändigen Personal Computer ausgeliefert und war + für viele Programmierer die erste + Programmiersprache. <acronym>BASIC</acronym> ist auch + die Grundlage fü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äten 50er Jahren + als Alternative zu den, zu dieser Zeit populären, + <quote>zahlenverarbeitenden</quote> Sprachen entwickelt. + Anstelle auf Zahlen basiert Lisp auf Listen; + tatsächlich ist der Name Lisp eine Kurzform + für <quote>List Processing</quote> (Listen + abarbeiten). Sehr populär fü + <acronym>AI</acronym> (Artificial Intelligence/ + künstliche Intelligez) (Fach-) Kreisen.</para> + + <para>Lisp ist eine extrem kraftvolle und durchdachte + Sprache, kann aber auch recht groß und unhandlich + sein.</para> + + <para>Zahlreiche Ausformungen von Lisp, die auf &unix; + Systemen laufen sind über die Ports-Sammlung + verfü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ür + CMUCL, welches auch einen hoch-optimierten Compiler + enthält, oder einfachere Ausformungen wie SLisp, + das die meisten gängigen Lisp Konstrukte in wenigen + hundert Zeilen C Code enthä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ä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ür alle + &os;-Versionen verfü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äten sehr beliebt, da er zum einen + für den Unterricht im Grundstudium einfach genug + ist, und zum anderen ein ausreichend hohes + Abstraktionsniveau für den Einsatz in der Forschung + bietet.</para> + + <para>Scheme ist in der Ports-Sammlung in Form des Elk + Scheme Interpreters als <filename + role="package">lang/elk</filename> verfü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öglichkeiten zur Verarbeitung von Zeichenketten + und Strukturen. Die unter &os; verfügbare Version + von Icon steht in der Ports-Sammlung unter <filename + role="package">lang/icon</filename> zur + Verfügung.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Logo</term> + + <listitem> + <para>Logo ist eine leicht zu erlernende + Programmiersprache, welche in vielen Kursen als + einführende Programmiersprache gewählt wird. + Sie ist ein ideales Arbeitswerkzeug beim Unterricht mit + jungen Menschen, da mit ihr die Erstellung komplizierter + geometrischer Oberflächen selbst für kleine + Kinder einfach ist.</para> + + <para>Die für &os; aktuellste, verfü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ß sie eine der besten + Programmiersprachen für Programmieranfänger + sei, da sie einfach zu erlernen ist, und anderen + populären interpretierten Programmiersprachen, + welche zur Entwicklung großer und komplexer + Anwendungen verwendet werden, in nichts nachsteht (Perl + und Tcl sind zwei solcher bekannten + Programmiersprachen).</para> + + <para>Die aktuellste Version von Python ist in der + Ports-Sammlung unter <filename + role="package">lang/python</filename> + verfügbar.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Ruby</term> + + <listitem> + <para>Ruby ist eine interpretierte und rein + objektorientierte Programmiersprache. Sie wurde wegen + ihrer leicht verständlichen Syntax, ihrer + Flexibilität und der Möglichkeit, große und + komplexe Programme einfach zu entwickeln und zu pflegen, + populär.</para> + + <para>Ruby ist in der Ports-Sammlung unter <filename + role="package">lang/ruby18</filename> + verfü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ü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ür &os; verfügbar. Die aktuellste Version, + Tcl 8.5, ist unter <filename + role="package">lang/tcl85</filename> + verfü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ßend ruft man den Compiler auf + um zu sehen, ob dieser das Programm annimmt. Wenn das Programm + nicht kompiliert werden konnte, muß man die Zähne + zusammenbeissen und wieder zum Editor zurückkehren; falls + das Programm kompiliert und eine ausführbare Anwendung + erzeugt wurde, kann man diese über eine + Eingabeaufforderung oder über einen Debugger aufrufen um + zu sehen, ob sie auch funktioniert. + + <footnote> + <para>Wenn die Anwendung über eine Eingabeaufforderung + gestartet wird kö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öglich, die mit einem + Interpreter nur sehr schwer oder überhaupt nicht + realisierbar wären, wie z.B. das Schreiben von Code, der + sehr eng mit dem Betriebsystem zusammen arbeitet—oder + das Schreiben eines eigenen Betriebsystems selbst! Des + weiteren ist so das Erzeugen von sehr effizientem Code + möglich, da sich der Compiler für die Optimierung + Zeit nehmen kann, was bei einem Interpreter inakzeptabel + wäre. Ferner ist das Verbreiten von Programmen, welche + für einen Compiler geschrieben wurden, einfacher als + welche, die für einen Interpreter geschrieben + wurden—man muss in ersterem Fall nur die + ausführbare Datei verbreiten, vorausgesetzt, daß 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ür erfahrene + Programmierer gedacht; Pascal auf der anderen Seite wurde zu + Ausbildungszwecken entworfen, und stellt daher eine + einsteigerfreundliche Programmiersprache dar. FreeBSD + beinhaltet im Basissystem keine Unterstützung für + Pascal, stellt jedoch über die Ports-Sammlung den + Free Pascal Compiler unter <filename + role="package">lang/fpc</filename> zur Verfügung.</para> + + <para>Da der editier-kompilier-ausführ-debug-Kreislauf + unter Verwendung mehrerer Programme eher mühsam ist haben + viele Hersteller von Compilern integrierte + Entwicklungsumgebungen (Integrated Development Environment; + auch kurz <acronym>IDE</acronym>) entwickelt. FreeBSD bietet + zwar im Basissystem keine IDE an, stellt jedoch über die + Ports-Sammlung IDEs wie <filename + role="package">devel/kdevelop</filename> oder + <application>Emacs</application> zur Verfü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ßlich den GNU + Compiler fü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ührlich in der zugehörigen + Dokumentation oder Online-Hilfe beschrieben.</para> <para>Sobald + Sie Ihr Meisterwerk fertig geschrieben haben besteht der + nächste Schritt darin, dieses (hoffentlich!) unter FreeBSD + zum Laufen zu bekommen. Dies beinhaltet üblicherweise + mehrere Schritte, wobei jeder einzelne Schritt von einem + separaten Programm durchgeführt wird.</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>Überprü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>Übersetzen des Quelltextes in Assemblersprache + —diese ist dem eigentlichen Maschinencode schon sehr + nahe, jedoch immer noch für Menschen lesbar. + Angeblich. + + <footnote> + <para>Um genau zu sein übersetzt der + <command>cc</command> den Quelltext an dieser Stelle + nicht in Assemblersprache, sondern in seine eigene, + maschinenunabhängige Sprache namens + <firstterm>p-code</firstterm>.</para> + </footnote> + </para> + </step> + + <step> + <para>Übersetzen der Assemblersprache in + Maschinencode—genau, wir sprechen hier von Bits und + Bytes, Einsen und Nullen.</para> + </step> + + <step> + <para>Überprüfen, ob Sie Dinge wie Funktionen und + globale Variablen in einheitlicher Weise verwendet haben. + Wenn Sie z.B. eine nicht existierende Funktion aufgerufen + haben, wird eine entsprechende Fehlermeldung Ihnen dies + mitteilen.</para> + </step> + + <step> + <para>Wenn aus mehreren Quelltextdateien eine + ausführbare Datei erstellt werden soll wird + herausgefunden, wie die einzelnen Codeteile + zusammengefügt werden mü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ühren kann.</para> + </step> + + <step> + <para>Endgültiges Schreiben der ausführbaren Datei + in das Dateisystem.</para> + </step> + </procedure> + + <para>Das Wort <firstterm>kompilieren</firstterm> wird häufig + für die Schritte 1 bis 4 verwendet—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ücklicherweise werden alle diese Details vor Ihnen + verborgen, da <command>cc</command> ein Frontend ist, welches + sich um die Ausführung all dieser Programme mit den + richtigen Argumenten für Sie kümmert; einfaches + eingeben von</para> + + <screen>&prompt.user; <userinput>cc foobar.c</userinput></screen> + + <para>führt zur Übersetzung von + <filename>foobar.c</filename> durch alle bereits erwähnten + Schritte. Wenn Sie mehr als eine Datei übersetzen wollen + müssen Sie etwas wie folgt eingeben</para> + + <screen>&prompt.user; <userinput>cc foo.c bar.c</userinput></screen> + + <para>Beachten Sie, daß die Überprüfung der Syntax + genau dies tut—das reine Überprüfen der Syntax. + Es findet keine Überprüfung bzgl. logischer Fehler + statt, die Sie vielleicht gemacht haben, wie z.B. das Programm + in eine Endlosschleife zu versetzen, oder Bubble Sort zu + verwenden, wenn Sie eigentlich Binary Sort benutzen wollten. + + <footnote> + <para>Falls Sie es nicht wußten, Binary Sort ist, im + Gegensatz zu Bubble Sort, eine effektive Möglichkeit, + Dinge zu sortieren.</para> + </footnote> + </para> + + <para>Es gibt haufenweise Optionen für <command>cc</command>, + die alle in der zugehö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ü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ützlich für Spielereien, um die Syntax + auf Korrektheit zu überprü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ührbar) + mit den Namen <filename>foobar.o</filename>. Diese kann + mit anderen Objektdateien zusammen zu einer + ausführbaren Datei verlinkt werden.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-g</option></term> + + <listitem> + <para>Diese Option erzeugt die Debug-Version einer + ausführbaren Datei. Dabei fügt der Compiler + zusätzliche Informationen darüber, welcher + Funktionsaufruf zu welcher Zeile im Quelltext gehört, + der ausführbaren Datei hinzu. Ein Debugger kann Ihnen + mit Hilfe dieser Information den zugehörigen + Quelltext anzeigen, während Sie den Programmverlauf + schrittweise verfolgen, was <emphasis>sehr</emphasis> + hilfreich sein kann; der Nachteil dabei ist, daß + durch die zusätzlichen Informationen das Programm + viel größer wird. Normalerweise verwendet man + die Option <option>-g</option> während der + Entwicklung eines Programms, und für die + <quote>Release-Version</quote>, wenn man von der + Korrektheit des Programms ü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ß an dieser Stelle die + Option <option>-o</option> zum Festlegen des Namens + der ausführbaren Datei nicht verwendet wurde, + weswegen an dieser Stelle die erzeugte Datei + <filename>a.out</filename> heißt. Die Erzeugung + einer Debug-Version namens <filename>foobar</filename> + ist als Übung dem Leser überlassen!</para> + </footnote> + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-O</option></term> + + <listitem> + <para>Diese Option erzeugt eine optimierte Version der + ausführbaren Datei. Der Compiler verwendet einige + clevere Tricks, um das erzeugte Programm schneller zu + machen. Sie können hinter der Option + <option>-O</option> eine Zahl angeben, um eine + höheres Level der Optimierung festzulegen. Dadurch + wird jedoch häufig eine fehlerhafte Optimierung + seitens des Compilers aufgedeckt. Zum Beispiel erzeugte + die Version des <command>cc</command>, welche mit dem + FreeBSD Release 2.1.0 mitgeliefert wurde, bei Verwendung + der Option <option>-O2</option> unter bestimmten + Umstä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 überprüfen, welche häufig als + <acronym>ANSI</acronym> Standards bezeichnet werden, obwohl sie + streng genommen zum <acronym>ISO</acronym> Standard + gehören.</para> + + <variablelist> + <varlistentry> + <term><option>-Wall</option></term> + + <listitem> + <para>Aktivieren aller Warnmeldungen, die die Autoren des + <command>cc</command> für wichtig halten. Trotz des + Namens dieser Option werden dadurch nicht sämtliche + Warnungen ausgegeben, die der <command>cc</command> + ausgeben könnte.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-ansi</option></term> + + <listitem> + <para>Deaktivieren der meisten, jedoch nicht aller, + nicht-<acronym>ANSI</acronym> C Eigenschaften, die + der <command>cc</command> bietet. Trotz des Namens ist + durch diese Option nicht sichergestellt, daß Ihr + Code diese Standards auch vollständig + einhä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> 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ützlich, werden jedoch + nicht von anderen Compilern unterstützt—eigentlich + ist eines der Hauptziele des Standards, das Leute Code so + schreiben können, daß dieser mit jedem Compiler auf + beliebigen Systemen funktioniert. Dies wird häufig als + <firstterm>portabler Code</firstterm> bezeichnet.</para> + + <para>Im Allgemeinen sollten Sie versuchen, Ihren Code so portabel + wie möglich zu schreiben, da Sie ansonsten eventuell das + gesamte Programm noch einmal neu schreiben müssen, falls + dieser in einer anderen Umgebung laufen soll—und wer + weiß schon was er in ein paar Jahren verwenden + wird?</para> + + <informalexample> + <screen>&prompt.user; <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen> + </informalexample> + + <para>Durch diesen Befehl wird eine ausführbare Datei namens + <filename>foobar</filename> erzeugt, nachdem + <filename>foobar.c</filename> auf die Einhaltung der Standards + überprü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ährend des Verlinkens + verwendet wird.</para> + + <para>Das am häufigsten auftretende Beispiel dieser + Option ist die Übersetzung eines Programmes, welches + einige der mathematischen Funktionen in C verwendet. Im + Gegensatz zu den meisten anderen Plattformen befinden sich + diese Funktionen in einer separaten Bibliothek, deren + Verwendung Sie dem Compiler explizit mitteilen + müssen.</para> + + <para>Angenommen eine Bibliothek heißt + <filename>lib<replaceable>irgendwas</replaceable>.a</filename>, + dann müssen Sie dem <command>cc</command> als + Argument + <option>-l<replaceable>irgendwas</replaceable></option> + übergeben. Zum Beispiel heißt die + Mathematik-Bibliothek <filename>libm.a</filename>, und + daher müssen Sie dem <command>cc</command> als + Argument <option>-lm</option> übergeben. Ein + typisches <quote>Manko</quote> der Mathematik-Bibliothek + ist, daß diese immer die letzte Bibliothek auf der + Kommandozeile sein muß.</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üssen Sie + <option>-lg++</option>, bzw. <option>-lstdc++</option> + falls Sie FreeBSD 2.2 oder neuer verwenden, zu Ihrer + Kommandozeile hinzufügen, um Ihr Programm gegen die + Funktionen der C++ Bibliothek zu linken. Alternativ + können Sie anstatt <command>cc</command> auch + <command>c++</command> aufrufen, welcher dies fü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 ä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ührbare + <filename>foobar</filename> aus der C++ Quelltextdatei + <filename>foobar.cc</filename>. Beachten Sie bitte, + daß auf &unix; Systemen C++ Quelltextdateien + ü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ür die Quelltextdatei zum Einsatz + kommen soll; allerdings gilt diese Einschränkung + jetzt nicht mehr, und Sie können Ihre C++-Dateien + ungestraft auf <filename>.cpp</filename> enden + lassen!</para> + </listitem> + </varlistentry> + </variablelist> + + <sect2> + <title>Hä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ü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 + Übung für <option>-lm</option> geschrieben. + Alles was es macht ist, 2.1 hoch 6 zu berechnen.</para> + + <informalexample> + <programlisting>#include <stdio.h> + +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ü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, + überprüft er, ob er schon einmal einen + Prototypen für diese gesehen hat. Wenn nicht nimmt + er als Rü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ören, seltsame Dinge mit Ihrer Berechnung zu + machen!</para> + + <informalexample> + <programlisting>#include <math.h> +#include <stdio.h> + +int main() { +... + </programlisting> + </informalexample> + + <para>Nach erneutem Compilieren sollte das Folgende bei + der Ausfü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ührbare Datei namens + <filename>foobar</filename> finden. Wo befindet sich + diese?</para> + </question> + + <answer> + <para>Denken Sie daran, daß der + <command>cc</command> die ausführbare Datei + <filename>a.out</filename> nennt, wenn Sie nicht + explizit einen Namen angeben. Verwenden Sie in solch + einem Fall die Option + <option>-o <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ü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ß 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ührbaren + Programm, das Sie versuchen auszuführen, solange + Sie dies nicht explizit mit angeben. Sie können + entweder <command>./foobar</command> eingeben, was + soviel bedeutet wie <quote>führe eine Datei namens + <filename>foobar</filename> im aktuellen Verzeichnis + aus</quote>, oder Sie können Ihre Umgebungsvariable + <envar>PATH</envar> so erweitern, daß sie + ä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ü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önnen entweder den folgenden Befehl + eingeben:</para> + + <informalexample> + <screen>&prompt.user; <userinput>./test</userinput> + </screen> + </informalexample> + + <para>oder Sie können einen geeigneteren Namen + für Ihr Programm wä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ühen Zeiten von &unix;, als die + Maschinen noch Kernspeicher zum Speichern von Daten + verwendeten. Einfach ausgedrückt, wenn bei einem + Programm unter bestimmen Bedingungen ein Fehler auftrat, + hat das System den Inhalt des Kernspeichers auf der + Festplatte in eine Datei namens + <filename>core</filename> geschrieben, welche der + Programmierer dann nä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ßt im Prinzip, daß Ihr + Programm eine illegale Operation mit dem Speicher + durchführen wollte; &unix; wurde so entworfen, + daß es das andere Programme und das Betriebssystem + selbst vor wildgewordenen Programmen + schützt.</para> + + <para>Häufige Ursachen hierfü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älligen Wert, + welcher mit etwas Glück in einen Bereich des + Speichers zeigt, der für Ihr Programm nicht + verfügbar ist, und der Kernel bricht Ihr + Programm ab, bevor es irgendwelchen Schaden + anrichten kann. Wenn Sie Pech haben zeigt der Zeiger + irgendwo mitten in Ihr eigenes Programm, und + verändert dort ihre eigenen Datenstrukturen, + was zu sehr seltsamen Fehlern Ihres Programmes + führt.</para> + </listitem> + + <listitem> + <para>Der Versuch, auf Daten auß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ä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ü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ühren zwar nicht + immer zu einem Fehlverhalten des Programms, stellen + jedoch immer eine falsche Verwendung dar. Manche Systeme + und Compiler sind toleranter als andere, weshalb + Programme auf dem einen System einwandfrei laufen, auf + dem anderen System jedoch abstürzen.</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ß die Ursache ein + Hardwareproblem sei. Der Computer scheint aber weiterhin + zu funktionieren. Ist dies wahr?</para> + </question> + + <answer> + <para>Nein, glücklicherweise nicht (es sei denn Sie + haben wirklich ein Hardwareproblem…). + Üblicherweise ist dies ein Weg Ihnen mitzuteilen, + daß 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ört sich sehr + nützlich an, wenn ich so etwas selber an beliebiger + Stelle bewirken könnte. Kann ich das tun, oder + muß ich warten bis ein Fehler auftritt?</para> + </question> + + <answer> + <para>Ja, nehmen sie einfach eine andere Konsole oder + XTerm und führen Sie</para> + + <screen>&prompt.user; <userinput>ps</userinput> + </screen> + + <para>aus, um die Prozess-ID Ihres Programms + herauszufinden. Führen Sie + anschließ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ü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öglichkeiten, die denselben + Effekt haben.</para> + + <para>Alternativ können Sie einen core dump aus + Ihrem Programm heraus erstellen, indem Sie die Funktion + <function>abort()</function> aufrufen. Weitere + Informationen darüber können Sie in der + Manualpage &man.abort.3; nachlesen.</para> + + <para>Wenn Sie einen core dump von außerhalb Ihres + Programms erzeugen wollen, ohne dabei den Prozess + abzubrechen, können Sie das Programm + <command>gcore</command> verwenden. Weitere + Informationen dazu finden Sie in der zugehö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ästig—und auch das + Kompilieren kann eine Weile dauern.</para> + + <para>Eine Möglichkeit dies zu umgehen besteht in der + Verwendung von Objektdateien, wobei man nur die + Quelltextdateien neu kompiliert, die verändert wurden. So + könnten wir etwa folgendes erhalten:</para> + + <screen>&prompt.user; <userinput>cc file1.o file2.o</userinput> … <userinput>file37.c</userinput> …</screen> + + <para>falls wir seit dem letzten Kompiliervorgang nur die Datei + <filename>file37.c</filename> verändert haben. Dadurch + könnte der Kompiliervorgang um einiges beschleunigt + werden, es muß jedoch immer noch alles von Hand + eingegeben werden.</para> + + <para>Oder wir könnten uns ein Shell Skript schreiben. + Dieses würde jedoch alles immer wieder neu kompilieren, + was bei einem großen Projekt sehr ineffizient + wäre.</para> + + <para>Was ist, wenn wir hunderte von Quelltextdateien + hätten? Was ist, wenn wir in einem Team mit anderen + Leuten arbeiten würden, die vergessen uns Bescheid zu + sagen, falls sie eine der Quelltextdateien verändert + haben, die wir ebenfalls benutzen?</para> + + <para>Vielleicht könnten wir beide Lösungen + kombinieren und etwas wie ein Shell Skript schreiben, welches + eine Art magische Regel enthalten würde, die feststellt, + welche Quelltextdateien neu kompiliert werden müssten. + Alles was wir bräuchten wäre ein Programm, das diese + Regeln verstehen könnte, da diese Aufgabe etwas zu + kompliziert für eine Shell ist.</para> + + <para>Dieses Programm heißt <command>make</command>. Es + liest eine Datei namens <firstterm>makefile</firstterm>, + welche ihm sagt, wie unterschiedliche Dateien voneinander + abhängen, und berechnet, welche Dateien neu kompiliert + werden müssen und welche nicht. Zum Beispiel könnte + eine Regel etwas sagen wie <quote>wenn + <filename>fromboz.o</filename> älter als + <filename>fromboz.c</filename> ist, bedeutet dies, daß + jemand die Datei <filename>fromboz.c</filename> verändert + haben muß, und diese daher neu kompiliert werden + muß.</quote> Das makefile enthält außerdem + Regeln die make sagen, <emphasis>wie</emphasis> die + Quelltextdatei neu kompiliert werden muß, was dieses + Tool noch sehr viel mächtiger macht.</para> + + <para>Makefiles werden normalerweise im selben Verzeichnis + wie die Quelltextdateien abgelegt, zu denen sie gehören, + und kann <filename>makefile</filename>, + <filename>Makefile</filename> oder + <filename>MAKEFILE</filename> heißen. Die meisten + Programmierer verwenden den Namen + <filename>Makefile</filename>, da diese Schreibweise + dafür sorgt, daß die Datei gut lesbar ganz oben in + der Verzeichnisliste aufgeführt wird. + + <footnote> + <para>Verwenden Sie nicht <filename>MAKEFILE</filename> mit + lauter Großbuchstaben, da diese Schreibweise + häufig fü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ängigkeitszeile und einer Erzeugungszeile.</para> + + <para>Die Abhängigkeitszeile hier besteht aus dem Namen + des Programms (auch <firstterm>Ziel</firstterm> genannt), + gefolgt von einem Doppelpunkt und einem Leerzeichen, und + anschließend dem Namen der Quelltextdatei. Wenn + <command>make</command> diese Zeile liest überprüft + es die Existenz von <filename>foo</filename>; falls diese + Datei existiert vergleicht es das Datum der letzten + Änderung von <filename>foo</filename> mit der von + <filename>foo.c</filename>. Falls <filename>foo</filename> + nicht existiert, oder ä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ß.</para> + + <para>Die Erzeugungszeile beginnt mit einem <token>tab</token> + (drücken Sie dazu die <keycap>tab</keycap>-Taste) gefolgt + von dem Befehl, mit dem Sie <filename>foo</filename> manuell + erzeugen würden. Wenn <filename>foo</filename> veraltet + ist, oder nicht existiert, fü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ß.</para> + + <para>Wenn Sie also <userinput>make</userinput> eingeben wird + dieses sicherstellen, daß <filename>foo</filename> bzgl. + Ihrer letzten Änderungen an <filename>foo.c</filename> + auf dem neuesten Stand ist. Dieses Prinzip kann auf + <filename>Makefile</filename>s mit hunderten von + Zielen—es ist bei FreeBSD praktisch möglich, das + gesamte Betriebssystem zu kompilieren, indem man nur + <userinput>make world</userinput> im richtigen Verzeichnis + eingibt!</para> + + <para>Eine weitere nützliche Eigenschaft der makefiles + ist, daß die Ziele keine Programme sein müssen. Wir + kö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ö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ören. Wenn wir hier also nur + <userinput>make</userinput> eingegeben hätten, würde + es nur zu dem Ziel <maketarget>foo</maketarget> gehen, + gegebenenfalls <filename>foo</filename> neu kompilieren, und + danach einfach aufhören, ohne das Ziel + <maketarget>install</maketarget> zu beachten.</para> + + <para>Beachten Sie, daß das <maketarget>install</maketarget>-Ziel + von nichts anderem abhängt! Dies bedeutet, daß der + Befehl in der nachfolgenden Zeile immer ausgefü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ä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ären. Wenn + Sie immer noch nicht so richtig verstanden haben, wie + <command>make</command> funktioniert, wä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ßchen + herum. Als nächstes könnten Sie mehrere + Quelltextdateien verwenden, oder in Ihrer Quelltextdatei eine + Header-Datei includen. Der Befehl <command>touch</command> ist + an dieser Stelle ganz hilfreich—er verändert das + Datum einer Datei, ohne das Sie diese extra editieren + müssen.</para> + </sect2> + + <sect2> + <title>Make und include-Dateien</title> + + <para>C-Code beginnt häufig mit einer Liste von Dateien, + die included werden sollen, zum Beispiel stdio.h. Manche + dieser Dateien sind include-Dateien des Systems, andere + gehören zum aktuellen Projekt, an dem Sie gerade + arbeiten:</para> + + <programlisting>#include <stdio.h> +#include "foo.h" + +int main(....</programlisting> + + <para>Um sicherzustellen, daß diese Datei neu kompiliert + wird, wenn <filename>foo.h</filename> verändert wurde, + müssen Sie diese Datei Ihrem + <filename>Makefile</filename> hinzufügen:</para> + + <programlisting>foo: foo.c foo.h</programlisting> + + <para>Sobald Ihr Projekt größer wird und Sie mehr + und mehr eigene include-Dateien verwalten müssen wird es + nur noch sehr schwer möglich sein, die Übersicht + über alle include-Dateien und Dateien, die von diesen + abhängen, beizubehalten. Falls Sie eine include-Datei + verändern, jedoch das erneute Kompilieren aller Dateien, + die von dieser Datei abhängen, vergessen, werden die + Folgen verheerend sein. Der <command>gcc</command> besitzt + eine Option, bei der er Ihre Dateien analysiert und eine Liste + aller include-Dateien und deren Abhängigkeiten erstellt: + <option>-MM</option>.</para> + + <para>Wenn Sie das Folgende zu Ihrem Makefile + hinzufügen:</para> + + <programlisting>depend: + gcc -E -MM *.c > .depend</programlisting> + + <para>und <userinput>make depend</userinput> ausfü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ändern + werden beim nächsten Aufruf von <command>make</command> + alle Dateien, die von <filename>foo.h</filename> + abhä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ügt + haben.</para> + </sect2> + + <sect2> + <title>FreeBSD Makefiles</title> + + <para>Makefiles können eher schwierig zu schreiben sein. + Glücklicherweise kommen BSD-basierende Systeme wie + FreeBSD mit einigen sehr mächtigen solcher Dateien als + Teil des Systems daher. Ein sehr gutes Beispiel dafür ist + das FreeBSD Portssystem. Hier ist der grundlegende Teil eines + typischen <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 <bsd.port.mk></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 überprüft, ob sich der Quelltext + fü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ür den Quelltext wird berechnet + und mit der schon bekannten und für sicher und gut + empfundenen verglichen. Damit wird sichergestellt, + daß der Quelltext bei der Übertragung nicht + beschädigt wurde.</para> + </step> + + <step> + <para>Sämtliche Anpassungen, die nötig sind, + damit der Quelltext unter FreeBSD funktioniert, werden + vorgenommen—dieser Vorgang wird auch + <firstterm>patchen</firstterm> genannt.</para> + </step> + + <step> + <para>Alle speziellen Konfigurationen, die am Quelltext + nötig sind, werden vorgenommen. (Viele &unix; + Programmdistributionen versuchen herauszufinden, auf + welcher &unix;-Version sie kompiliert werden sollen und + welche optionalen &unix;-Features vorhanden sind—an + dieser Stelle erhalten sie die Informationen im FreeBSD + Ports Szenario).</para> + </step> + + <step> + <para>Der Quelltext für das Programm wird kompiliert. + Im Endeffekt wechseln wir in das Verzeichnis, in das der + Quelltext entpackt wurde, und rufen + <command>make</command> auf—die eigene make-Datei + des Programms besitzt die nötigen Informationen um + dieses zu bauen.</para> + </step> + + <step> + <para>Wir haben jetzt eine kompilierte Version des + Programmes. Wenn wir wollen können wir dieses jetzt + testen; wenn wir überzeugt vom Programm sind, + können wir <userinput>make install</userinput> + eingeben. Dadurch werden das Programm sowie alle + zugehörigen Dateien an die richtige Stelle kopiert; + es wird auch ein Eintrag in der + <database>Paketdatenbank</database> erzeugt, sodaß + der Port sehr einfach wieder deinstalliert werden kann, + falls wir unsere Meinung über dieses geändert + haben.</para> + </step> + </procedure> + + <para>Ich glaube jetzt werden Sie mit mir übereinstimmen, + daß dies ziemlich eindrucksvoll fü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 übersehen, aber hierher + kommt all das klevere Zeugs—jemand hat ein makefile + geschrieben, welches <command>make</command> anweist, alle + weiter oben beschriebenen Schritte durchzuführen (neben + vielen weiteren Dingen, die ich nicht angesprochen habe, + einschließlich der Behandlung sämtlicher Fehler, + die auftreten könnten) und jeder kann darauf + zurückgreifen, indem er eine einzige Zeile in seine + eigene make-Datei einfügt!</para> + + <para>Falls Sie einen Blick in die makefiles des Systems werfen + möchten, finden Sie diese in + <filename>/usr/share/mk</filename>. Es ist aber wahrscheinlich + besser, wenn Sie damit noch warten, bis Sie ein biß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ä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ächtlich voneinander. + Der beste Weg herauszufinden was sie können ist + wahrscheinlich deren Dokumentation zu lesen—hoffentlich + hat diese Einführung Ihnen genügend Grundkenntnisse + vermitteln können, damit Sie dies tun kö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üssen Sie</para> + + <screen>&prompt.user; <userinput>zmore paper.ascii.gz</userinput></screen> + + <para>in diesem Verzeichnis ausfü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ändiger Port und Paket verfügbar.</para> + + <para>Um sich die Info-Seiten für + <application>GNU make</application> anzusehen müssen Sie + die Datei <filename>dir</filename> in + <filename>/usr/local/info</filename> um einen entsprechenden + Eintrag erweitern. Dies beinhaltet das Einfügen einer + Zeile wie</para> + + <programlisting> * Make: (make). The GNU Make utility.</programlisting> + + <para>in die Datei. Nachdem Sie dies getan haben können + Sie <userinput>info</userinput> eingeben und dann den + Menüeintrag <guimenuitem>make</guimenuitem> + auswählen (oder Sie kö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ßt + <command>gdb</command> (<application>GNU + debugger</application>). Sie kö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ühren zu + können. Typischerweise können Sie so Zeile für + Zeile durch Ihr Programm gehen, die Werte von Variablen + untersuchen, diese verändern, dem Debugger sagen er soll + das Programm bis zu einem bestimmten Punkt ausführen und + dann anhalten, und so weiter und so fort. Sie können + damit sogar ein schon laufendes Programm untersuchen, oder + eine Datei mit einem Kernspeicherabbild laden um + herauszufinden, warum das Programm abgestürzt ist. Es ist + sogar möglich damit den Kernel zu debuggen, wobei dies + etwas trickreicher als bei den Benutzeranwendungen ist, welche + wir in diesem Abschnitt behandeln werden.</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änken wird.</para> + + <para>Falls Sie den textbasierten Kommandozeilen-Stil + abstoßend finden gibt es ein graphisches Front-End + dafür (<filename + role="package">devel/xxgdb</filename>) in der Ports-Sammlung.</para> + + <para>Dieser Abschnitt ist als Einfü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ühren</title> + + <para>Sie müssen das Programm mit der Option + <option>-g</option> kompiliert haben um den + <command>gdb</command> effektiv einsetzen zu können. Es + geht auch ohne diese Option, allerdings werden Sie dann nur + den Namen der Funktion sehen, in der Sie sich gerade befinden, + anstatt direkt den zugehörigen Quelltext. Falls Sie eine + Meldung wie die folgende sehen:</para> + + <screen>… (no debugging symbols found) …</screen> + + <para>wenn der <command>gdb</command> gestartet wird, dann + wissen Sie, daß 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ü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önnen nun Schritt für Schritt durch Ihr + Programm gehen, indem Sie <command>n</command> drücken. + Wenn Sie zu einem Funktionsaufruf kommen können Sie diese + Funktion durch drücken von <command>s</command> betreten. + Sobald Sie sich in einem Funktionsaufruf befinden können + Sie diesen durch drücken von <command>f</command> wieder + verlassen. Sie kö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 <stdio.h> + +int bazz(int anint); + +main() { + int i; + + printf("This is my program\n"); + bazz(i); + return 0; +} + +int bazz(int anint) { + printf("You gave me %d\n", anint); + return anint; +}</programlisting> + + <para>Dieses Programm setzt <symbol>i</symbol> auf den Wert + <literal>5</literal> und ü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ü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ß 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ü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>…</lineannotation> +main() { + int i; + + i = 5; + printf("This is my program\n"); +<lineannotation>…</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 übergebenen Argumente angezeigt, was uns + dabei hilft, die Übersicht zu behalten. (Der Stack ist + ein Speicherbereich, in dem ein Programm Informationen + über die an eine Funktion übergebenen Argumente + ablegt, sowie die Rücksprungadresse eines + Funktionsaufrufes).</para> + </note> + </sect2> + + <sect2> + <title>Eine Kernspeicherdatei untersuchen</title> + + <para>Eine Kernspeicherdatei ist im Prinzip eine Datei, die den + vollständigen Zustand eines Prozesses enthält, als + dieses abgestürzt ist. In <quote>den guten alten + Zeiten</quote> mußten Programmierer hexadezimale Listen + der Kernspeicherdatei ausdrucken und über + Maschinencodehandbüchern schwitzen, aber heutzutage ist + das Leben etwas einfacher geworden. Zufälligerweise wird + die Kernspeicherdatei unter FreeBSD und anderen + 4.4BSD-Systemen + <filename><replaceable>progname</replaceable>.core</filename> + anstatt einfach nur <filename>core</filename> genannt, um + deutlich zu machen, zu welchem Programm eine Kernspeicherdatei + gehört.</para> + + <para>Um eine Kernspeicherdatei zu untersuchen müssen Sie + den <command>gdb</command> wie gewohnt starten. An Stelle von + <command>break</command> oder <command>run</command> + mü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ü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ß das Programm + <filename>a.out</filename>, weshalb die Kernspeicherdatei den + Namen <filename>a.out.core</filename> trägt. Wie wir + sehen können stürzte das Programm in einer Funktion + namens <function>bazz</function> ab, als es versuchte auf + einen Speicherbereich zuzugreifen, der dem Programm nicht zur + Verfügung stand.</para> + + <para>Manchmal ist es ganz nützlich zu sehen, wie eine + Funktion aufgerufen wurde, da bei komplexen Programmen das + eigentliche Problem schon sehr viel weiter oben auf dem + Aufruf-Stack aufgetreten sein könnte. Der Befehl + <command>bt</command> veranlaß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ü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öglichkeit, damit bereits laufende Programme zu + untersuchen. Dies bedeutet natürlich, daß Sie die + erforderlichen Rechte dafür besitzen. Ein häufig + auftretendes Problem ist das Untersuchen eines Programmes, + welches sich selber forkt. Vielleicht will man den Kindprozess + untersuchen, aber der Debugger erlaubt einem nur den Zugriff + auf den Elternprozess.</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önnen dann wie + üblich mit der Fehlersuche fortfahren.</para> + + <para><quote>Das ist zwar alles sehr schön,</quote> werden + Sie jetzt vielleicht denken, <quote>aber in der Zeit, in der + ich diese Schritte durchführe, ist der Kindprozess schon + längst über alle Berge</quote>. Fürchtet euch + nicht, edler Leser, denn Ihr müßt wie folgt + vorgehen (freundlicherweise zur Verfügung gestellt von + den Info-Seite des <command>gdb</command>):</para> + + <screen><lineannotation>…</lineannotation> +if ((pid = fork()) < 0) /* _Always_ check this */ + error(); +else if (pid == 0) { /* child */ + int PauseMode = 1; + + while (PauseMode) + sleep(10); /* Wait until someone attaches to us */ + <lineannotation>…</lineannotation> +} else { /* parent */ + <lineannotation>…</lineannotation></screen> + + <para>Alles was Sie jetzt noch tun müssen ist, sich an + den Kindprozess ranzuhängen, <symbol>PauseMode</symbol> + auf <literal>0</literal> zu setzen und auf den + <function>sleep()</function> Funktionsaufruf zu warten, um + zurü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ächtige und freie IDEs in + der Ports-Sammlung wie etwa KDevelop.</para> + </footnote> + + Trotzdem ist es möglich, seine eigene + Entwicklungsumgebung aufzusetzen. Diese wird vielleicht nicht + so hübsch und integriert sein, aber dafür + können Sie sie Ihren eigenen Wünschen anpassen. Und + sie ist frei. Und Sie haben die Quelltexte davon.</para> + + <para>Der Schlüssel zu all dem ist Emacs. Es gibt zwar ein + paar Leute die ihn hassen, es gibt jedoch auch viele die ihn + lieben. Falls Sie zu ersteren gehören befürchte ich, + daß dieser Abschnitt Ihnen wenig interessantes zu bieten + hat. Des weiteren benötigen Sie eine angemessene Menge an + freiem Speicher, um ihn zu benutzen—ich würde 8MB + für den Textmodus und 16MB unter X als absolutes Minimum + empfehlen, um eine halbwegs brauchbare Performance zu + erhalten.</para> + + <para>Emacs ist im Prinzip ein extrem anpassbarer Editor— + in der Tat ist er so stark veränderbar, daß 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öglich alles hier + zusammenzufassen, was man mit dem Emacs machen kann. Im + Folgenden werden einige Features aufgelistet, die für + einen Entwickler interessant sein könnten:</para> + + <itemizedlist> + <listitem> + <para>Sehr mächtiger Editor, der suchen-und-ersetzen + mit Zeichenfolgen und regulären Ausdrücken + (Pattern) sowie das direkte Anspringen von Anfang/Ende von + Blockausdrücken erlaubt, etc, etc.</para> + </listitem> + + <listitem> + <para>Pull-Down Menüs und eine Online-Hilfe.</para> + </listitem> + + <listitem> + <para>Sprachunabhängige Syntaxhervorhebung und + automatische Einrückung.</para> + </listitem> + + <listitem> + <para>Vollständig konfigurierbar.</para> + </listitem> + + <listitem> + <para>Sie können Programme im Emacs kompilieren und + debuggen.</para> + </listitem> + + <listitem> + <para>Bei Kompilationsfehlern können Sie direkt zu der + entsprechenden Zeile im Quelltext springen.</para> + </listitem> + + <listitem> + <para>Benutzerfreundliches Front-End fü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ür den + <command>gdb</command> um sich beim Verfolgen der + Programmanweisungen den zugehörigen Quelltext + anzeigen zu lassen.</para> + </listitem> + + <listitem> + <para>Sie können E-Mails und News im Usenet lesen, + während ihr Programm kompiliert wird.</para> + </listitem> + </itemizedlist> + + <para>Und zweifelsfrei viele weitere Punkte, die ich + übersehen habe.</para> + + <para>Emacs kann unter &os; ü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ührung + in Emacs zu lesen—d.h. Sie sollen bei gedrückter + <keycap>Strg</keycap>-Taste die <keycap>h</keycap>-Taste + drücken, beide wieder loslassen und anschließend + <keycap>t</keycap> drücken. (Alternativ können Sie + mit der Maus den Eintrag <guimenuitem>Emacs + Tutorial</guimenuitem> aus dem + <guimenu>Hilfe</guimenu>-Menü auswählen).</para> + + <para>Obwohl der Emacs Menüs besitzt ist das Erlernen der + Tastaturkombinationen lohnenswert, da man beim Editieren sehr + viel schneller Tastenkombinationen eingeben kann, als die Maus + zu finden und mit dieser dann an der richtigen Stelle zu + klicken. Und wenn Sie sich mit erfahrenen Emacs-Benutzern + unterhalten werden Sie feststellen, daß diese + häufig nebenbei Ausdrücke wie <quote><literal>M-x + replace-s RET foo RET bar RET</literal></quote> verwenden, + weshalb das Erlernen dieser sehr nützlich ist. Und Emacs + hat auf jeden Fall weit mehr nützliche Funktionen als das + diese in der Menüleiste unterzubringen wären.</para> + + <para>Zum Glück ist es sehr einfach die jeweiligen + Tastaturkombinationen herauszubekommen, da diese direkt neben + den Menüeinträgen stehen. Meine Empfehlung + wäre, den Menüeintrag für, sagen wir, das + Öffnen einer Datei zu verwenden, bis Sie die + Funktionsweise verstanden haben und sie mit dieser vertraut + sind, und es dann mit C-x C-f versuchen. Wenn Sie damit + zufrieden sind, gehen Sie zum nächsten + Menüeintrag.</para> + + <para>Falls Sie sich nicht daran erinnern können, was eine + bestimmte Tastenkombination macht, wählen Sie + <guimenuitem>Describe Key</guimenuitem> aus dem + <guimenu>Hilfe</guimenu>-Menü aus und geben Sie die + Tastenkombination ein—Emacs sagt Ihnen dann was diese + macht. Sie können ebenfalls den Menüeintrag + <guimenuitem>Command Apropos</guimenuitem> verwenden, um alle + Befehle, die ein bestimmtes Wort enthalten, mit den + zugehörigen Tastenkombinationen aufgelistet zu + bekommen.</para> + + <para>Übrigends bedeutet der Ausdruck weiter oben, bei + gedrückter <keysym>Meta</keysym>-Taste <keysym>x</keysym> + zu drücken, beide wieder loszulassen, + <userinput>replace-s</userinput> einzugeben (Kurzversion + für <literal>replace-string</literal>—ein weiteres + Feature des Emacs ist, daß Sie Befehle abkürzen + können), anschließend die + <keysym>return</keysym>-Taste zu drücken, dann + <userinput>foo</userinput> einzugeben (die Zeichenkette, die + Sie ersetzen möchten), dann wieder + <keysym>return</keysym>, dann die Leertaste zu drücken + (die Zeichenkette, mit der Sie <literal>foo</literal> ersetzen + möchten) und anschließend erneut + <keysym>return</keysym> zu drücken. Emacs wird dann die + gewünschte suchen-und-ersetzen-Operation + ausfü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 + ü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üssen sie + <command>C-x C-c</command> (das bedeutet, Sie müssen bei + gedrückter <keysym>Strg</keysym>-Taste zuerst + <keysym>x</keysym> und dann <keysym>c</keysym> drücken) + eingeben. Falls Sie noch irgendwelche ungespeicherten Dateien + offen haben wird Emacs Sie fragen ob Sie diese speichern + wollen. (Ignorieren Sie bitte die Stelle der Dokumentation, an + der gesagt wird, daß <command>C-z</command> der + übliche Weg ist, Emacs zu verlassen—dadurch wird + der Emacs in den Hintergrund geschaltet, was nur nützlich + ist, wenn Sie an einem System ohne virtuelle Terminals + arbeiten).</para> + </sect2> + + <sect2> + <title>Emacs konfigurieren</title> + + <para>Emacs kann viele wundervolle Dinge; manche dieser Dinge + sind schon eingebaut, andere müssen erst konfiguriert + werden.</para> + + <para>Anstelle einer proprietären Macrosprache verwendet + der Emacs für die Konfiguration eine speziell für + Editoren angepaßte Version von Lisp, auch bekannt als + Emacs Lisp. Das Arbeiten mit Emacs Lisp kann sehr hilfreich + sein, wenn Sie darauf aufbauend etwas wie Common Lisp lernen + möchten. Emacs Lisp hat viele Features von Common Lisp + obwohl es beträchtlich kleiner ist (und daher auch + einfacher zu 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ügt habe, die für den Anfang ausreichen + sollte. Kopieren Sie diese einfach in Ihr Heimverzeichnis und + starten Sie den Emacs neu, falls dieser bereits läuft; er + wird die Befehle aus der Datei lesen und Ihnen (hoffentlich) + eine brauchbare Grundeinstellung bieten.</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ären; es gibt jedoch ein oder zwei Punkte, + die besonders erwähnenswert sind.</para> + + <itemizedlist> + <listitem> + <para>Alles was mit einem <literal>;</literal> anfängt + ist ein Kommentar und wird von Emacs ignoriert.</para> + </listitem> + + <listitem> + <para>In der ersten Zeile mit + <literal>-*- Emacs-Lisp -*-</literal> sorgt + dafür, daß wir die Datei + <filename>.emacs</filename> in Emacs selber editieren + können und uns damit alle tollen Features zum + Editieren von Emacs Lisp zur Verfügung stehen. Emacs + versucht dies normalerweise anhand des Dateinamens + auszumachen, was vielleicht bei + <filename>.emacs</filename> nicht funktionieren + könnte.</para> + </listitem> + + <listitem> + <para>Die <keysym>Tab</keysym>-Taste ist in manchen Modi + an die Einrückungsfunktion gebunden, so daß + beim drücken dieser Taste die aktuelle Zeile + eingerückt wird. Wenn Sie ein + <token>tab</token>-Zeichen in einen Text, welchen auch + immer Sie dabei schreiben, einfügen wollen, + müssen Sie bei gedrückter + <keysym>Strg</keysym>-Taste die <keysym>Tab</keysym>-Taste + drücken.</para> + </listitem> + + <listitem> + <para>Diese Datei unterstützt Syntax Highlighting + fü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ächsten + Kompilierungsfehler zu springen; wir definieren eine + komplementäre Funktion + <function>previous-error</function>, die es uns erlaubt, + mittels <command>M-p</command> von einem zum vorherigen + Kompilierungsfehler zu springen. Das schönste Feature + von allen ist, daß mittels <command>C-c + C-c</command> die Quelltextdatei, in der der Fehler + aufgetreten ist, geöffnet und die betreffende Zeile + direkt angesprungen wird.</para> + </listitem> + + <listitem> + <para>Wir aktivieren die Möglichkeit von Emacs als + Server zu agieren, so daß wenn Sie etwas + außerhalb von Emacs machen und eine Datei editieren + möchten, Sie einfach das folgende eingeben + können</para> + + <screen>&prompt.user; <userinput>emacsclient <replaceable>filename</replaceable></userinput> + </screen> + + <para>und dann die Datei in Ihrem Emacs editieren + können! + + <footnote> + <para>Viele Emacs-Benutzer setzen Ihre + <envar>EDITOR</envar>-Umgebungsvariable auf + <literal>emacsclient</literal>, so daß dies + immer passiert, wenn sie eine Datei editieren + mü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-<") +(global-set-key [C-end] "\M->") +(global-set-key [C-prior] "\M-<") +(global-set-key [C-next] "\M->") + +;; Mouse +(global-set-key [mouse-3] 'imenu) + +;; Misc +(global-set-key [C-tab] "\C-q\t") ; Control tab quotes a tab. +(setq backup-by-copying-when-mismatch t) + +;; Treat 'y' or <CR> as yes, 'n' as no. +(fset 'yes-or-no-p 'y-or-n-p) +(define-key query-replace-map [return] 'act) +(define-key query-replace-map [?\C-m] 'act) + +;; Load packages +(require 'desktop) +(require 'tar-mode) + +;; Pretty diff mode +(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t) +(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t) +(autoload 'ediff-files-remote "ediff" + "Intelligent Emacs interface to diff") + +(if first-time + (setq auto-mode-alist + (append '(("\\.cpp$" . c++-mode) + ("\\.hpp$" . c++-mode) + ("\\.lsp$" . lisp-mode) + ("\\.scm$" . scheme-mode) + ("\\.pl$" . perl-mode) + ) auto-mode-alist))) + +;; Auto font lock mode +(defvar font-lock-auto-mode-list + (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode) + "List of modes to always start in font-lock-mode") + +(defvar font-lock-mode-keyword-alist + '((c++-c-mode . c-font-lock-keywords) + (perl-mode . perl-font-lock-keywords)) + "Associations between modes and keywords") + +(defun font-lock-auto-mode-select () + "Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list" + (if (memq major-mode font-lock-auto-mode-list) + (progn + (font-lock-mode t)) + ) + ) + +(global-set-key [M-f1] 'font-lock-fontify-buffer) + +;; New dabbrev stuff +;(require 'new-dabbrev) +(setq dabbrev-always-check-other-buffers t) +(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_") +(add-hook 'emacs-lisp-mode-hook + '(lambda () + (set (make-local-variable 'dabbrev-case-fold-search) nil) + (set (make-local-variable 'dabbrev-case-replace) nil))) +(add-hook 'c-mode-hook + '(lambda () + (set (make-local-variable 'dabbrev-case-fold-search) nil) + (set (make-local-variable 'dabbrev-case-replace) nil))) +(add-hook 'text-mode-hook + '(lambda () + (set (make-local-variable 'dabbrev-case-fold-search) t) + (set (make-local-variable 'dabbrev-case-replace) t))) + +;; C++ and C mode... +(defun my-c++-mode-hook () + (setq tab-width 4) + (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent) + (define-key c++-mode-map "\C-ce" 'c-comment-edit) + (setq c++-auto-hungry-initial-state 'none) + (setq c++-delete-function 'backward-delete-char) + (setq c++-tab-always-indent t) + (setq c-indent-level 4) + (setq c-continued-statement-offset 4) + (setq c++-empty-arglist-indent 4)) + +(defun my-c-mode-hook () + (setq tab-width 4) + (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent) + (define-key c-mode-map "\C-ce" 'c-comment-edit) + (setq c-auto-hungry-initial-state 'none) + (setq c-delete-function 'backward-delete-char) + (setq c-tab-always-indent t) +;; BSD-ish indentation style + (setq c-indent-level 4) + (setq c-continued-statement-offset 4) + (setq c-brace-offset -4) + (setq c-argdecl-indent 0) + (setq c-label-offset -4)) + +;; Perl mode +(defun my-perl-mode-hook () + (setq tab-width 4) + (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent) + (setq perl-indent-level 4) + (setq perl-continued-statement-offset 4)) + +;; Scheme mode... +(defun my-scheme-mode-hook () + (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent)) + +;; Emacs-Lisp mode... +(defun my-lisp-mode-hook () + (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent) + (define-key lisp-mode-map "\C-i" 'lisp-indent-line) + (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp)) + +;; Add all of the hooks... +(add-hook 'c++-mode-hook 'my-c++-mode-hook) +(add-hook 'c-mode-hook 'my-c-mode-hook) +(add-hook 'scheme-mode-hook 'my-scheme-mode-hook) +(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook) +(add-hook 'lisp-mode-hook 'my-lisp-mode-hook) +(add-hook 'perl-mode-hook 'my-perl-mode-hook) + +;; Complement to next-error +(defun previous-error (n) + "Visit previous compilation error message and corresponding source code." + (interactive "p") + (next-error (- n))) + +;; Misc... +(transient-mark-mode 1) +(setq mark-even-if-inactive t) +(setq visible-bell nil) +(setq next-line-add-newlines nil) +(setq compile-command "make") +(setq suggest-key-bindings nil) +(put 'eval-expression 'disabled nil) +(put 'narrow-to-region 'disabled nil) +(put 'set-goal-column 'disabled nil) +(if (>= emacs-major-version 21) + (setq show-trailing-whitespace t)) + +;; Elisp archive searching +(autoload 'format-lisp-code-directory "lispdir" nil t) +(autoload 'lisp-dir-apropos "lispdir" nil t) +(autoload 'lisp-dir-retrieve "lispdir" nil t) +(autoload 'lisp-dir-verify "lispdir" nil t) + +;; Font lock mode +(defun my-make-face (face color &optional bold) + "Create a face from a color and optionally make it bold" + (make-face face) + (copy-face 'default face) + (set-face-foreground face color) + (if bold (make-face-bold face)) + ) + +(if (eq window-system 'x) + (progn + (my-make-face 'blue "blue") + (my-make-face 'red "red") + (my-make-face 'green "dark green") + (setq font-lock-comment-face 'blue) + (setq font-lock-string-face 'bold) + (setq font-lock-type-face 'bold) + (setq font-lock-keyword-face 'bold) + (setq font-lock-function-name-face 'red) + (setq font-lock-doc-string-face 'green) + (add-hook 'find-file-hooks 'font-lock-auto-mode-select) + + (setq baud-rate 1000000) + (global-set-key "\C-cmm" 'menu-bar-mode) + (global-set-key "\C-cms" 'scroll-bar-mode) + (global-set-key [backspace] 'backward-delete-char) + ; (global-set-key [delete] 'delete-char) + (standard-display-european t) + (load-library "iso-transl"))) + +;; X11 or PC using direct screen writes +(if window-system + (progn + ;; (global-set-key [M-f1] 'hilit-repaint-command) + ;; (global-set-key [M-f2] [?\C-u M-f1]) + (setq hilit-mode-enable-list + '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode + scheme-mode) + hilit-auto-highlight nil + hilit-auto-rehighlight 'visible + hilit-inhibit-hooks nil + hilit-inhibit-rebinding t) + (require 'hilit19) + (require 'paren)) + (setq baud-rate 2400) ; For slow serial connections + ) + +;; TTY type terminal +(if (and (not window-system) + (not (equal system-type 'ms-dos))) + (progn + (if first-time + (progn + (keyboard-translate ?\C-h ?\C-?) + (keyboard-translate ?\C-? ?\C-h))))) + +;; Under UNIX +(if (not (equal system-type 'ms-dos)) + (progn + (if first-time + (server-start)))) + +;; Add any face changes here +(add-hook 'term-setup-hook 'my-term-setup-hook) +(defun my-term-setup-hook () + (if (eq window-system 'pc) + (progn +;; (set-face-background 'default "red") + ))) + +;; Restore the "desktop" - do this as late as possible +(if first-time + (progn + (desktop-load-default) + (desktop-read))) + +;; Indicate that this file has been read at least once +(setq first-time nil) + +;; No need to debug anything now + +(setq debug-on-error nil) + +;; All done +(message "All done, %s%s" (user-login-name) ".") + </programlisting> + </example> + </sect2> + + <sect2> + <title>Erweitern des von Emacs unterstützten Sprachbereichs</title> + + <para>Das ist jetzt alles sehr schön wenn Sie + ausschließlich in einer der Sprachen programmieren + wollen, um die wir uns bereits in der + <filename>.emacs</filename>-Datei gekü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ß festgestellt werden, ob whizbang mit + irgendwelchen Dateien daherkommt, die Emacs etwas über + die Sprache sagen. Diese enden üblicherweise auf + <filename>.el</filename>, der Kurzform für <quote>Emacs + Lisp</quote>. Falls whizbang zum Beispiel ein FreeBSD Port + ist, kö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ö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ächstes müssen wir festlegen, welche + Dateiendung Quelltextdateien für whizbang haben. Lassen + Sie uns um der Argumente Willen annehmen, die Dateiendung sei + <filename>.wiz</filename>. Wir müssen dann einen Eintrag + unserer <filename>.emacs</filename>-Datei hinzufügen um + sicherzustellen, daß 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ügen Sie an + dieser Stelle eine Zeile wie folgt für whizbang + hinzu:</para> + + <programlisting><lineannotation>…</lineannotation> +("\\.lsp$" . lisp-mode) +("\\.wiz$" . whizbang-mode) +("\\.scm$" . scheme-mode) +<lineannotation>…</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ötigt wird. Falls es + weitere Dinge gibt, die automatisch beim Öffnen einer + <filename>.wiz</filename>-Datei ausgeführt werden sollen, + können Sie einen <function>whizbang-mode + hook</function>-Eintrag hinzufügen (für ein + einfaches Beispiel, welches <function>auto-indent</function> + hinzufügt, sehen Sie sich bitte + <function>my-scheme-mode-hook</function> an).</para> + </sect2> + </sect1> + + <sect1 id="tools-reading"> + <title>Weiterführende Literatur</title> + + <para>Fü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: +--> |