doc/fr_FR.ISO8859-1/articles/programming-tools/article.sgml
Gabor Kovesdan 44ff87d9fa - Expand character entities in the French documentation
Approved by:	doceng (implicit)
2012-08-09 22:39:25 +00:00

2001 lines
100 KiB
XML
Executable file

<?xml version="1.0" encoding="ISO8859-1" standalone="no"?>
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V4.2-Based Extension//EN"
"../../../share/sgml/freebsd42.dtd" [
<!ENTITY % entities PUBLIC "-//FreeBSD//ENTITIES DocBook FreeBSD Entity Set//FR" "../../share/sgml/entities.ent">
%entities;
]>
<!--
The FreeBSD Documentation Project
The FreeBSD French Documentation Project
$FreeBSD$
Original revision: n.nn
-->
<article lang="fr">
<articleinfo>
<title>Les outils de développement sous FreeBSD : Guide de
l'utilisateur</title>
<authorgroup>
<author>
<firstname>James</firstname>
<surname>Raynard</surname>
<affiliation>
<address>
<email>jraynard@freebsd.org</email>
</address>
</affiliation>
</author>
</authorgroup>
<pubdate>$FreeBSD$</pubdate>
<releaseinfo>$FreeBSD$</releaseinfo>
<abstract>
<para>17 Août 1997</para>
<para>Copyright &copy; James Raynard, 1997.</para>
<para>Ce document est une introduction &agrave; l'utilisation de
quelques-uns des outils de programmation fournis avec FreeBSD,
quoique l'essentiel reste aussi valable pour de nombreuses autres
versions d'Unix. Il ne cherche <emphasis>pas</emphasis> &agrave;
expliquer en détail comment coder. La plus grande partie du
document suppose que vous n'avez aucune ou peu de notions
préalables de programmation, bien que l'on espère
que la plupart des programmeurs y trouveront quelque chose qui leur
sera utile.</para>
&trans.a.haby;
</abstract>
</articleinfo>
<sect1>
<title>Introduction<anchor id="foo"/></title>
<para>FreeBSD fournit un excellent environnement de développement.
Le système de base comprend des compilateurs C, C++ et Fortran,
et un assembleur, pour ne pas mentionner l'interpréteur Perl et
les outils Unix classiques comme <command>sed</command> et
<command>awk</command>. Si cela ne vous suffit pas, il y a beaucoup
d'autres compilateurs et interpréteurs au catalogue des logiciels
portés. FreeBSD est très largement compatible avec les
standards comme <acronym>POSIX</acronym> et <acronym>ANSI</acronym> C,
de même qu'avec son propre héritage BSD, il est donc
possible d'écrire des applications qui compilent et
s'exécutent sur une grande variété de
plates-formes.</para>
<para>Toute cette puissance, toutefois, peut submerger au premier abord,
si vous n'avez jamais auparavant écrit de programme sur une
plate-forme Unix. Ce document vise &agrave; vous aider &agrave; vous
y mettre, sans approfondir trop les questions les plus avancées.
L'intention est de vous fournir suffisamment de bases pour vous
permettre de tirer ensuite profit de la documentation.</para>
<para>La plus grande partie du document ne demande aucune ou peu de
connaissance de la programmation mais suppose une compétence de
base dans l'utilisation d'Unix et la volonté d'apprendre!</para>
</sect1>
<sect1>
<title>Introduction &agrave; la programmation</title>
<para>Un programme est une série d'instructions qui dit &agrave;
l'ordinateur de faire des choses diverses; l'instruction qu'il doit
exécuter dépend parfois de ce qui s'est passé
lorsqu'il a exécuté une instruction
précédente. Cette section vous donne un aperçu
des deux principales méthodes pour transmettre ces instructions,
ou &ldquo;commandes&rdquo; comme on les appellent. L'une est d'utiliser
un <firstterm>interpréteur</firstterm>, l'autre de se servir d'un
<firstterm>compilateur</firstterm>. Comme les langues humaines sont trop
compliquées pour être comprises sans ambiguïté
par un ordinateur, les commandes sont généralement
écrites dans l'un ou l'autre des languages spécialement
conçus &agrave; cet effet.</para>
<sect2>
<title>Interpréteurs</title>
<para>Dans le cas d'un interpréteur, le langage s'accompagne d'un
environnement, sous lequel vous tapez des commandes &agrave; son invite
et qui les exécute pour vous. Pour des programmes plus
compliqués, vous pouvez saisir les commandes dans un fichier
et le faire charger et exécuter les commandes qu'il contient par
l'interpréteur. Si quelque chose se passe mal, la plupart des
interpréteurs passeront le contrôle &agrave; un
débogueur pour vous aider &agrave; trouver l'origine du
problème.</para>
<para>Cela a l'avantage de vous permettre de voir immédiatement
le résultat de vos commandes et de corriger sur le champ vos
erreurs. Le principal inconvénient survient lorsque vous voulez
partager vos programmes avec d'autres. Il faut qu'ils aient le
même interpréteur que vous ou que vous ayez le moyen de
leur fournir cet interpréteur; il faut aussi qu'ils comprennent
comment s'en servir. Les utilisateurs peuvent aussi ne pas
apprécier de se retrouver sous un débogueur s'ils
appuient sur la mauvaise touche! Du point de vue de la performance,
les interpréteurs utilisent parfois beaucoup de mémoire
et ne génèrent habituellement pas le code aussi
efficacement que les compilateurs.</para>
<para>A mon avis, les langages interprétés sont le meilleur
moyen de débuter si vous n'avez jamais programmé
auparavant. On trouve typiquement ce genre d'environnement avec des
langages tels que Lisp, Smalltalk, Perl et Basic. On peut aussi
avancer que le <foreignphrase>shell</foreignphrase> Unix est
lui-même un interpréteur, beaucoup écrivent en fait
avec des
procédures&nbsp;-&nbsp;<foreignphrase>scripts</foreignphrase>&nbsp;-&nbsp;pour
se faciliter le travail d'administration de leur machine. De fait,
une partie de la philosophie d'origine d'Unix était de fournir
nombre de petits programmes utilitaires qui puissent être
utilisés de concert dans des procédures pour effectuer
des tâches utiles.</para>
</sect2>
<sect2>
<title>Interpréteurs disponibles pour FreeBSD</title>
<para>Voici une liste des interpréteurs disponibles sous forme de
<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/">&ldquo;paquetages&rdquo;</ulink>
FreeBSD, accompagnée d'une brève description des langages
interprétés les plus répandus.</para>
<para>Pour vous procurer l'un de ces &ldquo;paquetages&rdquo;, il vous
suffit de cliquer sur le lien correspondant et d'exécuter
ensuite:</para>
<screen>&prompt.root; <userinput>pkg_add <replaceable>nom_du_paquetage</replaceable></userinput></screen>
<para>sous le compte super-utilisateur <username>root</username>. Il faut
bien évidemment que vous ayez un système FreeBSD 2.1.0
ou ultérieur en état de marche pour que le logiciel
fonctionne.</para>
<variablelist>
<varlistentry>
<term><acronym>BASIC</acronym></term>
<listitem>
<para>Abréviation pour &ldquo;<foreignphrase>Beginner's
All-purpose Symbolic Instruction
Code</foreignphrase>&rdquo;&nbsp;-&nbsp;code d'instructions
symbolique universel pour les débutants.
Développé dans les années 50 pour apprendre
la programmation aux étudiants des Universités et
fourni avec tout ordinateur personnel qui se respectait dans les
années 80, <acronym>BASIC</acronym> a été le
premier langage pour de nombreux programmeurs. C'est aussi la base
de <trademark>Visual Basic</trademark>.</para>
<para>L'<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/bwbasic-2.10.tgz">interpréteur
Basic Bywater</ulink> et
l'<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/pbasic-2.0.tgz">interpréteur
Basic de Phil Cockroft</ulink> (appelé auparavant
&ldquo;Rabbit Basic&rdquo;) sont disponibles sous forme de
<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/">&ldquo;paquetages&rdquo;
FreeBSD</ulink>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Lisp</term>
<listitem>
<para>Un langage développé &agrave; la fin des
années 1950 comme alternative aux langages
&ldquo;dévoreurs de nombres&rdquo; qui e&acute;taient
populaires &agrave; l'époque. Au lieu d'être
basé sur les nombres, Lisp repose sur les listes; de fait,
son nom est une abréviation pour &ldquo;<foreignphrase>List
Processing</foreignphrase>&rdquo;&nbsp;-&nbsp;traitement de
listes. Très répandu dans les milieux de l'IA
(Intelligence Artificielle).</para>
<para>Lisp est un langage très puissant et
sophistiqué, mais peut être assez lourd et
bavard.</para>
<para>FreeBSD dispose de
<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/gcl-2.0.tgz">GNU
Common Lisp</ulink> sous forme de &ldquo;paquetage&rdquo;.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Perl</term>
<listitem>
<para>Très employé par les administrateurs
système pour écrire des procédures; et
souvent aussi sur les serveurs <foreignphrase>World Wide
Web</foreignphrase> pour écrire des procédures
<acronym>CGI</acronym>.</para>
<para>La Version 4, qui est probablement encore la version la plus
largement répandue est fournie avec FreeBSD; le plus
récent
<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/perl-5.001.tgz">Perl
Version 5</ulink> est disponible sous forme de
&ldquo;paquetage&rdquo;.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Scheme</term>
<listitem>
<para>Un dialecte de Lisp qui est plutôt plus compact et plus
propre que Common Lisp. Courant dans les Universités parce
qu'il est assez facile &agrave; enseigner en premier cycle comme
langage d'initiation et présente un niveau d'abstraction
suffisant pour être utilisé pour du travail de
recherche.</para>
<para>FreeBSD offre en &ldquo;paquetages&rdquo;
l'<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/elk-3.0.tgz">Interpréteur
Scheme Elk</ulink>,
l'<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/mit-scheme-7.3.tgz">Interpréteur Scheme du MIT</ulink> et
l'<ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/scm-4e1.tgz">Interpréteur
Scheme SCM</ulink>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Icon</term>
<listitem>
<para><ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/icon-9.0.tgz">Le
langage de programmation Icon</ulink>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Logo</term>
<listitem>
<para><ulink url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/ucblogo-3.3.tgz">L'interpréteur
LOGO de Brian Harvey</ulink>.</para>
</listitem>
</varlistentry>
<varlistentry><term>Python</term>
<listitem>
<para><ulink url="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/python-1.2">Le
langage de programmation orienté objet Python</ulink>.</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2>
<title>Compilateurs</title>
<para>Les compilateurs sont assez différents. Vous écrivez
d'abord votre code dans un(des) fichiers(s) &agrave; l'aide d'un
éditeur. Vous exécutez ensuite le compilateur et voyez
s'il valide votre programme. S'il ne le compile pas, serrez les dents et
retournez sous l'éditeur. S'il le compile et vous en fait un
programme, vous pouvez l'utiliser soit &agrave; l'invite de
l'interpréteur de commande, soit en vous servant d'un
débogueur pour voir s'il fonctionne
correctement<footnote><para>Dans
le cas contraire, si vous l'exécutez sur la ligne de commande, il
peut éventuellement
planter&nbsp;-&nbsp;&ldquo;<foreignphrase>core
dump</foreignphrase>&rdquo;.</para></footnote>.</para>
<para>Ce n'est évidemment pas aussi immédiat que de se
servir d'un interpréteur. Cela vous permet cependant de faire
beaucoup de choses qui sont très difficiles ou même
irréalisables avec un interpréteur, comme écrire
du code qui interagisse étroitement avec le système
d'exploitation&nbsp;-&nbsp; ou même écrire votre propre
système d'exploitation! C'est aussi utile si vous avez besoin
d'écrire du code très efficace, parce que le compilateur
peut prendre son temps et optimiser le code, ce qui ne serait pas
acceptable d'un interpréteur. Distribuer un programme
écrit pour un compilateur est généralement plus
facile&nbsp;-&nbsp;il suffit de livrer une copie de l'exécutable,
en supposant que les destinataires aient le même système
d'exploitation que vous.</para>
<para>Les langages compilés incluent Pascal, C et C++. C et C++
sont des langages qui pardonnent assez peu, et plus adaptés aux
programmeurs plus expérimentés. Pascal, d'un autre
côté, a été conçu pour l'enseignement,
et est un assez bon langage avec lequel commencer. Malheureusement,
FreeBSD n'a aucun support pour Pascal, &agrave; l'exception d'un
convertisseur de Pascal en C, au catalogue des logiciels
portés.</para>
<para>Comme le cycle
&ldquo;édition-compilation-exécution-débogage&rdquo;
est assez fastidieux, de nombreux fournisseurs de compilateurs
commerciaux
ont produit des Environnements de Développement
Intégrés (<acronym>EDI</acronym> en abrégé).
FreeBSD ne dispose pas d'<acronym>EDI</acronym> en tant que tel; il est
cependant possible d'utiliser Emacs &agrave; cet effet. C'est
expliqué &agrave; la section <link linkend="emacs">Utiliser
Emacs comme environnement de développement</link>.</para>
</sect2>
</sect1>
<sect1>
<title>Compiler avec <command>cc</command></title>
<para>Cette section ne s'occupe que du compilateur GNU pour C et C++, qui
est fourni de base avec le système FreeBSD. Il peut être
appelé soit avec la commande <command>cc</command>, soit avec
<command>gcc</command>. Les détails de la réalisation
d'un programme avec un interpréteur varient considérablement
d'un interpréteur &agrave; l'autre, est sont
généralement bien décrits par l'aide en ligne de
l'interpréteur.</para>
<para>Une fois que vous avez écrit votre chef-d'oeuvre,
l'étape suivante consiste &agrave; le convertir en quelque chose
qui (espérons-le!) s'exécutera sous FreeBSD. Cela demande
habituellement plusieurs opérations successives, dont chacune est
confiée &agrave; un programme différent.</para>
<procedure>
<step>
<para>Pré-processer votre code source pour en éliminer les
commentaires et faire diverses autres choses, comme la substitution
des macros-instructions en C.</para>
</step>
<step>
<para>Vérifier la syntaxe de votre code pour s'assurer que vous
avez respecté les règles du langage. Si ce n'est pas le
cas, il rouspétera.</para>
</step>
<step>
<para>Convertir le code source en langage
assembleur&nbsp;-&nbsp;c'est très proche du code machine, mais
encore compréhensible par des êtres humains. C'est du
moins ce que l'on prétend<footnote><para>Pour être
rigoureusement exact, <command>cc</command> convertit le code source
en un <firstterm>P-code</firstterm> qui lui est propre, et ne
dépend pas de la machine, et non en assembleur &agrave; ce
stade.</para></footnote>.</para>
</step>
<step>
<para>Convertir le langage assembleur en code machine&nbsp;-&nbsp;oui,
nous parlons ici de bits et d'octets, de zéros et de
uns.</para>
</step>
<step>
<para>Vérifier que vous avez utilisé de façon
cohérente les fonctions et les variables globales. Si, par
exemple, vous avez appelé une fonction qui n'existe pas, il
s'en plaindra.</para>
</step>
<step>
<para>Si vous essayez de générer un programme &agrave;
partir de plusieurs fichiers de source, faire ce qu'il faut pour
les regrouper.</para>
</step>
<step>
<para>S'arranger pour produire quelque chose que le chargeur de
programmes du système pourra mettre en mémoire et
exécuter.</para>
</step>
</procedure>
<para>Le mot <firstterm>compiler</firstterm> est souvent utilisé pour
ne désigner que les étapes 1 &agrave; 4&nbsp;-&nbsp;les
autres sont appelées <firstterm>édition de
liens</firstterm>. L'étape 1 est parfois appelée
<firstterm>pré-processer</firstterm> et les étapes 3-4
<firstterm>assembler</firstterm>.</para>
<para>Heureusement, pratiquement tous ces détails vous sont
transparents, car la commande <command>cc</command> est une interface
qui gère pour vous l'appel de ces différents programmes
avec les bons arguments; taper simplement:</para>
<screen>&prompt.user; <userinput>cc foobar.c</userinput></screen>
<para>effectue la compilation de <filename>foobar.c</filename> en passant
par toutes les étapes décrites ci-dessus. Si vous avez
&agrave; compiler plus d'un fichier, faites simplement quelque chose
comme:</para>
<screen>&prompt.user; <userinput>cc foo.c bar.c</userinput></screen>
<para>Notez que la vérification syntaxique ne consiste qu'en cela:
vérifier la syntaxe. Il n'y aura pas de contrôle sur les
erreurs logiques que vous auriez commises, comme faire exécuter
au programme une boucle infinie ou utiliser un tri &agrave; bulles au lieu
d'un tri par arbre binaire<footnote><para>Au cas où vous ne le
sauriez pas, un tri par arbre binaire est une manière efficace
d'ordonner des données, ce qui n'est pas le cas du tri
&agrave; bulles.</para></footnote>.</para>
<para><command>cc</command> dispose d'une quantité d'options, qui
sont toutes décrites dans les pages de manuel. En voici
quelques-unes des plus importantes, et la façon de les
utiliser.</para>
<variablelist>
<varlistentry>
<term><option>-o <replaceable>nom_de_fichier</replaceable></option></term>
<listitem>
<para>Le nom du fichier résultat. Si vous n'utilisez pas cette
option, <command>cc</command> générera un
exécutable appelé
<filename>a.out</filename><footnote><para>Les raisons de cela se
sont perdues dans les brumes de
l'histoire.</para></footnote>.</para>
<informalexample>
<screen>&prompt.user; <userinput>cc foobar.c</userinput> <lineannotation>l'exécutable est <filename>a.out</filename></lineannotation>
&prompt.user; <userinput>cc -o foobar foobar.c</userinput> <lineannotation>l'exécutable est <filename>foobar</filename></lineannotation></screen>
</informalexample>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-c</option></term>
<listitem>
<para>Uniquement compiler le fichier, ne pas faire l'édition de
liens. Utile pour des programmes d'essai, quand vous voulez
simplement vérifier la syntaxe, ou si vous vous servez d'un
<filename>Makefile</filename>.</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -c foobar.c</userinput></screen>
</informalexample>
<para>Cela générera un <firstterm>fichier
objet</firstterm> (et non un exécutable) appelé
<filename>foobar.o</filename>. Il pourra être lié avec
d'autres fichiers objet pour constituer un exécutable.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-g</option></term>
<listitem>
<para>Crée une version débogable de l'exécutable
Le compilateur inclut alors dans l'exécutable des
informations de correspondance entre les numéros de ligne du
fichier source et les fonctions appelées. Un débogueur
peut alors utiliser ces informations pour vous afficher le code
source tandis que vous exécutez pas &agrave; pas le
programme, ce qui est <emphasis>très</emphasis> utile;
l'inconvénient est que toutes ces informations augmentent
considérablement la taille du programme. Normalement, vous
compilez avec <option>-g</option> quand vous développez le
programme, et compilez ensuite une &ldquo;version de
livraison&rdquo; quand vous êtes satisfait parce qu'il
fonctionne correctement.</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -g foobar.c</userinput></screen>
</informalexample>
<para>Cela produira une version débogable du
programme<footnote><para>Remarquez que nous n'avons pas
utilisé l'indicateur <option>-o</option> pour préciser
le nom de l'exécutable, celui-ci s'appellera donc
<filename>a.out</filename>. Générer une version
débogable appelée <filename>foobar</filename> est
laissé &agrave; titre d'exercice aux soins du
lecteur!</para></footnote>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-O</option></term>
<listitem>
<para>Génère une version optimisée de
l'exécutable. Le compilateur effectue alors diverses
opérations bien pensées pour essayer de construire
un programme qui aille plus vite que normalement. Vous pouvez
faire suivre <option>-O</option> d'un nombre pour demander un
degré plus important d'optimisation, mais cela met souvent
en évidence des bogues dans l'optimiseur du compilateur.
Par exemple, on sait que la version de <command>cc</command> de
FreeBSD 2.1.0 produit du code incorrect avec l'option
<option>-O2</option> dans certaines circonstances.</para>
<para>On n'active en général l'optimisation
qu'&agrave; la compilation de la version de livraison.</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -O -o foobar foobar.c</userinput></screen>
</informalexample>
<para>Cela construira une version optimisée de
<filename>foobar</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
<para>Les trois indicateurs suivants demanderont &agrave;
<command>cc</command> de vérifier que votre code est conforme
&agrave; la norme internationale, souvent appelée norme
<acronym>ANSI</acronym>, bien que ce soit &agrave; proprement parler
une norme <acronym>ISO</acronym>.</para>
<variablelist>
<varlistentry>
<term><option>-Wall</option></term>
<listitem>
<para>Active tous les messages d'avertissement que les auteurs du
compilateur <command>cc</command> ont jugés
intéressants. Malgré son nom
(&ldquo;<foreignphrase>all</foreignphrase>&rdquo;&nbsp;-&nbsp;tous),
cela n'active pas tous les messages d'avertissement dont le
compilateur est capable.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-ansi</option></term>
<listitem>
<para>Désactive la plupart, mais pas toutes, les
possibilités non-<acronym>ANSI</acronym>&nbsp;C fournies par
<command>cc</command>. Malgré son nom, cela ne garantit pas
absolument que votre code soit conforme &agrave; la norme.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-pedantic</option></term>
<listitem>
<para>Désactive <emphasis>toutes</emphasis> les
possibilités non-<acronym>ANSI</acronym>&nbsp;C de
<command>cc</command>.</para>
</listitem>
</varlistentry>
</variablelist>
<para>Sans ces indicateurs, <command>cc</command> vous permet d'utiliser
ses extensions non-standard de la norme. Quelques-unes sont très
utiles, mais ne se retrouveront pas sur d'autres
compilateurs&nbsp;-&nbsp;de fait, l'un des objectifs principaux de la
norme est de permettre l'écriture de code qui puissent être
réutilisé avec n'importe quel compilateur sur n'importe
quel système. C'est cela que l'on appelle du <firstterm>code
portable</firstterm>.</para>
<para>En général, vous devriez vous efforcer de rendre votre
code aussi portable que possible, sans quoi vous risquez de devoir
récrire entièrement votre programme par la suite
pour qu'il fonctionne ailleurs&nbsp;-&nbsp;et qui peut dire ce que vous
utiliserez dans quelques années?</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
</informalexample>
<para>Cela générera un exécutable
<filename>foobar</filename> après avoir vérifié que
<filename>foobar.c</filename> respecte la norme.</para>
<variablelist>
<varlistentry>
<term><option>-l<replaceable>bibliothèque</replaceable></option></term>
<listitem>
<para>Définit une bibliothèque de fonctions &agrave;
utiliser pour l'édition de liens.</para>
<para>L'exemple le plus courant est la compilation d'un programme
qui utilise certaines des fonctions mathématiques de C. A
l'inverse de la plupart des autres plates-formes, ces fonctions
sont dans une bibliothèque différente de la
bibliothèque C standard et vous devez préciser au
compilateur qu'il doit l'utiliser.</para>
<para>La règle est que si la bibliothèque s'appelle
<filename>lib<replaceable>quelque_chose</replaceable>.a</filename>,
vous donnez &agrave; <command>cc</command> l'argument
<option>-l<replaceable>quelque_chose</replaceable></option>. Par
exemple, la bibliothèque mathématique s'appelle
<filename>libm.a</filename>, vous donnez donc &agrave;
<command>cc</command> l'argument <option>-lm</option>. Un
détail &agrave; connaître &agrave; propos de la
bibliothèque mathématique est que ce doit
généralement être la dernière sur
la ligne de commande.</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput></screen>
</informalexample>
<para>Cela ajoutera &agrave; l'édition de liens de
<filename>foobar</filename> des fonctions de la
bibliothèque mathématique.</para>
<para>Si vous compilez du code C++, vous devrez ajouter
<option>-lg++</option>, ou <option>-lstdc++</option> si vous
utilisez la version 2.2 de FreeBSD ou une version
ultérieure, &agrave; la ligne de commande pour
éditer les liens avec les fonctions de la
bibliothèque C++. Au lieu de cela, vous pouvez utiliser la
commande <command>c++</command> au lieu de <command>cc</command>,
qui fera la même chose &agrave; votre place. Sous FreeBSD,
<command>c++</command> peut aussi être appelé avec
<command>g++</command>.</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>Avec FreeBSD 2.1.6 et antérieurs</lineannotation>
&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>Avec FreeBSD 2.2 et ultérieurs</lineannotation>
&prompt.user; <userinput>c++ -o foobar foobar.cc</userinput></screen>
</informalexample>
<para>Chacun de ces exemples construira un exécutable
<filename>foobar</filename> &agrave; partir du fichier source C++
<filename>foobar.cc</filename>. Remarquez que, sur les
systèmes Unix, les fichiers sources C++ ont
traditionnellement l'extension <filename>.C</filename>,
<filename>.cxx</filename> ou <filename>.cc</filename>,
plutôt que l'extension <filename>.cpp</filename>
de sytle <trademark>MS-DOS</trademark> (qui est déj&agrave;
utilisée pour autre chose). <command>gcc</command> se
fiait autrefois &agrave; l'extension pour savoir quel type de
compilateur utiliser avec le fichier source, mais cette
restriction ne s'applique plus, vous pouvez donc appeler vos
fichiers C++ <filename>.cpp</filename> en toute
impunité!</para>
</listitem>
</varlistentry>
</variablelist>
<sect2>
<title>Questions et problèmes <command>cc</command></title>
<para>Q. J'essaie d'écrire un programme qui utilise la fonction
<function>sin()</function> et j'obtiens une erreur qui ressemble
&agrave; ce qui suit. Qu'est-ce que cela veut dire?
<informalexample>
<screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment</screen>
</informalexample>
</para>
<para>R. Quand vous utilisez des fonctions mathématiques telles
que <function>sin()</function>, vous devez dire &agrave;
<command>cc</command> d'inclure la bibliothèque
mathématique &agrave; l'édition de liens, comme ceci:
<informalexample>
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput></screen>
</informalexample></para>
<para>Q. D'accord, j'ai écrit ce petit programme pour
m'entraîner &agrave; utiliser <option>-lm</option>. Il ne fait
que calculer 2.1 &agrave; la puissance 6:
<informalexample>
<programlisting>
#include &lt;stdio.h&gt;
int main() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;float f;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f = pow(2.1, 6);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("2.1 ^ 6 = %f\n", f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}
</programlisting>
</informalexample>
et l'ai compilé comme ceci:
<informalexample>
<screen>&prompt.user; <userinput>cc temp.c -lm</userinput></screen>
</informalexample>
comme vous avez dit qu'il fallait le faire, mais voil&agrave; ce que
j'obtiens &agrave; l'exécution:
<informalexample>
<screen>&prompt.user; <userinput>./a.out</userinput>
2.1 ^ 6 = 1023.000000</screen>
</informalexample></para>
<para>Ce n'est <emphasis>pas</emphasis> la bonne réponse! Que se
passe-t-il?</para>
<para>R. Quand le compilateur voit que vous appelez une fonction, il
regarde s'il en a déj&agrave; vu un prototype. Si ce n'est pas
le cas, il suppose que la fonction retourne un
<type>int</type>&nbsp;-&nbsp;<foreignphrase>entier</foreignphrase>, ce
qui n'est évidemment pas ce que vous souhaitez dans ce
cas.</para>
<para>Q. Comment alors régler ce problème?</para>
<para>R. Les prototypes des fonctions mathématiques sont dans
<filename>math.h</filename>. Si vous incluez ce fichier, le
compilateur trouvera le prototype et cessera de vous fournir un
résultat bizarre!
<informalexample>
<programlisting>
#include &lt;math.h&gt;
#include &lt;stdio.h&gt;
int main() {
...
</programlisting>
</informalexample>
</para>
<para>Après l'avoir recompilé de la même
façon qu'auparavant, exécutez-le:
<informalexample>
<screen>&prompt.user; <userinput>./a.out</userinput>
2.1 ^ 6 = 85.766121</screen>
</informalexample>
</para>
<para>Si vous utilisez la moindre fonction mathématique, incluez
<emphasis>toujours</emphasis> <filename>math.h</filename> et n'oubliez
pas d'utiliser la bibliothèque mathématique &agrave;
l'édition de liens.</para>
<para>Q. J'ai compilé un fichier appelé
<filename>foobar.c</filename> et je ne trouve pas d'exécutable
appelé <filename>foobar</filename>. Où est-il
passé?</para>
<para>R. N'oubliez pas, <command>cc</command> appellera
l'exécutable <filename>a.out</filename> &agrave; moins que vous
ne lui disiez de faire autrement. Utilisez l'option
<option>-o&nbsp;<replaceable>nom_de_fichier</replaceable></option>:
<informalexample>
<screen>&prompt.user; <userinput>cc -o foobar foobar.c</userinput></screen>
</informalexample>
</para>
<para>Q. OK, si j'ai un exécutable appelé
<filename>foobar</filename>, je le vois avec <command>ls</command>,
mais quand je tape <command>foobar</command> sur la ligne de commande,
il me dit que le fichier n'existe pas. Pourquoi ne le trouve-t-il
pas?</para>
<para>R. A l'inverse de <trademark>MS-DOS</trademark>, Unix ne regarde
pas dans le répertoire courant quand il cherche le programme
que vous voulez exécuter, &agrave; moins que vous ne le lui
disiez. Soit tapez <command>./foobar</command>, ce qui veut dire
&ldquo;exécuter le fichier appelé
<filename>foobar</filename> du répertoire courant&rdquo;, ou
modifiez votre variable d'environnement
<envar>PATH</envar> pour qu'elle ressemble
&agrave;:
<informalexample>
<screen>bin:/usr/bin:/usr/local/bin:.</screen>
</informalexample>
Le dernier point signifie &ldquo;chercher dans le répertoire
courant si le fichier n'est pas dans les autres
répertoires&rdquo;.</para>
<para>Q. J'ai appelé mon exécutable
<filename>test</filename>, mais il ne se passe rien quand je le
lance. Pourquoi?</para>
<para>R. Il y a un programme appelé <command>test</command> dans
<filename>/usr/bin</filename> sur la plupart des systèmes Unix
et c'est celui-l&agrave; que trouve l'interpréteur de commandes
avant de regarder dans le répertoire courant. Soit tapez:
<informalexample>
<screen>&prompt.user; <userinput>./test</userinput></screen>
</informalexample>
ou choisissez un meilleur nom pour votre programme!</para>
<para>Q. J'ai compilé et tout a commencé &agrave;
fonctionner correctement, puis il y a eu une erreur et il m'a dit
quelque chose &agrave; propos de <errorname>core dumped</errorname>.
Qu'est-ce que cela veut dire?</para>
<para>A. L'expression <firstterm>core dump</firstterm> date des tous
premiers jours d'Unix, quand les machines utilisaient la
mémoire
centrale&nbsp;-&nbsp;&ldquo;<foreignphrase>core memory</foreignphrase>&rdquo;
pour stocker les informations. Essentiellement, si le programme
&ldquo;plantait&rdquo; dans certaines conditions, le système
enregistrait sur disque le contenu de la mémoire centrale
dans un fichier appelé <filename>core</filename>, que le
programmeur pouvait ensuite disséquer pour trouver
où les choses avaient mal tournées.</para>
<para>Q. Fascinant, mais que suis-je censé faire
maintenant?</para>
<para>A. Servez-vous de <command>gdb</command> pour analyser l'image
mémoire (Reportez-vous &agrave; la section
<link linkend="debugging">Déboguer</link>).</para>
<para>R. Quand mon programme a généré une image
mémoire, il a dit quelque chose &agrave; propose de
<errorname>segmentation fault</errorname>&nbsp;-&nbsp;&ldquo;erreur
de segmentation&rdquo;. Qu'est-ce que c'est?</para>
<para>Q. Cela signifie essentiellement que votre programme a
essayé d'effectuer une quelconque opération
illégale sur la mémoire; Unix est conçu pour
protéger le système d'exploitation des programmes
mal éduqués.</para>
<para>Les raisons les plus courantes en sont:
<itemizedlist>
<listitem>
<para>Essayer d'écrire en mémoire adressée par
un pointeur <symbol>NULL</symbol>, e.g.:
<programlisting>
char *foo = NULL;
strcpy(foo, "bang!");
</programlisting>
</para>
</listitem>
<listitem>
<para>Utiliser un pointeur qui n'a pas été
initialisé, e.g.:
<programlisting>
char *foo;
strcpy(foo, "bang!");
</programlisting>
Le pointeur aura une valeur aléatoire qui, avec de la
chance, adressera une zone mémoire non accessible &agrave;
votre programme, de sorte que le noyau tuera ce dernier avant
qu'il ne provoque de dégât. Si vous manquez de chance,
il pointera quelque part &agrave; l'intérieur de votre
programme et endommagera l'une de vos structures de
données, provoquant un dysfonctionnement mystérieux
de votre programme.</para>
</listitem>
<listitem>
<para>Tenter d'accéder au-del&agrave; du dernier
élément d'un tableau, e.g.:
<programlisting>
int bar[20];
bar[27] = 6;
</programlisting>
</para>
</listitem>
<listitem>
<para>Essayer d'enregistrer quelque chose dans une zone de
mémoire accessible en lecture seule, e.g.:
<programlisting>
char *foo = "Mon texte";
strcpy(foo, "bang!");
</programlisting>
Les compilateurs Unix stockent souvent les chaînes de
caractères constantes comme <literal>"Mon texte"</literal>
en mémoire accessible en lecture seule.</para>
</listitem>
<listitem>
<para>Utiliser incorrectement les fonctions
<function>malloc()</function> et <function>free()</function>,
e.g.:
<programlisting>
char bar[80];
free(bar);
</programlisting>
ou:
<programlisting>
char *foo = malloc(27);
free(foo);
free(foo);
</programlisting>
</para>
</listitem>
</itemizedlist>
</para>
<para>Commettre l'une de ces fautes ne provoquera pas toujours une erreur,
mais ce sont malgré tout des choses &agrave; ne pas faire.
Certains systèmes et compilateurs sont plus tolérants que
d'autres, ce qui fait que des programmes qui s'exécutent
correctement sur un système peuvent ne plus fonctionner sur un
autre.</para>
<para>Q. Parfois, le programme provoque la génération d'une
image mémoire avec le message <errorname>bus error</errorname>.
Mon manuel Unix dit qu'il s'agit d'un erreur matériel, mais
l'ordinateur fonctionne apparemment correctement. Est-ce vrai?</para>
<para>R. Fort heureusement, non (&agrave; moins bien sûr que vous
n'ayez aussi un problème matériel). C'est habituellement
une autre façon de dire que vous avez accédé
incorrectement &agrave; la mémoire.</para>
<para>Q. Il me semble que cette histoire de <foreignphrase>core
dump</foreignphrase> peut être très utile, si je peux la
provoquer quand je veux. Est-ce possible, ou dois-je attendre qu'il se
produise une erreur?</para>
<para>R. Oui, allez simplement sur une autre console ou fenêtre
<application>xterm</application> et tapez:
<screen>&prompt.user; <userinput>ps</userinput></screen> pour
connaître l'IDentifiant de processus de votre programme, puis:
<screen>&prompt.user; <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
<parameter><replaceable>pid</replaceable></parameter> est
l'ID de processus que vous avez recherché.</para>
<para>C'est par exemple utile si votre programme est parti dans une boucle
infinie. Au cas où votre programme piégerait les
interruptions <symbol>SIGABRT</symbol>, il y a plusieurs autres signaux
qui auront le même effet.</para>
</sect2>
</sect1>
<sect1>
<title>Make</title>
<sect2>
<title>Qu'est-ce que <command>make</command>?</title>
<para>Lorsque vous travaillez sur un programme simple avec seulement un
ou deux fichiers de source, taper:
<screen>&prompt.user; <userinput>cc fichier1.c fichier2.c</userinput></screen>
n'est pas trop gênant, mais cela devient rapidement très
fastidieux lorsqu'il y a plusieurs fichiers&nbsp;-&nbsp;et cela peut
aussi mettre du temps &agrave; compiler.</para>
<para>Un façon d'éviter ces problèmes est
d'utiliser des fichiers <firstterm>objets</firstterm> et de ne
recompiler que les fichiers de source dont le contenu a changé.
Nous pourrions alors avoir quelque chose du style:
<screen>&prompt.user; <userinput>cc fichier1.o fichier2.o</userinput> &hellip; <userinput>file37.c</userinput> &hellip;</screen>
si nous avons modifé <filename>fichier37.c</filename>, et
celui-l&agrave; uniquement, depuis notre compilation
précédente. Cela peut sérieusement
accélérer la compilation, mais ne résout pas le
problème de saisie &agrave; répétition de la
commande.</para>
<para>Nous pourrions aussi écrire une procédure pour
résoudre ce dernier problème, mais ne ne pourrions alors
que lui faire tout recompiler, ce qui serait très peu efficace
sur un gros projet.</para>
<para>Que ce passe-t-il si nous avons des centaines de fichiers de
sources? Si nous travaillons en équipe et que d'autres
oublient de nous prévenir des modifications qu'ils ont
apportées &agrave; un des fichiers que nous utilisons?</para>
<para>Peut-être pourrions-nous rassembler les deux solutions et
écrire quelque chose qui ressemble &agrave; une
procédure et comporte une sorte de règle magique
qui dise quand tel fichier de source doit être compilé.
Nous n'aurions plus besoin que d'un programme qui comprennent ces
règles, parce que c'est un peu trop compliqué pour une
procédure.</para>
<para>Ce programme s'appelle <command>make</command>. Il lit un fichier,
qu'on appelle un <firstterm>makefile</firstterm>, qui lui dit quelles
sont les dépendances entre les différents fichiers, et
en déduit lesquels ont besoin ou non d'être
recompilés. Par exemple, une règle peut signifier
quelque chose comme &ldquo;si <filename>fromboz.o</filename> est plus
ancien que <filename>fromboz.c</filename>, cela veut dire que
<filename>fromboz.c</filename> doit avoir été
modifié, il faut donc le recompiler&rdquo;. Le fichier
&ldquo;<foreignphrase>makefile</foreignphrase>&rdquo; inclut aussi
des règles qui lui disent <emphasis>comment</emphasis>
recompiler, ce qui en fait un outil encore plus puissant.</para>
<para>Ces fichiers &ldquo;makefiles&rdquo; sont habituellement
rangés dans le même répertoire que les sources
auxquels ils s'appliquent, et peuvent être appelés
<filename>makefile</filename>, <filename>Makefile</filename> ou
<filename>MAKEFILE</filename>. La plupart des programmeurs utilisent
le nom <filename>Makefile</filename>, ce qui fait qu'ils se trouvent
alors vers le début de la liste des fichiers et sont ainsi
facilement repérables <footnote><para>Ils n'utilisent pas la
variante <filename>MAKEFILE</filename> parce que les noms en
majuscules servent souvent &agrave; désigner les fichiers de
documentation comme
<filename>README</filename>.</para></footnote>.</para>
</sect2>
<sect2>
<title>Exemple d'utilisation de <command>make</command></title>
<para>Voici un fichier <filename>Makefile</filename>
élémentaire :
<programlisting>
foo: foo.c
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cc -o foo foo.c
</programlisting>
Il contient deux lignes, une pour la dépendance et une
pour la génération.</para>
<para>La ligne décrivant la dépendance contient le
nom du programme (qu'on appelle la <firstterm>cible</firstterm>),
suivi de &ldquo;deux points&rdquo;, puis d'un blanc et du nom
du fichier source. Quand <command>make</command> lit cette ligne,
il regarde si <filename>foo</filename> existe; s'il existe, il
compare la date de dernière modification de
<filename>foo</filename> &agrave; celle de dernière
modification de <filename>foo.c</filename>. Si
<filename>foo</filename> n'existe pas, ou s'il est antérieur
&agrave; <filename>foo.c</filename>, il regarde alors la ligne de
génération pour savoir ce qu'il faut faire. En
d'autres termes, c'est la règle &agrave; appliquer pour
savoir si <filename>foo.c</filename> doit être
recompilé.</para>
<para>La ligne de génération commence par une
<token>tabulation</token> (appuyez sur la touche
<keycap>Tab</keycap>) suivie de la commande que vous taperiez
pour compiler <filename>foo</filename> si vous le faisiez sur
la ligne de commande. Si <filename>foo</filename> n'est pas
&agrave; jour ou s'il n'existe pas, <command>make</command>
exécute alors cette commande pour le créer. En
d'autres termes, c'est la règle qui dit &agrave;
<command>make</command> comment recompiler
<filename>foo.c</filename>.</para>
<para>Ainsi, quand vous tapez <userinput>make</userinput>, il
fera en sorte que <filename>foo</filename> soit en phase avec les
dernières modifications que vous avez apportées &agrave;
<filename>foo.c</filename>. Ce principe s'étend aux
<filename>Makefile</filename>s avec des centaines de
cibles&nbsp;-&nbsp;de fait, sur FreeBSD, il est possible de compiler
tout le système d'exploitation en tapant simplement
<userinput>make world</userinput> dans le répertoire
adéquat!</para>
<para>Une autre particularité de <filename>Makefile</filename>s
est que les cibles ne sont pas nécessairement des programmes.
Nous pourrions par exemple avoir le <filename>Makefile</filename>
suivant:
<programlisting>
foo: foo.c
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cc -o foo foo.c
install:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cp foo /home/me
</programlisting>
</para>
<para>Nous pouvons dire &agrave; <command>make</command> quelle cible
nous voulons atteindre en tapant:
<screen>&prompt.user; <userinput>make <replaceable>cible</replaceable></userinput></screen>
<command>make</command> examinera alors cette cible et ignorera
toutes les autres. Par exemple, si, avec le
<filename>Makefile</filename> précédent, nous tapons
<userinput>make foo</userinput>, <command>make</command> ignorera
la cible <action>install</action>.</para>
<para>Si nous tapons simplement <userinput>make</userinput> tout
court, il examinera toujours la première cible et
s'arrêtera ensuite sans s'occuper des autres. Si nous
avions tapé <userinput>make</userinput> dans ce cas, il
serait simplement allé &agrave; la cible
<action>foo</action>, aurait recompilé
<filename>foo</filename> si nécessaire, et se serait
arrêté sans passer &agrave; la cible
<action>install</action>.</para>
<para>Remarquez que la cible <action>install</action> ne dépend
en fait de rien du tout! Cela signifie que la commande sur la ligne
suivante est toujours exécutée si nous essayons de
reconstruire cette cible en tapant
<userinput>make install</userinput>. Dans ce cas, il copiera
<filename>foo</filename> dans le répertoire de l'utilisateur.
C'est souvent utilisé par les <filename>Makefile</filename>s
de logiciels, de sorte que l'application soit installée dans
le bon répertoire, une fois correctement
compilée.</para>
<para>C'est un point un peu délicat &agrave; expliquer. Si vous
ne comprenez pas exactement comment <command>make</command>
fonctionne, la meilleure chose &agrave; faire est d'écrire
un programme simple comme le classique &ldquo;Bonjour, le
monde!&rdquo;, un fichier <filename>Makefile</filename> et de
faire des essais. Compilez ensuite en utilisant plus d'un
fichier source, ou en ayant un fichier source qui inclut un
fichier d'en-tête. La commande <command>touch</command>
vous sera très utile&nbsp;-&nbsp;elle modifie la date
d'un fichier sans que vous ayez &agrave; l'éditer.</para>
</sect2>
<sect2>
<title>Makefiles FreeBSD</title>
<para>L'écriture de <filename>Makefile</filename>s peut
être assez compliquée. Heureusement, les systèmes
basés sur BSD, comme FreeBSD, en fournissent de très
puissants, intégrés au système. Le catalogue des
logiciels portés de FreeBSD en est un excellent exemple. Voici
l'essentiel d'un de leurs <filename>Makefile</filename>s typiques:
<programlisting>
MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz
.include &lt;bsd.port.mk&gt;
</programlisting>
</para>
<para>Si nous allons maintenant dans le répertoire associé
&agrave; ce logiciel et tapons <userinput>make</userinput>, voici ce
qui se passe:</para>
<procedure>
<step>
<para>Il regarde si le code source de ce logiciel est
déj&agrave; présent sur le système.</para>
</step>
<step>
<para>S'il n'y est pas, une connexion FTP &agrave; l'URL
indiquée par <symbol>MASTER_SITES</symbol> est
établie pour télécharger le source.</para>
</step>
<step>
<para>La somme de contrôle est calculée sur le source et
comparée &agrave; celle calculée sur une version
connue et validée. Cela pour s'assurer que le source n'a
pas été corrompu pendant le transfert.</para>
</step>
<step>
<para>Les modifications nécessaires pour que le code
fonctionne sous FreeBSD sont appliquées&nbsp;-&nbsp;c'est
ce que l'on appelle <firstterm>patcher</firstterm>.</para>
</step>
<step>
<para>Les opérations particulières de configuration
du source sont effectuées. (De nombreuses distributions de
programmes Unix essayent de déterminer sur quel
système elles sont compilées et de quelles
fonctionnalités Unix optionnelles il
dispose&nbsp;-&nbsp;c'est &agrave; ce stade du scénario
d'installation de logiciels sous FreeBSD que leur sont fournies
ces informations).</para>
</step>
<step>
<para>Le code source du programme est compilé. De fait, on
passe dans le répertoire où le code a
été décompacté et
<command>make</command> y est exécuté&nbsp;-&nbsp;le
<filename>Makefile</filename> du programme lui-même contient
les informations nécessaires &agrave; sa
compilation.</para>
</step>
<step>
<para>Nous disposons maintenant d'une version compilée du
programme. Si nous le voulons, nous pouvons maintenant la tester;
si nous avons confiance dans le programme, nous pouvons taper
<userinput>make install</userinput>. Cela recopiera le programme
et tous les fichiers d'environnement dont il a besoin &agrave;
l'endroit adéquat; une entrée sera aussi
créée dans une <database>base de données des
logiciels</database>, de façon &agrave; ce qu'il puisse
être désinstallé par la suite, si nous
changeons d'avis.</para>
</step>
</procedure>
<para>Je pense que vous serez maintenant d'accord pour trouver que c'est
assez impressionnant pour une simple procédure de quatre
lignes!</para>
<para>Le secret se trouve &agrave; la dernière ligne, qui dit
&agrave; <command>make</command> d'aller voir ce qu'il y a dans le
<filename>Makefile</filename> appelé
<filename>bsd.port.mk</filename>. Il est facile de rater cette ligne,
mais c'est pourtant de l&agrave; que vient toute la mécanique
subtile. Quelqu'un a écrit un <filename>Makefile</filename>
qui dit &agrave; <command>make</command> de faire tout ce qui a
été décrit ci-dessus (plus deux ou trois autres
choses dont je n'ai pas parlé, dont le traitement des erreurs
qui pourraient se produire) et tout le monde peut l'utiliser en
mettant simplement cette unique ligne dans son propre
<filename>Makefile</filename>!</para>
<para>Si vous voulez jeter un oeil &agrave; ces
<filename>Makefile</filename>s systèmes, ils sont dans le
répertoire <filename>/usr/share/mk</filename>, mais il vaut
mieux attendre d'avoir un peu d'expérience des
<filename>Makefile</filename>s, parce qu'ils sont très
compliqués (et si vous les regardez, ayez sous la main
une bonne dose de café serré!).</para>
</sect2>
<sect2>
<title>Utilisation plus poussée de <command>make</command></title>
<para> <command>make</command> est un outil très puissant, et peut
faire beaucoup plus que l'exemple élémentaire que nous
avons donné. Il y a malheureusement plusieurs versions de
<command>make</command>, et elles sont très
différentes. La meilleure façon de savoir ce qu'elles
peuvent faire est certainement de lire la
documentation&nbsp;-&nbsp;espérons que cette introduction
vous aura fourni les bases pour le faire.</para>
<para>La version de <command>make</command> fournie avec FreeBSD est
<application>Berkeley make</application>; elle s'accompagne d'un guide
dans <filename>/usr/share/doc/psd/12.make</filename>. Pour le
visualiser, tapez:
<screen>&prompt.user; <userinput>zmore paper.ascii.gz</userinput></screen>
dans ce répertoire.</para>
<para>Il y a des nombreux logiciels du catalogue des logiciels
portés qui utilisent <application>GNU make</application>, qui
est très bien documenté dans les pages
&ldquo;info&rdquo;. Si vous avez installé un de ces logiciels,
<application>GNU make</application> sera automatiquement installé
sont le nom <command>gmake</command>. Il est aussi disponible sous forme
de logiciel porté ou précompilé autonome.</para>
<para>Pour visualiser les pages &ldquo;info&rdquo; de
<application>GNU make</application>, il vous faut éditer le
fichier <filename>dir</filename> du répertoire
<filename>/usr/local/info</filename> et y ajouter une ligne pour ce
programme. C'est une ligne du genre:
<programlisting>
* Make: (make). L'utilitaire GNU Make.
</programlisting>
Une fois que c'est fait, vous pouvez taper <userinput>info</userinput>
puis sélectionner <guimenuitem>make</guimenuitem> dans le menu
(ou sous <application>Emacs</application>, taper <userinput>C-h
i</userinput>).</para>
</sect2>
</sect1>
<sect1 id="debugging">
<title>Déboguer</title>
<sect2>
<title>Le débogueur</title>
<para>Le débogueur qui est fourni avec FreeBSD s'appelle
<command>gdb</command>
(<application>GNU débogueur</application>). Vous le lancez en
tapant:
<screen>&prompt.user; <userinput>gdb <replaceable>nom_du_programme</replaceable></userinput></screen>
bien que la plupart des gens préfèrent l'exécuter
sous <application>Emacs</application>. Ce qui se fait avec:
<screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen>
</para>
<para>Se servir d'un débogueur vous permet d'exécuter le
programme sous contrôle. Vous pouvez typiquement
l'exécuter pas &agrave; pas, inspecter les valeurs des
variables, les modifier, dire au débogueur d'exécuter
le programme jusqu'&agrave; un certain endroit et de s'y
arrêter, et ainsi de suite. Vous pouvez même
le rattacher &agrave; un programme qui est déj&agrave; en
cours d'exécution, ou charger une image
mémoire&nbsp;-&nbsp;&ldquo;<foreignphrase>core</foreignphrase>&rdquo;.
Il est même possible de déboguer le noyau, bien que cela
soit un peu plus compliqué que dans le cas des programmes
utilisateurs, dont nous parlerons dans cette section.</para>
<para><command>gdb</command> dispose d'une assez bonne aide en ligne,
ainsi que d'un jeu de pages &ldquo;info&rdquo;, cette section se
concentrera donc sur quelques commandes de base.</para>
<para>Enfin, si le mode de fonctionnement en ligne de commande vous
rebute, il existe une interface graphique appelée
<ulink url="http://www.freebsd.org/ports/devel.html">xxgdb</ulink>
au catalogue des logiciels portés.</para>
<para>Cette section est destinée &agrave; servir d'introduction
&agrave; l'utilisation du débogueur et ne couvre pas les
questions spécialisées comme le débogage du
noyau.</para>
</sect2>
<sect2>
<title>Exécuter un programme sous le débogueur</title>
<para>Il faudra que vous ayez compilé le programme avec l'option
<option>-g</option> pour tirer le meilleur parti de
<command>gdb</command>. Cela fonctionnera sans cela, mais vous ne
verrez que le nom de la fonction dans laquelle vous êtes, au
lieu du code source. Si vous avez un message du genre:
<screen>&hellip; (no debugging symbols found) &hellip;</screen>
au démarrage de <command>gdb</command>, vous saurez que le
programme n'a pas été compilé avec l'option
<option>-g</option>.</para>
<para>A l'invite de <command>gdb</command>, tapez <userinput>break
main</userinput>. Cela dira au débogueur d'exécuter le
code préliminaire de mise en oeuvre dans le programme et de
s'arrêter au début de votre programme. Tapez maintenant
<userinput>run</userinput> pour lancer le programme&nbsp;-&nbsp;il
commencera au début du code préliminaire et sera
interrompu par le débogueur sur l'appel de
<function>main()</function>. (Si vous vous étiez jamais
demandé d'où la fonction <function>main()</function>
était appelée, vous le savez maintenant!).</para>
<para>Vous pouvez maintenant exécuter le programme une ligne
&agrave; la fois, en appuyant sur <command>n</command>. Si
vous arrivez sur un appel de fonction, vous pouvez passer dans la
fonction en appuyant sur <command>s</command>. Une fois dans la
fonction, vous pouvez terminer son exécution et en sortir en
tapant <command>f</command>. Vous pouvez aussi utiliser
<command>up</command> et <command>down</command> pour jeter un
coup d'oeil au code appelant.</para>
<para>Voici un exemple simple de la manière de diagnostiquer une
erreur dans un programme avec <command>gdb</command>. Voici notre
programme (intentionnellement faux):
<programlisting>
#include &lt;stdio.h&gt;
int bazz(int un_entier);
main() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("C'est mon programme\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bazz(i);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}
int bazz(int un_entier) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Vous m'avez donné %d\n", un_entier);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return un_entier;
}
</programlisting>
</para>
<para>Ce programme affecte &agrave; <symbol>i</symbol> la valeur
<literal>5</literal> et la passe &agrave; la fonction
<function>bazz()</function> qui affiche la valeur que nous lui
donnons en paramètre.</para>
<para>Quand nous compilons et exécutons le programme, nous
obtenons:
<screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
&prompt.user; <userinput>./temp</userinput>
C'est mon programme
Vous m'avez donné 4231</screen></para>
<para>Ce n'est pas ce &agrave; quoi nous nous attendions! C'est le
moment d'aller voir ce qui ce passe!
<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>Exécuter le code d'initialisation</lineannotation>
Breakpoint 1 at 0x160f: file temp.c, line 9. <lineannotation><command>gdb</command> met un pont d'arrêt &agrave; l'appel de <function>main()</function></lineannotation>
(gdb) <userinput>run</userinput> <lineannotation>Exécuter jusqu'&agrave; <function>main()</function></lineannotation>
Starting program: /home/james/tmp/temp <lineannotation>Le programme démarre</lineannotation>
Breakpoint 1, main () at temp.c:9 <lineannotation><command>gdb</command> s'arrête &agrave; <function>main()</function></lineannotation>
(gdb) <userinput>n</userinput> <lineannotation>Aller &agrave; la ligne suivante</lineannotation>
C'est mon programme <lineannotation>Le programme imprime</lineannotation>
(gdb) <userinput>s</userinput> <lineannotation>Aller dans <function>bazz()</function></lineannotation>
bazz (un_entier=4231) at temp.c:17 <lineannotation><command>gdb</command> affiche la position dans la pile d'appel</lineannotation>
(gdb)</screen></para>
<para>Une minute! Comment <symbol>un_entier</symbol> peut-il valoir
<literal>4231</literal>? Ne l'avons-nous pas initialisé
&agrave; <literal>5</literal> dans <function>main()</function>?
Revenons &agrave; <function>main()</function> et jetons un
oeil.</para>
<para>
<screen>(gdb) <userinput>up</userinput> <lineannotation>Remonter d'un cran dans la pile d'appel</lineannotation>
#1 0x1625 in main () at temp.c:11 <lineannotation><command>gdb</command> affiche la position dans la pile d'appel</lineannotation>
(gdb) <userinput>p i</userinput> <lineannotation>Afficher la valeur de <symbol>i</symbol></lineannotation>
$1 = 4231 <lineannotation><command>gdb</command> affiche <literal>4231</literal></lineannotation></screen>
Et oui! Si nous regardons le code, nous avons oublié
d'initialiser <symbol>i</symbol>. Nous voulions mettre:
<programlisting>
<lineannotation>&hellip;</lineannotation>
main() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i = 5;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("C'est mon programme\n");
<lineannotation>&hellip;</lineannotation>
</programlisting>
mais nous avons oublié la ligne <literal>i=5;</literal>.
Comme nous n'avons pas initialisé <symbol>i</symbol>, il
prend la valeur qui se trouve &agrave; cet endroit de la
mémoire quand le programme s'exécute, dans notre
cas, il s'est trouvé que c'était
<literal>4231</literal>.</para>
<note>
<para><command>gdb</command> affiche l'endroit où nous nous
trouvons dans la pile d'appel, chaque fois que nous entrons ou
sortons d'une fonction, même si nous utilisons
<command>up</command> et <command>down</command> pour nous
déplacer dans la pile. Cela nous donne le nom de la fonction
et les valeurs de ses paramètres, ce qui nous aide &agrave;
repérer où nous sommes et ce qu'il se passe. (La pile
d'appel est une zone de mémoire où le programme
enregistre les informations sur les paramètres passés
aux fonctions et où aller quand il ressort d'un fonction
appelée.)</para>
</note>
</sect2>
<sect2>
<title>Examiner un fichier
&ldquo;<foreignphrase>core</foreignphrase>&rdquo;</title>
<para>Un fichier &ldquo;<foreignphrase>core</foreignphrase>&rdquo; est
essentiellement un fichier qui contient l'état complet du
programme au moment où il s'est &ldquo;planté&rdquo;. Au
&ldquo;bon vieux temps&rdquo;, les programmeurs devaient imprimer le
contenu en hexadécimal des fichiers
&ldquo;<foreignphrase>core</foreignphrase>&rdquo; et transpirer sur des
manuels de code machine, mais la vie est aujourd'hui un peu plus facile.
Au passage, sous FreeBSD et les autres systèmes 4.4BSD, un
fichier &ldquo;<foreignphrase>core</foreignphrase>&rdquo; s'appelle
<filename><replaceable>nom_du_programme</replaceable>.core</filename>,
et non <filename>core</filename> tout court,
de façon &agrave; ce que l'on sache &agrave; quel programme il
correspond.</para>
<para>Pour examiner un fichier
&ldquo;<foreignphrase>core</foreignphrase>&rdquo;, lancez
<command>gdb</command> comme d'habitude. Au lieu de taper
<command>break</command> ou <command>run</command>, tapez:
<screen>(gdb) <userinput>core <replaceable>nom_du_programme</replaceable>.core</userinput></screen>
Si vous n'êtes pas dans le même répertoire que
le fichier &ldquo;<foreignphrase>core</foreignphrase>&rdquo;, vous
devrez d'abord faire
<userinput>dir /ou/se/trouve/le/fichier/core</userinput>.</para>
<para>Vous devriez voir quelque chose comme:
<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 (un_entier=0x5) at temp.c:17
(gdb)</screen></para>
<para>Dans ce cas, le programme s'appelait <filename>a.out</filename>, le
fichier &ldquo;<foreignphrase>core</foreignphrase>&rdquo; s'appelle
donc <filename>a.out.core</filename>. Nous constatons que le programme
s'est terminé en erreur &agrave; cause d'une tentative
d'accès &agrave; une zone de mémoire qui n'était
pas accessible dans une fonction appelé
<function>bazz</function>.</para>
<para>Il est parfois utile de pouvoir savoir comment une fonction a
été appelée, parce que le problème peut
s'être produit bien au-dessus dans la pile d'appel dans un
programme complexe. La commande <command>bt</command> dit &agrave;
<command>gdb</command> d'imprimer en remontant la pile d'appel:
<screen>(gdb) <userinput>bt</userinput>
#0 0x164a in bazz (un_entier=0x5) at temp.c:17
#1 0xefbfd888 in end ()
#2 0x162c in main () at temp.c:11
(gdb)</screen>
La fonction <function>end()</function> est appelée quand un
programme échoue; dans le cas présent, la fonction
<function>bazz()</function> a été appelée par
<function>main()</function>.</para>
</sect2>
<sect2>
<title>Prendre le contrôle d'un programme en cours
d'exécution</title>
<para>Une des possibilités les plus intéressantes de
<command>gdb</command> est qu'il peut se rattacher &agrave; un
programme en cours d'exécution. Il faut bien sûr que vous
ayez les autorisations suffisantes pour le faire. Le cas d'un programme
qui &ldquo;fourche&rdquo;&nbsp;-&nbsp;<foreignphrase>fork</foreignphrase>&nbsp;-&nbsp;est
un problème classique, lorsque vous voulez suivre le
déroulement du processus fils, alors que le débogueur ne
vous permet que de tracer le processus père.</para>
<para>Vous lancez alors un autre <command>gdb</command>, utilisez
<command>ps</command> pour connaître l'IDentifiant de processus du
fils, puis faites:
<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
sous <command>gdb</command>, et déboguez alors comme
d'habitude.</para>
<para>&ldquo;Tout cela est bien beau&rdquo;, vous dites vous
peut-être, &ldquo;mais le temps que j'ai fait tout ça, le
processus fils aura déj&agrave; fait un bon bout de
chemin&rdquo;. Rien &agrave; craindre, aimable lecteur, voici ce
qu'il faut faire (emprunté aux pages &ldquo;info&rdquo; de
<command>gdb</command>):
<screen><lineannotation>&hellip;</lineannotation>
if ((pid = fork()) &lt; 0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* _Toujours_ effectuer se contrôle */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error();
else if (pid == 0) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* C'est le processus fils */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int PauseMode = 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (PauseMode)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Attendre que quelqu'un se rattache &agrave; nous */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&hellip;
} else {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* parent */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&hellip;</screen>
Il n'y a plus qu'&agrave; se rattacher au fils, positionner
<symbol>PauseMode</symbol> &agrave; <literal>0</literal>, et attendre
que l'appel de <function>sleep()</function> nous rende la main!</para>
</sect2>
</sect1>
<sect1 id="emacs">
<title>Utiliser Emacs comme environnement de développement</title>
<sect2>
<title>Emacs</title>
<para>Les systèmes Unix ne s'accompagnent malheureusement pas
du type d'environnement de développement
intégré du genre &ldquo;tout ce que vous avez toujours
voulu et encore beaucoup plus en un seul monstrueux paquetage&rdquo;
dont disposent d'autres systèmes<footnote><para>Au moins, pas
&agrave; moins que vous ne soyez prêt &agrave; les payer une somme
astronomique.</para></footnote>. Il est cependant possible de mettre
au point votre propre environnement. Il ne sera peut-être pas
aussi esthétique et il ne sera peut-être pas aussi
intégré, mais vous pourrez le configurer comme vous le
voulez. Et il est gratuit. En plus, vous en avez les sources.</para>
<para>Emacs est la clé de tout. Il y a bien des gens qui le
décrient, mais nombreux sont ceux qui l'aiment. Si vous
êtes des premiers, j'ai peur que cette section n'ait que peu
d'intérêt pour vous. Il vous faudra aussi pas mal de
mémoire pour l'utiliser. Je conseille 8Mo en mode texte et
16Mo sous X comme strict minimum pour avoir des temps de réponse
raisonnables.</para>
<para>Emacs est essentiellement un éditeur extrêmement
configurable&nbsp;-&nbsp;il a de fait été configuré
au point de ressembler plus &agrave; un système
d'exploitation qu'&agrave; un éditeur! De nombreux
développeurs et administrateurs système passent le plus
clair de leur temps &agrave; travailler sous Emacs, le quittant
seulement pour se déconnecter.</para>
<para>Il est impossible de même résumer ici tout ce qu'Emacs
est capable de faire, mais voici quelques fonctionnalités qui
intéressent les développeurs:
<itemizedlist>
<listitem>
<para>Editeur très puissant qui permet et de rechercher et
remplacer des chaînes de caractères et d'utiliser pour
le faire des expressions régulières (motifs), d'aller
au début ou &agrave; la fin de blocs syntaxiques, etc,
etc.</para>
</listitem>
<listitem>
<para>Menus déroulants et aide en ligne.</para>
</listitem>
<listitem>
<para>Mise en valeur et indentation en fonction de la syntaxe du
langage utilisé.</para>
</listitem>
<listitem>
<para>Complètement configurable.</para>
</listitem>
<listitem>
<para>Vous pouvez compiler et déboguer des programmes depuis
Emacs.</para>
</listitem>
<listitem>
<para>En cas d'erreur &agrave; la compilation, vous pouvez aller
directement &agrave; la ligne qui en est la cause.</para>
</listitem>
<listitem>
<para>Interface ergonomique au programme <command>info</command>
qui sert &agrave; lire la documentation hypertexte GNU, dont
celle d'Emacs lui-même.</para>
</listitem>
<listitem>
<para>Interface conviviale pour <command>gdb</command>, qui vous
permet de visualiser le code source en même temps que vous
exécutez pas &agrave; pas le programme.</para>
</listitem>
<listitem>
<para>Vous pouvez lire les &ldquo;news&rdquo; Usenet et votre
courrier électronique pendant que votre programme
compile.</para>
</listitem>
</itemizedlist>
Et sans aucun doute bien d'autres choses qui m'ont
échappées.</para>
<para>Emacs peut être installé sous FreeBSD sous forme de
<ulink url="http://www.freebsd.org/ports/editors.html">logiciel
porté</ulink>.</para>
<para>Une fois qu'il est installé, lancez-le et tapez
<userinput>C-h t</userinput>&nbsp;-&nbsp;ce qui signifie maintenir
enfoncée la touche <keycap>Ctrl</keycap>, taper
<keycap>h</keycap>, relâcher la touche <keycap>Ctrl</keycap>, et
appuyer ensuite sur <keycap>t</keycap>&nbsp;-&nbsp; pour lire le guide
d'Emacs (Vous pouvez aussi utiliser la souris pour sélectionner
<guimenuitem>Emacs
Tutorial</guimenuitem>&nbsp;-&nbsp;&ldquo;<foreignphrase>Guide
Emacs</foreignphrase>&rdquo;&nbsp;-&nbsp;depuis le menu
<guimenu>Help</guimenu>&nbsp;-&nbsp;&ldquo;<foreignphrase>Aide</foreignphrase>&rdquo;).</para>
<para>Bien qu'Emacs ait des menus, il vaut la peine d'apprendre &agrave;
utiliser les raccourcis claviers, parce qu'il est bien plus rapide
quand vous éditez quelque chose d'appuyer sur deux ou trois
touches que de courir après la souris et cliquer ensuite au bon
endroit. Si, par ailleurs, vous discutez avec des utilisateurs
expérimentés d'Emacs, vous vous apercevrez qu'ils
utilisent assez couramment des expressions comme
&ldquo;<literal>M-x replace-s RET foo RET bar RET</literal>&rdquo;,
il peut donc servir de comprendre ce qu'ils veulent dire. Et de toute
façon, Emacs a bien plus de fonctions utiles qu'il ne peut en
tenir sur une barre de menus.</para>
<para>Il est heureusement assez facile de découvrir les raccourcis
claviers, ils sont affichés dans les menus. Je vous conseille
d'utiliser les menus pour, par exemple, ouvrir un fichier
jusqu'&agrave; ce que vous compreniez comment cela marche et ayez
suffisamment confiance en vous, puis d'essayer C-x C-f. Une fois que
cela vous convient, passez &agrave; une autre des commandes des
menus.</para>
<para>Si vous ne vous rappelez pas ce que fait une combinaison
donnée de touches, choisissez <guimenuitem>Describe
Key</guimenuitem>&nbsp;-&nbsp;&ldquo;<foreignphrase>Description d'une
touche</foreignphrase>&rdquo;&nbsp;-&nbsp;dans le menu
<guimenu>Help</guimenu>&nbsp;-&nbsp;&ldquo;<foreignphrase>Aide</foreignphrase>&rdquo;&nbsp;-&nbsp;et
tapez cette combinaison&nbsp;-&nbsp;Emacs vous dira ce qu'elle fait.
Vous pouvez aussi utiliser le choix <guimenuitem>Command
Apropos</guimenuitem>&nbsp;-&nbsp;&ldquo;<foreignphrase>A propos d'une
commande</foreignphrase>&rdquo;&nbsp;-&nbsp;pour connaître
toutes les commandes comportant un mot donné et les touches qui
leur correspondent.</para>
<para>Au fait, l'expression plus haut signifie: enfoncer la touche
<keysym>Méta</keysym>, appuyer sur <keysym>x</keysym>,
relâcher la touche <keysym>Méta</keysym>, taper
<userinput>replace-s</userinput> (abréviation de
<literal>replace-string</literal>&nbsp;-&nbsp;&ldquo;<foreignphrase>remplacer
une chaîne de caractères</foreignphrase>&rdquo;&nbsp;-&nbsp;une autre
caractéristique d'Emacs est de vous permettre d'abréger
les commandes), appuyer sur <keysym>Entrée</keysym>, taper
<userinput>foo</userinput> (la chaîne que vous voulez remplacer),
appuyer sur <keysym>Entrée</keysym>, taper
<userinput>bar</userinput> (la chaîne avec laquelle vous voulez
remplacer <literal>foo</literal>) et appuyer encore sur
<keysym>Entrée</keysym>. Emacs effectuera alors
l'opération de recherche et remplacement que vous venez de
demander.</para>
<para>Si vous vous demandez ce qu'est la touche
<keysym>Méta</keysym>, c'est une touche spéciale qu'ont
beaucoup de stations Unix. Malheureusement, les PCs n'en ont pas, c'est
habituellement la touche <keysym>Alt</keysym> qui est utilisée
(ou si vous n'avez pas de chance, la touche
<keysym>Echap</keysym>).</para>
<para>Oh, et pour sortir d'Emacs, tapez <command>C-x C-c</command>
(Ce qui signifie: enfoncer la touche <keysym>Ctrl</keysym>, appuyer sur
<keysym>c</keysym>, appuyer sur <keysym>x</keysym> et relâcher la
touche <keysym>Ctrl</keysym>). S'il y a des fichiers ouverts que vous
n'avez pas sauvegardés, Emacs vous demandera si vous voulez les
sauvegarder. (Oubliez que la documentation dit que la méthode
habituelle pour quitter Emacs est d'utiliser
<command>C-z</command>&nbsp;-&nbsp;cela laisse Emacs actif en
tâche de fond et n'est réellement utile que si vous
êtes sur un système qui ne gère pas de terminaux
virtuels).</para>
</sect2>
<sect2>
<title>Configurer Emacs</title>
<para>Emacs fait des choses admirables; certaines fonctionnalités
sont incorporées, d'autres doivent être
configurées.</para>
<para>Au lieu d'utiliser un langage de macros-instructions
propriétaires, Emacs se sert d'une version de Lisp
spécialement adaptée aux éditeurs, connue sous le
nom de Emacs Lisp. Ce peut être très utile si vous voulez
aller plus loin et apprendre ensuite par exemple Common Lisp, parce
qu'il est considérablement plus léger que Common Lisp
(quoique qu'encore assez imposant!).</para>
<para>La meilleure façon d'apprendre Emacs Lisp est de
télécharger
<ulink url="ftp://prep.ai.mit.edu/pub/gnu/elisp-manual-19-2.4.tar.gz">le
Guide Emacs Lisp</ulink>.</para>
<para>Il n'y a cependant pas besoin de connaître quoique ce soit
&agrave; Lisp pour commencer &agrave; configurer Emacs, parce que j'ai
inclu un fichier <filename>.emacs</filename> d'exemple, qui devrait
suffire au début. Copiez-le simplement dans votre
répertoire utilisateur et relancez Emacs, s'il s'exécute
déj&agrave;; il lira les commandes du fichier et (je
l'espère) vous fournira une configuration de base utile.</para>
</sect2>
<sect2>
<title>Un exemple de fichier <filename>.emacs</filename></title>
<para>Il contient malheureusement beaucoup trop de choses pour tout
expliquer en détails; il y a cependant un ou deux points
intéressants &agrave; mentionner.</para>
<para>
<itemizedlist>
<listitem>
<para>Tout ce qui commence par un <literal>;</literal> est en
commentaire et est ignoré par Emacs.</para>
</listitem>
<listitem>
<para>La première ligne,
<literal>-*-&nbsp;Emacs-Lisp&nbsp;-*-</literal> permet
d'éditer le fichier <filename>.emacs</filename>
lui-même sous Emacs et de profiter de toutes les
fonctionnalitées liées &agrave; l'édition de
code Emacs Lisp. Emacs tente habituellement de deviner le type de
fichier en fonction de son nom, mais risque de ne pas y arriver
pour le fichier <filename>.emacs</filename>.</para>
</listitem>
<listitem>
<para>La touche <keysym>Tab</keysym> est utilisée pour
l'indentation dans certains modes, de sorte que si vous appuyez
sur cette touche cela indente la ligne de code courante. Si vous
voulez mettre un caractère <token>tabulation</token> dans
votre texte, enfoncer la touche <keysym>Ctrl</keysym> en
même temps que vous appuyez sur
<keysym>Tab</keysym>.</para>
</listitem>
<listitem>
<para>Ce fichier permet le mise en valeur syntaxique de code C,
C++, Perl, Lisp et Scheme, en déterminant le langage
d'après le nom du fichier édité.</para>
</listitem>
<listitem>
<para>Emacs a déj&agrave; une fonction
prédéfinie appelée
<function>next-error</function>&nbsp;-&nbsp;&ldquo;<foreignphrase>erreur
suivante</foreignphrase>&rdquo;. Dans la fenêtre de
résultats d'une compilation, cela vous permet d'aller
d'une erreur &agrave; la suivante avec <command>M-n</command>;
nous définissons la fonction complémentaire
<function>previous-error</function>&nbsp;-&nbsp;&ldquo;<foreignphrase>erreur
précédente</foreignphrase>&rdquo;, qui vous permet
de retourner &agrave; l'erreur précédente avec
<command>M-p</command>. Le plus sympathique est que
<command>C-c C-c</command> ouvrira le fichier source où
l'erreur s'est produite et ira &agrave; la ligne
concernée.</para>
</listitem>
<listitem>
<para>Nous activons la possibilité qu'a Emacs d'agir comme
serveur, de façon &agrave; ce que si vous travaillez hors
d'Emacs et voulez éditer un fichier, il vous suffise de
taper:
<screen>&prompt.user; <userinput>emacsclient <replaceable>nom_du_fichier</replaceable></userinput></screen>
pour pouvoir ensuite le modifier avec Emacs!<footnote><para>De
nombreux utilisateurs d'Emacs affectent &agrave; leur variable
d'environnement <envar>EDITOR</envar>
la valeur <literal>emacsclient</literal> de façon &agrave;
ce que ce soit ce qui se produise chaque fois qu'ils ont besoin
d'éditer un fichier.</para></footnote>.</para>
</listitem>
</itemizedlist>
</para>
<example>
<title>Un exemple de fichier <filename>.emacs</filename></title>
<screen>
;; -*-Emacs-Lisp-*-
;; Ce fichier est conçu pour être relu; la variable
;; first-time est utilisée pour éviter les problèmes
;; que cela pourra poser.
(defvar first-time t
"Indicateur signifiant que le fichier .emacs est lu pour la première fois")
;; Méta
(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)
;; Touches fonction
(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)
;; Touches curseur
(global-set-key [up] "\C-p")
(global-set-key [down] "\C-n")
(global-set-key [left] "\C-b")
(global-set-key [right] "\C-f")
(global-set-key [home] "\C-a")
(global-set-key [end] "\C-e")
(global-set-key [prior] "\M-v")
(global-set-key [next] "\C-v")
(global-set-key [C-up] "\M-\C-b")
(global-set-key [C-down] "\M-\C-f")
(global-set-key [C-left] "\M-b")
(global-set-key [C-right] "\M-f")
(global-set-key [C-home] "\M-&lt;")
(global-set-key [C-end] "\M-&gt;")
(global-set-key [C-prior] "\M-&lt;")
(global-set-key [C-next] "\M-&gt;")
;; Souris
(global-set-key [mouse-3] 'imenu)
;; Divers
(global-set-key [C-tab] "\C-q\t") ; Ctrl tab = caractère tabulation.
(setq backup-by-copying-when-mismatch t)
;; 'y' ou &lt;CR&gt; équivaut &agrave; yes, 'n' &agrave; 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)
;; Paquetages &agrave; charger
(require 'desktop)
(require 'tar-mode)
;; Mode diff évolué
(autoload 'ediff-buffers "ediff" "Interface Emacs intelligente pour diff" t)
(autoload 'ediff-files "ediff" "Interface Emacs intelligente pour diff" t)
(autoload 'ediff-files-remote "ediff"
"Interface Emacs intelligente pour diff")
</screen>
<screen>
(if first-time
&nbsp;&nbsp;&nbsp;&nbsp;(setq auto-mode-alist
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(append '(("\\.cpp$" . c++-mode)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;("\\.hpp$" . c++-mode)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;("\\.lsp$" . lisp-mode)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;("\\.scm$" . scheme-mode)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;("\\.pl$" . perl-mode)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;) auto-mode-alist)))
;; Mise en valeur syntaxique automatique
(defvar font-lock-auto-mode-list
(list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
"Listes des modes &agrave; démarrer toujours avec mise en valeur")
(defvar font-lock-mode-keyword-alist
'((c++-c-mode . c-font-lock-keywords)
(perl-mode . perl-font-lock-keywords))
"Associations entre modes et mots-clés")
(defun font-lock-auto-mode-select ()
"Sélectionne automatiquement type de mise en valeur si le major mode courant est dans font-lock-auto-mode-list"
(if (memq major-mode font-lock-auto-mode-list)
(progn
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(font-lock-mode t))
)
)
(global-set-key [M-f1] 'font-lock-fontify-buffer)
;; Nouveau dabbrev
;(require 'new-dabbrev)
(setq dabbrev-always-check-other-buffers t)
(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
(add-hook 'emacs-lisp-mode-hook
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'(lambda ()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(set (make-local-variable 'dabbrev-case-fold-search) nil)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(set (make-local-variable 'dabbrev-case-replace) nil)))
(add-hook 'c-mode-hook
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'(lambda ()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(set (make-local-variable 'dabbrev-case-fold-search) nil)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(set (make-local-variable 'dabbrev-case-replace) nil)))
(add-hook 'text-mode-hook
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'(lambda ()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(set (make-local-variable 'dabbrev-case-fold-search) t)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(set (make-local-variable 'dabbrev-case-replace) t)))
;; Mode C++ et C...
(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)
;; indentation style BSD
(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))
;; Mode Perl...
(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))
;; Mode Scheme...
(defun my-scheme-mode-hook ()
(define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
;; Mode Emacs-Lisp...
(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))
;; Ajouts des précédents
(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)
;; L'inverse de next-error
(defun previous-error (n)
"Aller &agrave; l'erreur de compilation précédente et au code correspondant."
(interactive "p")
(next-error (- n)))
</screen>
<screen>;; Divers...
(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)
;; Recherche dans les archives Elisp
(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)
;; Mise en valeur syntaxique
(defun my-make-face (face colour &amp;optional bold)
"Créer une apparence pour une couleur, éventuellement en gras"
(make-face face)
(copy-face 'default face)
(set-face-foreground face colour)
(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)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; (global-set-key [delete] 'delete-char)
(standard-display-european t)
(load-library "iso-transl")))
;; X11 ou PC écrivant directement &agrave; l'écran
(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
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scheme-mode)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hilit-auto-highlight nil
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hilit-auto-rehighlight 'visible
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hilit-inhibit-hooks nil
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hilit-inhibit-rebinding t)
(require 'hilit19)
(require 'paren))
(setq baud-rate 2400) ; Pour les connections série lentes
)
;; Terminal type TTY
(if (and (not window-system)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not (equal system-type 'ms-dos)))
&nbsp;&nbsp;&nbsp;&nbsp;(progn
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if first-time
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(progn
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyboard-translate ?\C-h ?\C-?)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyboard-translate ?\C-? ?\C-h)))))
;; Sous UNIX
(if (not (equal system-type 'ms-dos))
&nbsp;&nbsp;&nbsp;&nbsp;(progn
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if first-time
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(server-start))))
;; Ajouter ici toute modification d'apparence des caractères
(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")
)))
;; Restaurer le "bureau" - le faire le plus tard possible
(if first-time
(progn
(desktop-load-default)
(desktop-read)))
;; Indique que le fichier a été lu au moins une fois
(setq first-time nil)
;; Plus besoin de déboguer quoi que ce soit maintenant.
(setq debug-on-error nil)
;; C'est tout
(message "OK, %s%s" (user-login-name) ".")
</screen>
</example>
</sect2>
<sect2>
<title>Permettre &agrave; Emacs de comprendre de nouveaux
langages</title>
<para>Bon, tout cela est très bien si vous ne voulez programmer
qu'avec les langages déj&agrave; introduits dans le fichier
<filename>.emacs</filename> (C, C++, Perl, Lisp et Scheme), mais que se
passe-t-il quand un nouveau langage appelé
&ldquo;whizbang&rdquo; fait son apparition, avec plein de nouvelles
fonctionnalités attrayantes?</para>
<para>La première chose &agrave; faire est de regarder si whizbang
s'accompagne de fichiers de configuration d'Emacs pour ce langage.
Ces fichiers ont généralement comme extension
<filename>.el</filename>, raccourci pour &ldquo;Emacs Lisp&rdquo;.
Par exemple, si whizbang est un logiciel porté pour FreeBSD,
ces fichiers peuvent être repérés par:
<screen>&prompt.user; <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
et il faut les installer en le copiant dans le répertoire du
&ldquo;site Lisp&rdquo; d'Emacs. Sous FreeBSD 2.1.0-RELEASE, c'est le
répertoire
<filename>/usr/local/share/emacs/site-lisp</filename>.</para>
<para>Ainsi par exemple, si la commande précédente nous
donnait:
<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
nous le copierions alors comme suit:
<screen>&prompt.user; <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
</para>
<para>Décidons ensuite de l'extension que doivent avoir les
fichiers source whizbang. Supposons, pour les besoins de l'exemple,
qu'ils se terminent tous par <filename>.wiz</filename>. Il faut ajouter
une entrée &agrave; notre fichier <filename>.emacs</filename>,
pour être sûr qu'Emacs puisse utiliser les informations du
fichier <filename>whizbang.el</filename>.</para>
<para>Recherchons l'entrée <symbol>auto-mode-alist</symbol> dans
<filename>.emacs</filename> et ajoutons une ligne pour whizbang, par
exemple:
<programlisting>
<lineannotation>&hellip;</lineannotation>
("\\.lsp$" . lisp-mode)
("\\.wiz$" . whizbang-mode)
("\\.scm$" . scheme-mode)
<lineannotation>&hellip;</lineannotation>
</programlisting>
Cela signifie qu'Emacs passera automatiquement en
<function>whizbang-mode</function> &agrave; l'édition d'un
fichier d'extension <filename>.wiz</filename>.</para>
<para>Juste après, il y a une entrée
<symbol>font-lock-auto-mode-list</symbol>. Ajoutez-y
<function>whizbang-mode</function> comme ceci:
<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)
"Listes des modes &agrave; démarrer toujours en font-lock-mode")
</programlisting>
Ce qui signifie qu'Emacs activera toujours le
<function>font-lock-mode</function> (i.e., la mise en valeur
syntaxique) &agrave; l'édition d'un fichier
<filename>.wiz</filename>.</para>
<para>Cela suffit. S'il y a autre chose que vous voulez automatiser
&agrave; l'ouverture d'un fichier <filename>.wiz</filename>, vous
pouvez ajouter un <function>whizbang-mode hook</function> (voyez mon
<function>my-scheme-mode-hook</function> pour avoir un exemple simple
qui ajoute un <function>auto-indent</function>&nbsp;-&nbsp;indentation
automatique).</para>
</sect2>
</sect1>
<sect1>
<title>A lire pour aller plus loin</title>
<itemizedlist>
<listitem>
<para>Brian Harvey et 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 et 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 et Rob Pike <emphasis>The Unix Programming
Environment</emphasis> Prentice-Hall 1984<!-- <br> --> ISBN
0-13-937681-X</para>
</listitem>
<listitem>
<para>Brian W. Kernighan et 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>
</article>