2635 lines
95 KiB
XML
2635 lines
95 KiB
XML
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
|
|
<!--
|
|
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>
|