doc/fr_FR.ISO8859-1/articles/programming-tools/article.sgml
Dima Dorfman 773ff743ed Reference %authors via its PUBLIC rather than SYSTEM identifier.
There's a reason we have catalogs, and it isn't to use inodes.
2001-08-25 21:55:57 +00:00

2001 lines
108 KiB
Text
Executable file

<!--
The FreeBSD Documentation Project
The FreeBSD French Documentation Project
$FreeBSD: doc/fr_FR.ISO8859-1/articles/programming-tools/article.sgml,v 1.4 2001/07/13 15:48:40 nik Exp $
Original revision: n.nn
-->
<!DOCTYPE ARTICLE PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN"> %man;
<!ENTITY % urls PUBLIC "-//FreeBSD//ENTITIES Common Document URL Entities//FR"> %urls;
<!ENTITY % abstract PUBLIC "-//FreeBSD//ENTITIES DocBook Abstract Entities//FR"> %abstract;
<!ENTITY % artheader PUBLIC "-//FreeBSD//ENTITIES DocBook ArtHeader Entities//FR"> %artheader;
<!ENTITY % translators PUBLIC "-//FreeBSD//ENTITIES DocBook Translator Entities//FR"> %translators;
<!ENTITY % authors PUBLIC "-//FreeBSD//ENTITIES DocBook Author Entities//EN"> %authors;
<!ENTITY % mailing-lists PUBLIC "-//FreeBSD//ENTITIES DocBook Mailing List Entities//FR"> %mailing-lists;
<!ENTITY rel.current CDATA "3.2">
]>
<article LANG="fr">
<articleinfo>
<title>Les outils de d&eacute;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>
<abstract>
<para>17 Ao&ucirc;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&eacute;tail comment coder. La plus grande partie du
document suppose que vous n'avez aucune ou peu de notions
pr&eacute;alables de programmation, bien que l'on esp&egrave;re
que la plupart des programmeurs y trouveront quelque chose qui leur
sera utile.</para>
&abstract.disclaimer;
&trans.a.haby;
</abstract>
</articleinfo>
<sect1>
<title>Introduction<anchor id=foo></title>
<para>FreeBSD fournit un excellent environnement de d&eacute;veloppement.
Le syst&egrave;me de base comprend des compilateurs C, C++ et Fortran,
et un assembleur, pour ne pas mentionner l'interpr&eacute;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&eacute;teurs au catalogue des logiciels
port&eacute;s. FreeBSD est tr&egrave;s largement compatible avec les
standards comme <acronym>POSIX</acronym> et <acronym>ANSI</acronym> C,
de m&ecirc;me qu'avec son propre h&eacute;ritage BSD, il est donc
possible d'&eacute;crire des applications qui compilent et
s'ex&eacute;cutent sur une grande vari&eacute;t&eacute; de
plates-formes.</para>
<para>Toute cette puissance, toutefois, peut submerger au premier abord,
si vous n'avez jamais auparavant &eacute;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&eacute;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&eacute;tence de
base dans l'utilisation d'Unix et la volont&eacute; d'apprendre!</para>
</sect1>
<sect1>
<title>Introduction &agrave; la programmation</title>
<para>Un programme est une s&eacute;rie d'instructions qui dit &agrave;
l'ordinateur de faire des choses diverses; l'instruction qu'il doit
ex&eacute;cuter d&eacute;pend parfois de ce qui s'est pass&eacute;
lorsqu'il a ex&eacute;cut&eacute; une instruction
pr&eacute;c&eacute;dente. Cette section vous donne un aper&ccedil;u
des deux principales m&eacute;thodes pour transmettre ces instructions,
ou &ldquo;commandes&rdquo; comme on les appellent. L'une est d'utiliser
un <firstterm>interpr&eacute;teur</firstterm>, l'autre de se servir d'un
<firstterm>compilateur</firstterm>. Comme les langues humaines sont trop
compliqu&eacute;es pour &ecirc;tre comprises sans ambigu&iuml;t&eacute;
par un ordinateur, les commandes sont g&eacute;n&eacute;ralement
&eacute;crites dans l'un ou l'autre des languages sp&eacute;cialement
con&ccedil;us &agrave; cet effet.</para>
<sect2>
<title>Interpr&eacute;teurs</title>
<para>Dans le cas d'un interpr&eacute;teur, le langage s'accompagne d'un
environnement, sous lequel vous tapez des commandes &agrave; son invite
et qui les ex&eacute;cute pour vous. Pour des programmes plus
compliqu&eacute;s, vous pouvez saisir les commandes dans un fichier
et le faire charger et ex&eacute;cuter les commandes qu'il contient par
l'interpr&eacute;teur. Si quelque chose se passe mal, la plupart des
interpr&eacute;teurs passeront le contr&ocirc;le &agrave; un
d&eacute;bogueur pour vous aider &agrave; trouver l'origine du
probl&egrave;me.</para>
<para>Cela a l'avantage de vous permettre de voir imm&eacute;diatement
le r&eacute;sultat de vos commandes et de corriger sur le champ vos
erreurs. Le principal inconv&eacute;nient survient lorsque vous voulez
partager vos programmes avec d'autres. Il faut qu'ils aient le
m&ecirc;me interpr&eacute;teur que vous ou que vous ayez le moyen de
leur fournir cet interpr&eacute;teur; il faut aussi qu'ils comprennent
comment s'en servir. Les utilisateurs peuvent aussi ne pas
appr&eacute;cier de se retrouver sous un d&eacute;bogueur s'ils
appuyent sur la mauvaise touche! Du point de vue de la performance,
les interpr&eacute;teurs utilisent parfois beaucoup de m&eacute;moire
et ne g&eacute;n&eacute;rent habituellement pas le code aussi
efficacement que les compilateurs.</para>
<para>A mon avis, les langages interpr&eacute;t&eacute;s sont le meilleur
moyen de d&eacute;buter si vous n'avez jamais programm&eacute;
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&ecirc;me un interpr&eacute;teur, beaucoup &eacute;crivent en fait
avec des
proc&eacute;dures&nbsp;-&nbsp;<foreignphrase>scripts</foreignphrase>&nbsp;-&nbsp;pour
se faciliter le travail d'administration de leur machine. De fait,
une partie de la philosphie d'origine d'Unix &eacute;tait de fournir
nombre de petits programmes utilitaires qui puissent &ecirc;tre
utilis&eacute;s de concert dans des proc&eacute;dures pour effectuer
des t&acirc;ches utiles.</para>
</sect2>
<sect2>
<title>Interpr&eacute;teurs disponibles pour FreeBSD</title>
<para>Voici une liste des interpr&eacute;teurs disponibles sous forme de
<ulink URL="ftp://ftp.freebsd.org/pub/FreeBSD/packages/">&ldquo;paquetages&rdquo;</ulink>
FreeBSD, accompagn&eacute;e d'une br&egrave;ve description des langages
interpr&eacute;t&eacute;s les plus r&eacute;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&eacute;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 &eacute;videmment que vous ayez un syst&egrave;me FreeBSD 2.1.0
ou ult&eacute;rieur en &eacute;tat de marche pour que le logiciel
fonctionne.</para>
<variablelist>
<varlistentry>
<term><acronym>BASIC</acronym></term>
<listitem>
<para>Abr&eacute;viation pour &ldquo;<foreignphrase>Beginner's
All-purpose Symbolic Instruction
Code</foreignphrase>&rdquo;&nbsp;-&nbsp;code d'instructions
symbolique universel pour les d&eacute;butants.
D&eacute;velopp&eacute; dans les ann&eacute;es 50 pour apprendre
la programmation aux &eacute;tudiants des Universit&eacute;s et
fourni avec tout ordinateur personnel qui se respectait dans les
ann&eacute;es 80, <acronym>BASIC</acronym> a &eacute;t&eacute; 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&eacute;teur
Basic Bywater</ulink> et
l'<ulink URL="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/pbasic-2.0.tgz">interpr&eacute;teur
Basic de Phil Cockroft</ulink> (appel&eacute; 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&eacute;velopp&eacute; &agrave; la fin des
ann&eacute;es 1950 comme alternative aux langages
&ldquo;d&eacute;voreurs de nombres&rdquo; qui e&acute;taient
populaires &agrave; l'&eacute;poque. Au lieu d'&ecirc;tre
bas&eacute; sur les nombres, Lisp repose sur les listes; de fait,
son nom est une abr&eacute;viation pour &ldquo;<foreignphrase>List
Processing</foreignphrase>&rdquo;&nbsp;-&nbsp;traitement de
listes. Tr&eacute;s r&eacute;pandu dans les milieux de l'IA
(Intelligence Artificielle).</para>
<para>Lisp est un langage tr&egrave;s puissant et
sophistiqu&eacute;, mais peut &ecirc;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&egrave;s employ&eacute; par les administrateurs
syst&egrave;me pour &eacute;crire des proc&eacute;dures; et
souvent aussi sur les serveurs <foreignphrase>World Wide
Web</foreignphrase> pour &eacute;crire des proc&eacute;dures
<acronym>CGI</acronym>.</para>
<para>La Version 4, qui est probablement encore la version la plus
largement r&eacute;pandue est fournie avec FreeBSD; le plus
r&eacute;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&ocirc;t plus compact et plus
propre que Common Lisp. Courant dans les Universit&eacute;s parce
qu'il est assez facile &agrave; enseigner en premier cycle comme
langage d'initiation et pr&eacute;sente un niveau d'abstraction
suffisant pour &ecirc;tre utilis&eacute; 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&eacute;teur
Scheme Elk</ulink>,
l'<ulink URL="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/mit-scheme-7.3.tgz">Interpr&eacute;teur Scheme du MIT</ulink> et
l'<ulink URL="ftp://ftp.freebsd.org/pub/FreeBSD/packages/lang/scm-4e1.tgz">Interpr&eacute;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&eacute;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&eacute; objet Python</ulink>.</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2>
<title>Compilateurs</title>
<para>Les compilateurs sont assez diff&eacute;rents. Vous &eacute;crivez
d'abord votre code dans un(des) fichiers(s) &agrave; l'aide d'un
&eacute;diteur. Vous ex&eacute;cutez ensuite le compilateur et voyez
s'il valide votre programme. S'il ne le compile pas, serrez les dents et
retournez sous l'&eacute;diteur. S'il le compile et vous en fait un
programme, vous pouvez l'utiliser soit &agrave; l'invite de
l'interpr&eacute;teur de commande, soit en vous servant d'un
d&eacute;bogueur pour voir s'il fonctionne
correctement<footnote><para>Dans
le cas contraire, si vous l'ex&eacute;cutez sur la ligne de commande, il
peut &eacute;ventuellement
planter&nbsp;-&nbsp;&ldquo;<foreignphrase>core
dump</foreignphrase>&rdquo;.</para></footnote>.</para>
<para>Ce n'est &eacute;videmment pas aussi imm&eacute;diat que de se
servir d'un interpr&eacute;teur. Cela vous permet cependant de faire
beaucoup de choses qui sont tr&egrave;s difficiles ou m&ecirc;me
irr&eacute;alisables avec un interpr&eacute;teur, comme &eacute;crire
du code qui interagisse &eacute;troitement avec le syst&egrave;me
d'exploitation&nbsp;-&nbsp; ou m&ecirc;me &eacute;crire votre propre
syst&egrave;me d'exploitation! C'est aussi utile si vous avez besoin
d'&eacute;crire du code tr&egrave;s efficace, parce que le compilateur
peut prendre son temps et optimiser le code, ce qui ne serait pas
acceptable d'un interpr&eacute;teur. Distribuer un programme
&eacute;crit pour un compilateur est g&eacute;n&eacute;ralement plus
facile&nbsp;-&nbsp;il suffit de livrer une copie de l'ex&eacute;cutable,
en supposant que les destinataires aient le m&ecirc;me syst&egrave;me
d'exploitation que vous.</para>
<para>Les langages compil&eacute;s incluent Pascal, C et C++. C et C++
sont des langages qui pardonnent assez peu, et plus adapt&eacute;s aux
programmeurs plus exp&eacute;riment&eacute;s. Pascal, d'un autre
c&ocirc;t&eacute;, a &eacute;t&eacute; con&ccedil;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&eacute;s.</para>
<para>Comme le cycle
&ldquo;&eacute;dition-compilation-ex&eacute;cution-d&eacute;bogage&rdquo;
est assez fastidieux, de nombreux fournisseurs de compilateurs
commerciaux
ont produit des Environnements de D&eacute;veloppement
Int&eacute;gr&eacute;s (<acronym>EDI</acronym> en abr&eacute;g&eacute;).
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&eacute; &agrave; la section <link linkend="emacs">Utiliser
Emacs comme environnement de d&eacute;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&egrave;me FreeBSD. Il peut &ecirc;tre
appel&eacute; soit avec la commande <command>cc</command>, soit avec
<command>gcc</command>. Les d&eacute;tails de la r&eacute;alisation
d'un programme avec un interpr&eacute;teur varient consid&eacute;rablement
d'un interpr&eacute;teur &agrave; l'autre, est sont
g&eacute;n&eacute;ralement bien d&eacute;crits par l'aide en ligne de
l'interpr&eacute;teur.</para>
<para>Une fois que vous avez &eacute;crit votre chef-d'oeuvre,
l'&eacute;tape suivante consiste &agrave; le convertir en quelque chose
qui (esp&eacute;rons-le!) s'ex&eacute;cutera sous FreeBSD. Cela demande
habituellement plusieurs op&eacute;rations successives, dont chacune est
confi&eacute;e &agrave; un programme diff&eacute;rent.</para>
<procedure>
<step>
<para>Pr&eacute;-processer votre code source pour en &eacute;liminer les
commentaires et faire diverses autres choses, comme la substitution
des macros-instructions en C.</para>
</step>
<step>
<para>V&eacute;rifier la syntaxe de votre code pour s'assurer que vous
avez respect&eacute; les r&egrave;gles du langage. Si ce n'est pas le
cas, il rousp&eacute;tera.</para>
</step>
<step>
<para>Convertir le code source en langage
assembleur&nbsp;-&nbsp;c'est tr&egrave;s proche du code machine, mais
encore compr&eacute;hensible par des &ecirc;tres humains. C'est du
moins ce que l'on pr&eacute;tend<footnote><para>Pour &ecirc;tre
rigoureusement exact, <command>cc</command> convertit le code source
en un <firstterm>P-code</firstterm> qui lui est propre, et ne
d&eacute;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&eacute;ros et de
uns.</para>
</step>
<step>
<para>V&eacute;rifier que vous avez utilis&eacute; de fa&ccedil;on
coh&eacute;rente les fonctions et les variables globales. Si, par
exemple, vous avez appel&eacute; une fonction qui n'existe pas, il
s'en plaindra.</para>
</step>
<step>
<para>Si vous essayez de g&eacute;n&eacute;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&egrave;me pourra mettre en m&eacute;moire et
ex&eacute;cuter.</para>
</step>
</procedure>
<para>Le mot <firstterm>compiler</firstterm> est souvent utilis&eacute; pour
ne d&eacute;signer que les &eacute;tapes 1 &agrave; 4&nbsp;-&nbsp;les
autres sont appel&eacute;es <firstterm>&eacute;dition de
liens</firstterm>. L'&eacute;tape 1 est parfois appel&eacute;e
<firstterm>pr&eacute;-processer</firstterm> et les &eacute;tapes 3-4
<firstterm>assembler</firstterm>.</para>
<para>Heureusement, pratiquement tous ces d&eacute;tails vous sont
transparents, car la commande <command>cc</command> est une interface
qui g&egrave;re pour vous l'appel de ces diff&eacute;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 &eacute;tapes d&eacute;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</></screen>
<para>Notez que la v&eacute;rification syntaxique ne consiste qu'en cela:
v&eacute;rifier la syntaxe. Il n'y aura pas de contr&ocirc;le sur les
erreurs logiques que vous auriez commises, comme faire ex&eacute;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&ugrave; vous ne le
sauriez pas, un tri par arbre binaire est une mani&egrave;re efficace
d'ordonner des donn&eacute;es, ce qui n'est pas le cas du tri
&agrave; bulles.</para></footnote>.</para>
<para><command>cc</command> dispose d'une quantit&eacute; d'options, qui
sont toutes d&eacute;crites dans les pages de manuel. En voici
quelques-unes des plus importantes, et la fa&ccedil;on de les
utiliser.</para>
<variablelist>
<varlistentry>
<term><option>-o <replaceable>nom_de_fichier</replaceable></option></term>
<listitem>
<para>Le nom du fichier r&eacute;sultat. Si vous n'utilisez pas cette
option, <command>cc</command> g&eacute;n&eacute;rera un
ex&eacute;cutable appel&eacute;
<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&eacute;cutable est <filename>a.out</filename></lineannotation>
&prompt.user; <userinput>cc -o foobar foobar.c</userinput> <lineannotation>l'ex&eacute;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'&eacute;dition de
liens. Utile pour des programmes d'essai, quand vous voulez
simplement v&eacute;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&eacute;n&eacute;rera un <firstterm>fichier
objet</firstterm> (et non un ex&eacute;cutable) appel&eacute;
<filename>foobar.o</filename>. Il pourra &ecirc;tre li&eacute; avec
d'autres fichiers objet pour constituer un ex&eacute;cutable.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-g</option></term>
<listitem>
<para>Cr&eacute;e une version d&eacute;bogable de l'ex&eacute;cutable
Le compilateur inclut alors dans l'ex&eacute;cutable des
informations de correspondance entre les num&eacute;ros de ligne du
fichier source et les fonctions appel&eacute;es. Un d&eacute;bogueur
peut alors utiliser ces informations pour vous afficher le code
source tandis que vous ex&eacute;cutez pas &agrave; pas le
programme, ce qui est <emphasis>tr&egrave;s</emphasis> utile;
l'inconv&eacute;nient est que toutes ces informations augmentent
consid&eacute;rablement la taille du programme. Normalement, vous
compilez avec <option>-g</option> quand vous d&eacute;veloppez le
programme, et compilez ensuite une &ldquo;version de
livraison&rdquo; quand vous &ecirc;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&eacute;bogable du
programme<footnote><para>Remarquez que nous n'avons pas
utilis&eacute; l'indicateur <option>-o</option> pour pr&eacute;ciser
le nom de l'ex&eacute;cutable, celui-ci s'appelera donc
<filename>a.out</filename>. G&eacute;n&eacute;rer une version
d&eacute;bogable appel&eacute;e <filename>foobar</filename> est
laiss&eacute; &agrave; titre d'exercice aux soins du
lecteur!</para></footnote>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-O</option></term>
<listitem>
<para>G&eacute;n&egrave;re une version optimis&eacute;e de
l'ex&eacute;cutable. Le compilateur effectue alors diverses
op&eacute;rations bien pens&eacute;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&eacute; plus important d'optimisation, mais cela met souvent
en &eacute;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&eacute;n&eacute;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&eacute;e de
<filename>foobar</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
<para>Les trois indicateurs suivants demanderont &agrave;
<command>cc</command> de v&eacute;rifier que votre code est conforme
&agrave; la norme internationale, souvent appel&eacute;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&eacute;s
int&eacute;ressants. Malgr&eacute; 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&eacute;sactive la plupart, mais pas toutes, les
possibilit&eacute;s non-<acronym>ANSI</>&nbsp;C fournies par
<command>cc</command>. Malgr&eacute; 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&eacute;sactive <emphasis>toutes</emphasis> les
possibilit&eacute;s non-<acronym>ANSI</>&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&egrave;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'&eacute;criture de code qui puissent &ecirc;tre
r&eacute;utilis&eacute; avec n'importe quel compilateur sur n'importe
quel syst&egrave;me. C'est cela que l'on appelle du <firstterm>code
portable</firstterm>.</para>
<para>En g&eacute;n&eacute;ral, vous devriez vous efforcer de rendre votre
code aussi portable que possible, sans quoi vous risquez de devoir
r&eacute;&eacute;crire enti&egrave;rement votre programme par la suite
pour qu'il fonctionne ailleurs&nbsp;-&nbsp;et qui peut dire ce que vous
utiliserez dans quelques ann&eacute;es?</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
</informalexample>
<para>Cela g&eacute;n&eacute;rera un ex&eacute;cutable
<filename>foobar</filename> apr&egrave;s avoir v&eacute;rifi&eacute; que
<filename>foobar.c</filename> respecte la norme.</para>
<variablelist>
<varlistentry>
<term><option>-l<replaceable>biblioth&egrave;que</replaceable></option></term>
<listitem>
<para>D&eacute;finit une biblioth&egrave;que de fonctions &agrave;
utiliser pour l'&eacute;dition de liens.</para>
<para>L'exemple le plus courant est la compilation d'un programme
qui utilise certaines des fonctions math&eacute;matiques de C. A
l'inverse de la plupart des autres plates-formes, ces fonctions
sont dans une biblioth&egrave;que diff&eacute;rente de la
biblioth&egrave;que C standard et vous devez pr&eacute;ciser au
compilateur qu'il doit l'utiliser.</para>
<para>La r&egrave;gle est que si la biblioth&egrave;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&egrave;que math&eacute;matique s'appelle
<filename>libm.a</filename>, vous donnez donc &agrave;
<command>cc</command> l'argument <option>-lm</option>. Un
d&eacute;tail &agrave; conna&icirc;tre &agrave; propos de la
biblioth&egrave;que math&eacute;matique est que ce doit
g&eacute;n&eacute;ralement &ecirc;tre la derni&egrave;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'&eacute;dition de liens de
<filename>foobar</filename> des fonctions de la
biblioth&egrave;que math&eacute;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&eacute;rieure, &agrave; la ligne de commande pour
&eacute;diter les liens avec les fonctions de la
biblioth&egrave;que C++. Au lieu de cela, vous pouvez utiliser la
commande <command>c++</command> au lieu de <command>cc</command>,
qui fera la m&ecirc;me chose &agrave; votre place. Sous FreeBSD,
<command>c++</command> peut aussi &ecirc;tre appell&eacute; 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&eacute;rieurs</lineannotation>
&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>Avec FreeBSD 2.2 et ult&eacute;rieurs</lineannotation>
&prompt.user; <userinput>c++ -o foobar foobar.cc</userinput></screen>
</informalexample>
<para>Chacun de ces exemples construira un ex&eacute;cutable
<filename>foobar</filename> &agrave; partir du fichier source C++
<filename>foobar.cc</filename>. Remarquez que, sur les
syst&egrave;mes Unix, les fichiers sources C++ ont
traditionnellement l'extension <filename>.C</filename>,
<filename>.cxx</filename> ou <filename>.cc</filename>,
plut&ocirc;t que l'extension <filename>.cpp</filename>
de sytle <trademark>MS-DOS</trademark> (qui est d&eacute;j&agrave;
utilis&eacute;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&eacute;!</para>
</listitem>
</varlistentry>
</variablelist>
<sect2>
<title>Questions et probl&egrave;mes <command>cc</command></title>
<para>Q. J'essaie d'&eacute;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&eacute;matiques telles
que <function>sin()</function>, vous devez dire &agrave;
<command>cc</command> d'inclure la biblioth&egrave;que
math&eacute;matique &agrave; l'&eacute;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 &eacute;crit ce petit programme pour
m'entra&icirc;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&eacute; 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&eacute;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&eacute;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&eacute;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 &eacute;videmment pas ce que vous souhaitez dans ce
cas.</para>
<para>Q. Comment alors r&eacute;gler ce probl&egrave;me?</para>
<para>R. Les prototypes des fonctions math&eacute;matiques sont dans
<filename>math.h</filename>. Si vous incluez ce fichier, le
compilateur trouvera le prototype et cessera de vous fournir un
r&eacute;sultat bizarre!
<informalexample>
<programlisting>
#include &lt;math.h&gt;
#include &lt;stdio.h&gt;
int main() {
...
</programlisting>
</informalexample>
</para>
<para>Apr&egrave;s l'avoir recompil&eacute; de la m&ecirc;me
fa&ccedil;on qu'auparavant, ex&eacute;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&eacute;matique, incluez
<emphasis>toujours</emphasis> <filename>math.h</filename> et n'oubliez
pas d'utiliser la biblioth&egrave;que math&eacute;matique &agrave;
l'&eacute;dition de liens.</para>
<para>Q. J'ai compil&eacute; un fichier appel&eacute;
<filename>foobar.c</filename> et je ne trouve pas d'ex&eacute;cutable
appel&eacute; <filename>foobar</filename>. O&ugrave; est-il
pass&eacute;?</para>
<para>R. N'oubliez pas, <command>cc</command> appelera
l'ex&eacute;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&eacute;cutable appel&eacute;
<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&eacute;pertoire courant quand il cherche le programme
que vous voulez ex&eacute;cuter, &agrave; moins que vous ne le lui
disiez. Soit tapez <command>./foobar</command>, ce qui veut dire
&ldquo;ex&eacute;cuter le fichier appel&eacute;
<filename>foobar</filename> du r&eacute;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&eacute;pertoire
courant si le fichier n'est pas dans les autres
r&eacute;pertoires&rdquo;.</para>
<para>Q. J'ai appel&eacute; mon ex&eacute;cutable
<filename>test</filename>, mais il ne se passe rien quand je le
lance. Pourquoi?</para>
<para>R. Il y a un programme appel&eacute; <command>test</command> dans
<filename>/usr/bin</filename> sur la plupart des syst&egrave;mes Unix
et c'est celui-l&agrave; que trouve l'interpr&eacute;teur de commandes
avant de regarder dans le r&eacute;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&eacute; et tout a commenc&eacute; &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&eacute;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&egrave;me
enregistrait sur disque le contenu de la m&eacute;moire centrale
dans un fichier appel&eacute; <filename>core</filename>, que le
programmeur pouvait ensuite diss&eacute;quer pour trouver
o&ugrave; les choses avaient mal tourn&eacute;es.</para>
<para>Q. Fascinant, mais que suis-je cens&eacute; faire
maintenant?</para>
<para>A. Servez-vous de <command>gdb</command> pour analyser l'image
m&eacute;moire (Reportez-vous &agrave; la section
<link linkend="debugging">D&eacute;boguer</link>).</para>
<para>R. Quand mon programme a g&eacute;n&eacute;r&eacute; une image
m&eacute;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&eacute; d'effectuer une quelconque op&eacute;ration
ill&eacute;gale sur la m&eacute;moire; Unix est con&ccedil;u pour
prot&eacute;ger le syst&egrave;me d'exploitation des programmes
mal &eacute;duqu&eacute;s.</para>
<para>Les raisons les plus courantes en sont:
<itemizedlist>
<listitem>
<para>Essayer d'&eacute;crire en m&eacute;moire adress&eacute;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 &eacute;t&eacute;
initialis&eacute;, e.g.:
<programlisting>
char *foo;
strcpy(foo, "bang!");
</programlisting>
Le pointeur aura une valeur al&eacute;atoire qui, avec de la
chance, adressera une zone m&eacute;moire non accessible &agrave;
votre programme, de sorte que le noyau tuera ce dernier avant
qu'il ne provoque de d&eacute;gat. Si vous manquez de chance,
il pointera quelque part &agrave; l'int&eacute;rieur de votre
programme et endommagera l'une de vos structures de
donn&eacute;es, provoquant un dysfonctionnement myst&eacute;rieux
de votre programme.</para>
</listitem>
<listitem>
<para>Tenter d'acc&eacute;der au-del&agrave; du dernier
&eacute;l&eacute;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&eacute;moire accessible en lecture seule, e.g.:
<programlisting>
char *foo = "Mon texte";
strcpy(foo, "bang!");
</programlisting>
Les compilateurs Unix stockent souvent les cha&icirc;nes de
caract&egrave;res constantes comme <literal>"Mon texte"</literal>
en m&eacute;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&eacute; tout des choses &agrave; ne pas faire.
Certains syst&egrave;mes et compilateurs sont plus tol&eacute;rants que
d'autres, ce qui fait que des programmes qui s'ex&eacute;cutent
correctement sur un syst&egrave;me peuvent ne plus fonctionner sur un
autre.</para>
<para>Q. Parfois, le programme provoque la g&eacute;n&eacute;ration d'une
image m&eacute;moire avec le message <errorname>bus error</errorname>.
Mon manuel Unix dit qu'il s'agit d'un erreur mat&eacute;riel, mais
l'ordinateur fonctionne apparemment correctement. Est-ce vrai?</para>
<para>R. Fort heureusement, non (&agrave; moins bien s&ucirc;r que vous
n'ayez aussi un probl&egrave;me mat&eacute;riel). C'est habituellement
une autre fa&ccedil;on de dire que vous avez acc&eacute;d&eacute;
incorrectement &agrave; la m&eacute;moire.</para>
<para>Q. Il me semble que cette histoire de <foreignphrase>core
dump</foreignphrase> peut &ecirc;tre tr&egrave;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&ecirc;tre
<application>xterm</application> et tapez:
<screen>&prompt.user; <userinput>ps</userinput></screen> pour
conna&icirc;tre l'IDentifiant de processus de votre programme, puis:
<screen>&prompt.user; <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
o&ugrave; <parameter><replaceable>pid</replaceable></parameter> est
l'ID de processus que vous avez recherch&eacute;.</para>
<para>C'est par exemple utile si votre programme est parti dans une boucle
infinie. Au cas o&ugrave; votre programme pi&eacute;gerait les
interruptions <symbol>SIGABRT</symbol>, il y a plusieurs autres signaux
qui auront le m&ecirc;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&ecirc;nant, mais cela devient rapidement tr&egrave;s
fastidieux lorsqu'il y a plusieurs fichiers&nbsp;-&nbsp;et cela peut
aussi mettre du temps &agrave; compiler.</para>
<para>Un fa&ccedil;on d'&eacute;viter ces probl&egrave;mes est
d'utiliser des fichiers <firstterm>objets</firstterm> et de ne
recompiler que les fichiers de source dont le contenu a chang&eacute;.
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&eacute; <filename>fichier37.c</filename>, et
celui-l&agrave; uniquement, depuis notre compilation
pr&eacute;c&eacute;dente. Cela peut s&eacute;rieusement
acc&eacute;l&eacute;rer la compilation, mais ne r&eacute;soud pas le
probl&egrave;me de saisie &agrave; r&eacute;p&eacute;tition de la
commande.</para>
<para>Nous pourrions aussi &eacute;crire une proc&eacute;dure pour
r&eacute;soudre ce dernier probl&egrave;me, mais ne ne pourrions alors
que lui faire tout recompiler, ce qui serait tr&egrave;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 &eacute;quipe et que d'autres
oublient de nous pr&eacute;venir des modifications qu'ils ont
apport&eacute;es &agrave; un des fichiers que nous utilisons?</para>
<para>Peut-&ecirc;tre pourrions-nous rassembler les deux solutions et
&eacute;crire quelque chose qui ressemble &agrave; une
proc&eacute;dure et comporte une sorte de r&egrave;gle magique
qui dise quand tel fichier de source doit &ecirc;tre compil&eacute;.
Nous n'aurions plus besoin que d'un programme qui comprennent ces
r&egrave;gles, parce que c'est un peu trop compliqu&eacute; pour une
proc&eacute;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&eacute;pendances entre les diff&eacute;rents fichiers, et
en d&eacute;duit lesquels ont besoin ou non d'&ecirc;tre
recompil&eacute;s. Par exemple, une r&egrave;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 &eacute;t&eacute;
modifi&eacute;, il faut donc le recompiler&rdquo;. Le fichier
&ldquo;<foreignphrase>makefile</foreignphrase>&rdquo; inclut aussi
des r&egrave;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&eacute;s dans le m&ecirc;me r&eacute;pertoire que les sources
auxquels ils s'appliquent, et peuvent &ecirc;tre appel&eacute;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&eacute;but de la liste des fichiers et sont ainsi
facilement rep&eacute;rables <footnote><para>Ils n'utilisent pas la
variante <filename>MAKEFILE</filename> parce que les noms en
majuscules servent souvent &agrave; d&eacute;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>
&eacute;l&eacute;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&eacute;pendance et une
pour la g&eacute;n&eacute;ration.</para>
<para>La ligne d&eacute;crivant la d&eacute;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&egrave;re modification de
<filename>foo</filename> &agrave; celle de derni&egrave;re
modification de <filename>foo.c</filename>. Si
<filename>foo</filename> n'existe pas, ou s'il est ant&eacute;rieur
&agrave; <filename>foo.c</filename>, il regarde alors la ligne de
g&eacute;n&eacute;ration pour savoir ce qu'il faut faire. En
d'autres termes, c'est la r&egrave;gle &agrave; appliquer pour
savoir si <filename>foo.c</filename> doit &ecirc;tre
recompil&eacute;.</para>
<para>La ligne de g&eacute;n&eacute;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&eacute;cute alors cette commande pour le cr&eacute;er. En
d'autres termes, c'est la r&egrave;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&egrave;res modifications que vous avez apport&eacute;es &agrave;
<filename>foo.c</filename>. Ce principe s'&eacute;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&egrave;me d'exploitation en tapant simplement
<userinput>make world</userinput> dans le r&eacute;pertoire
ad&eacute;quat!</para>
<para>Une autre particularit&eacute; de <filename>Makefile</filename>s
est que les cibles ne sont pas n&eacute;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&eacute;c&eacute;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&egrave;re cible et
s'arr&ecirc;tera ensuite sans s'occuper des autres. Si nous
avions tap&eacute; <userinput>make</userinput> dans ce cas, il
serait simplement all&eacute; &agrave; la cible
<action>foo</action>, aurait recompil&eacute;
<filename>foo</filename> si n&eacute;cessaire, et se serait
arr&ecirc;t&eacute; sans passer &agrave; la cible
<action>install</action>.</para>
<para>Remarquez que la cible <action>install</action> ne d&eacute;pend
en fait de rien du tout! Cela signifie que la commande sur la ligne
suivante est toujours ex&eacute;cut&eacute;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&eacute;pertoire de l'utilisateur.
C'est souvent utilis&eacute; par les <filename>Makefile</filename>s
de logiciels, de sorte que l'application soit install&eacute;e dans
le bon r&eacute;pertoire, une fois correctement
compil&eacute;e.</para>
<para>C'est un point un peu d&eacute;licat &agrave; expliquer. Si vous
ne comprenez pas exactement comment <command>make</command>
fonctionne, la meilleure chose &agrave; faire est d'&eacute;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&ecirc;te. La commande <command>touch</command>
vous sera tr&egrave;s utile&nbsp;-&nbsp;elle modifie la date
d'un fichier sans que vous ayez &agrave; l'&eacute;diter.</para>
</sect2>
<sect2>
<title>Makefiles FreeBSD</title>
<para>L'&eacute;criture de <filename>Makefile</filename>s peut
&ecirc;tre assez compliqu&eacute;e. Heurusement, les syst&egrave;mes
bas&eacute;s sur BSD, comme FreeBSD, en fournissent de tr&egrave;s
puissants, int&eacute;gr&eacute;s au syst&egrave;me. Le catalogue des
logiciels port&eacute;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&eacute;pertoire associ&eacute;
&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&eacute;j&agrave; pr&eacute;sent sur le syst&egrave;me.</para>
</step>
<step>
<para>S'il n'y est pas, une connexion FTP &agrave; l'URL
indiqu&eacute;e par <symbol>MASTER_SITES</symbol> est
&eacute;tablie pour t&eacute;l&eacute;charger le source.</para>
</step>
<step>
<para>La somme de contr&ocirc;le est calcul&eacute;e sur le source et
compar&eacute;e &agrave; celle calcul&eacute;e sur une version
connue et valid&eacute;e. Cela pour s'assurer que le source n'a
pas &eacute;t&eacute; corrompu pendant le transfert.</para>
</step>
<step>
<para>Les modifications n&eacute;cessaires pour que le code
fonctionne sous FreeBSD sont appliqu&eacute;es&nbsp;-&nbsp;c'est
ce que l'on appelle <firstterm>patcher</firstterm>.</para>
</step>
<step>
<para>Les op&eacute;rations particuli&egrave;res de configuration
du source sont effectu&eacute;es. (De nombreuses distributions de
programmes Unix essayent de d&eacute;terminer sur quel
syst&egrave;me elles sont compil&eacute;es et de quelles
fonctionnalit&eacute;s Unix optionnelles il
dispose&nbsp;-&nbsp;c'est &agrave; ce stade du sc&eacute;nario
d'installation de logiciels sous FreeBSD que leur sont fournies
ces informations).</para>
</step>
<step>
<para>Le code source du programme est compil&eacute;. De fait, on
passe dans le r&eacute;pertoire o&ugrave; le code a
&eacute;t&eacute; d&eacute;compact&eacute; et
<command>make</command> y est ex&eacute;cut&eacute;&nbsp;-&nbsp;le
<filename>Makefile</filename> du programme lui-m&ecirc;me contient
les informations n&eacute;cessaires &agrave; sa
compilation.</para>
</step>
<step>
<para>Nous disposons maintenant d'une version compil&eacute;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&eacute;quat; une entr&eacute;e sera aussi
cr&eacute;&eacute;e dans une <database>base de donn&eacute;es des
logiciels</database>, de fa&ccedil;on &agrave; ce qu'il puisse
&ecirc;tre d&eacute;sinstall&eacute; 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&eacute;dure de quatre
lignes!</para>
<para>Le secret se trouve &agrave; la derni&egrave;re ligne, qui dit
&agrave; <command>make</command> d'aller voir ce qu'il y a dans le
<filename>Makefile</filename> appel&eacute;
<filename>bsd.port.mk</filename>. Il est facile de rater cette ligne,
mais c'est pourtant de l&agrave; que vient toute la m&eacute;canique
subtile. Quelqu'un a &eacute;crit un <filename>Makefile</filename>
qui dit &agrave; <command>make</command> de faire tout ce qui a
&eacute;t&eacute; d&eacute;crit ci-dessus (plus deux ou trois autres
choses dont je n'ai pas parl&eacute;, 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&egrave;mes, ils sont dans le
r&eacute;pertoire <filename>/usr/share/mk</filename>, mais il vaut
mieux attendre d'avoir un peu d'exp&eacute;rience des
<filename>Makefile</filename>s, parce qu'ils sont tr&egrave;s
compliqu&eacute;s (et si vous les regardez, ayez sous la main
une bonne dose de caf&eacute; serr&eacute;!).</para>
</sect2>
<sect2>
<title>Utilisation plus pouss&eacute;e de <command>make</command></title>
<para> <command>make</command> est un outil tr&egrave;s puissant, et peut
faire beaucoup plus que l'exemple &eacute;l&eacute;mentaire que nous
avons donn&eacute;. Il y a malheureusement plusieurs versions de
<command>make</command>, et elles sont tr&egrave;s
diff&eacute;rentes. La meilleure fa&ccedil;on de savoir ce qu'elles
peuvent faire est certainement de lire la
documentation&nbsp;-&nbsp;esp&eacute;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&eacute;pertoire.</para>
<para>Il y a des nombreux logiciels du catalogue des logiciels
port&eacute;s qui utilisent <application>GNU make</application>, qui
est tr&egrave;s bien document&eacute; dans les pages
&ldquo;info&rdquo;. Si vous avez install&eacute; un de ces logiciels,
<application>GNU make</application> sera automatiquement install&eacute;
sont le nom <command>gmake</command>. Il est aussi disponible sous forme
de logiciel port&eacute; ou pr&eacute;compil&eacute; autonome.</para>
<para>Pour visualiser les pages &ldquo;info&rdquo; de
<application>GNU make</application>, il vous faut &eacute;diter le
fichier <filename>dir</filename> du r&eacute;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&eacute;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&eacute;boguer</title>
<sect2>
<title>Le d&eacute;bogueur</title>
<para>Le d&eacute;bogueur qui est fourni avec FreeBSD s'appelle
<command>gdb</command>
(<application>GNU d&eacute;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&eacute;f&egrave;rent l'ex&eacute;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&eacute;bogueur vous permet d'ex&eacute;cuter le
programme sous contr&ocirc;le. Vous pouvez typiquement
l'ex&eacute;cuter pas &agrave; pas, inspecter les valeurs des
variables, les modifier, dire au d&eacute;bogueur d'ex&eacute;cuter
le programme jusqu'&agrave; un certain endroit et de s'y
arr&ecirc;ter, et ainsi de suite. Vous pouvez m&ecirc;me
le rattacher &agrave; un programme qui est d&eacute;j&agrave; en
cours d'ex&eacute;cution, ou charger une image
m&eacute;moire&nbsp;-&nbsp;&ldquo;<foreignphrase>core</foreignphrase>&rdquo;.
Il est m&ecirc;me possible de d&eacute;boguer le noyau, bien que cela
soit un peu plus compliqu&eacute; 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&eacute;e
<ulink URL="http://www.freebsd.org/ports/devel.html">xxgdb</ulink>
au catalogue des logiciels port&eacute;s.</para>
<para>Cette section est destin&eacute;e &agrave; servir d'introduction
&agrave; l'utilisation du d&eacute;bogueur et ne couvre pas les
questions sp&eacute;cialis&eacute;es comme le d&eacute;bogage du
noyau.</para>
</sect2>
<sect2>
<title>Ex&eacute;cuter un programme sous le d&eacute;bogueur</title>
<para>Il faudra que vous ayez compil&eacute; 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 &ecirc;tes, au
lieu du code source. Si vous avez un message du genre:
<screen>&hellip; (no debugging symbols found) &hellip;</screen>
au d&eacute;marrage de <command>gdb</command>, vous saurez que le
programme n'a pas &eacute;t&eacute; compil&eacute; avec l'option
<option>-g</option>.</para>
<para>A l'invite de <command>gdb</command>, tapez <userinput>break
main</userinput>. Cela dira au d&eacute;bogueur d'ex&eacute;cuter le
code pr&eacute;liminaire de mise en oeuvre dans le programme et de
s'arr&ecirc;ter au d&eacute;but de votre programme. Tapez maintenant
<userinput>run</userinput> pour lancer le programme&nbsp;-&nbsp;il
commencera au d&eacute;but du code pr&eacute;liminaire et sera
interrompu par le d&eacute;bogueur sur l'appel de
<function>main()</function>. (Si vous vous &eacute;tiez jamais
demand&eacute; d'o&ugrave; la fonction <function>main()</function>
&eacute;tait appel&eacute;e, vous le savez maintenant!).</para>
<para>Vous pouvez maintenant ex&eacute;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&eacute;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&egrave;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&eacute; %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&egrave;tre.</para>
<para>Quand nous compilons et ex&eacute;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&eacute; 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&eacute;cuter le code d'initialisation</lineannotation>
Breakpoint 1 at 0x160f: file temp.c, line 9. <lineannotation><command>gdb</command> met un pont d'arr&ecirc;t &agrave; l'appel de <function>main()</function></lineannotation>
(gdb) <userinput>run</userinput> <lineannotation>Ex&eacute;cuter jusqu'&agrave; <function>main()</function></lineannotation>
Starting program: /home/james/tmp/temp <lineannotation>Le programme d&eacute;marre</lineannotation>
Breakpoint 1, main () at temp.c:9 <lineannotation><command>gdb</command> s'arr&ecirc;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&eacute;
&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&eacute;
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&eacute; la ligne <literal>i=5;</literal>.
Comme nous n'avons pas initialis&eacute; <symbol>i</symbol>, il
prend la valeur qui se trouve &agrave; cet endroit de la
m&eacute;moire quand le programme s'ex&eacute;cute, dans notre
cas, il s'est trouv&eacute; que c'&eacute;tait
<literal>4231</literal>.</para>
<note>
<para><command>gdb</command> affiche l'endroit o&ugrave; nous nous
trouvons dans la pile d'appel, chaque fois que nous entrons ou
sortons d'une fonction, m&ecirc;me si nous utilisons
<command>up</command> et <command>down</command> pour nous
d&eacute;placer dans la pile. Cela nous donne le nom de la fonction
et les valeurs de ses param&egrave;tres, ce qui nous aide &agrave;
rep&eacute;rer o&ugrave; nous sommes et ce qu'il se passe. (La pile
d'appel est une zone de m&eacute;moire o&ugrave; le programme
enregistre les informations sur les param&egrave;tres pass&eacute;s
aux fonctions et o&ugrave; aller quand il ressort d'un fonction
appel&eacute;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'&eacute;tat complet du
programme au moment o&ugrave; il s'est &ldquo;plant&eacute;&rdquo;. Au
&ldquo;bon vieux temps&rdquo;, les programmeurs devaient imprimer le
contenu en hexad&eacute;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&egrave;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&ccedil;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'&ecirc;tes pas dans le m&ecirc;me r&eacute;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&eacute; en erreur &agrave; cause d'une tentative
d'acc&egrave;s &agrave; une zone de m&eacute;moire qui n'&eacute;tait
pas accessible dans une fonction appel&eacute;
<function>bazz</function>.</para>
<para>Il est parfois utile de pouvoir savoir comment une fonction a
&eacute;t&eacute; appel&eacute;e, parce que le probl&egrave;me peut
s'&ecirc;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&eacute;e quand un
programme &eacute;choue; dans le cas pr&eacute;sent, la fonction
<function>bazz()</function> a &eacute;t&eacute; appel&eacute;e par
<function>main()</function>.</para>
</sect2>
<sect2>
<title>Prendre le contr&ocirc;le d'un programme en cours
d'ex&eacute;cution</title>
<para>Une des possibilit&eacute;s les plus int&eacute;ressantes de
<command>gdb</command> est qu'il peut se rattacher &agrave; un
programme en cours d'ex&eacute;cution. Il faut bien s&ucirc;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&egrave;me classique, lorsque vous voulez suivre le
d&eacute;roulement du processus fils, alors que le d&eacute;bogueur ne
vous permet que de tracer le processus p&egrave;re.</para>
<para>Vous lancez alors un autre <command>gdb</command>, utilisez
<command>ps</command> pour conna&icirc;tre l'IDentifiant de processus du
fils, puis faites:
<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
sous <command>gdb</command>, et d&eacute;boguez alors comme
d'habitude.</para>
<para>&ldquo;Tout cela est bien beau&rdquo;, vous dites vous
peut-&ecirc;tre, &ldquo;mais le temps que j'ai fait tout &ccedil;a, le
processus fils aura d&eacute;j&agrave; fait un bon bout de
chemin&rdquo;. Rien &agrave; craindre, aimable lecteur, voici ce
qu'il faut faire (emprunt&eacute; aux pages &ldquo;info&rdquo; de
<command>gdb</command>):
<screen><lineannotation>&hellip</lineannotation>
if ((pid = fork()) < 0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* _Toujours_ effectuer se contr&ocirc;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&eacute;veloppement</title>
<sect2>
<title>Emacs</title>
<para>Les syst&egrave;mes Unix ne s'accompagnent malheureusement pas
du type d'environnement de d&eacute;veloppement
int&eacute;gr&eacute; 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&egrave;mes<footnote><para>Au moins, pas
&agrave; moins que vous ne soyez pr&ecirc;t &agrave; les payer une somme
astronomique.</para></footnote>. Il est cependant possible de mettre
au point votre propre environnement. Il ne sera peut-&ecirc;tre pas
aussi esth&eacute;tique et il ne sera peut-&ecirc;tre pas aussi
int&eacute;gr&eacute;, 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&eacute; de tout. Il y a bien des gens qui le
d&eacute;crient, mais nombreux sont ceux qui l'aiment. Si vous
&ecirc;tes des premiers, j'ai peur que cette section n'ait que peu
d'int&eacute;r&ecirc;t pour vous. Il vous faudra aussi pas mal de
m&eacute;moire pour l'utiliser. Je conseille 8Mo en mode texte et
16Mo sous X comme strict minimum pour avoir des temps de r&eacute;ponse
raisonnables.</para>
<para>Emacs est essentiellement un &eacute;diteur extr&ecirc;mement
configurable&nbsp;-&nbsp;il a de fait &eacute;t&eacute; configur&eacute;
au point de ressembler plus &agrave; un syst&egrave;me
d'exploitation qu'&agrave; un &eacute;diteur! De nombreux
d&eacute;veloppeurs et administrateurs syst&egrave;me passent le plus
clair de leur temps &agrave; travailler sous Emacs, le quittant
seulement pour se d&eacute;connecter.</para>
<para>Il est impossible de m&ecirc;me r&eacute;sumer ici tout ce qu'Emacs
est capable de faire, mais voici quelques fonctionnalit&eacute;s qui
int&eacute;ressent les d&eacute;veloppeurs:
<itemizedlist>
<listitem>
<para>Editeur tr&egrave;s puissant qui permet et de rechercher et
remplacer des cha&icirc;nes de caract&egrave;res et d'utiliser pour
le faire des expressions r&eacute;guli&egrave;res (motifs), d'aller
au d&eacute;but ou &agrave; la fin de blocs syntaxiques, etc,
etc.</para>
</listitem>
<listitem>
<para>Menus d&eacute;roulants et aide en ligne.</para>
</listitem>
<listitem>
<para>Mise en valeur et indentation en fonction de la syntaxe du
langage utilis&eacute;.</para>
</listitem>
<listitem>
<para>Compl&egrave;tement configurable.</para>
</listitem>
<listitem>
<para>Vous pouvez compiler et d&eacute;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&ecirc;me.</para>
</listitem>
<listitem>
<para>Interface conviviale pour <command>gdb</command>, qui vous
permet de visualiser le code source en m&ecirc;me temps que vous
ex&eacute;cutez pas &agrave; pas le programme.</para>
</listitem>
<listitem>
<para>Vous pouvez lire les &ldquo;news&rdquo; Usenet et votre
courrier &eacute;lectronique pendant que votre programme
compile.</para>
</listitem>
</itemizedlist>
Et sans aucun doute bien d'autres choses qui m'ont
&eacute;chapp&eacute;es.</para>
<para>Emacs peut &ecirc;tre install&eacute; sous FreeBSD sous forme de
<ulink URL="http://www.freebsd.org/ports/editors.html">logiciel
port&eacute;</ulink>.</para>
<para>Une fois qu'il est install&eacute;, lancez-le et tapez
<userinput>C-h t</userinput>&nbsp;-&nbsp;ce qui signifie maintenir
enfonc&eacute;e la touche <keycap>Ctrl</keycap>, taper
<keycap>h</keycap>, rel&acirc;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&eacute;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 &eacute;ditez quelque chose d'appuyer sur deux ou trois
touches que de courir apr&egrave;s la souris et cliquer ensuite au bon
endroit. Si, par ailleurs, vous discutez avec des utilisateurs
exp&eacute;riment&eacute;s d'Emacs, vous vous aperceverez 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&ccedil;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&eacute;couvrir les raccourcis
claviers, ils sont affich&eacute;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&eacute;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&icirc;tre
toutes les commandes comportant un mot donn&eacute; et les touches qui
leur correspondent.</para>
<para>Au fait, l'expression plus haut signifie: enfoncer la touche
<keysym>M&eacute;ta</keysym>, appuyer sur <keysym>x</keysym>,
rel&acirc;cher la touche <keysym>M&eacute;ta</keysym>, taper
<userinput>replace-s</userinput> (abr&eacute;viation de
<literal>replace-string</literal>&nbsp;-&nbsp;&ldquo;<foreignphrase>remplacer
une cha&icirc;ne de caract&egrave;res</foreignphrase>&rdquo;&nbsp;-&nbsp;une autre
caract&eacute;ristique d'Emacs est de vous permettre d'abr&eacute;ger
les commandes), appuyer sur <keysym>Entr&eacute;e</keysym>, taper
<userinput>foo</userinput> (la cha&icirc;ne que vous voulez remplacer),
appuyer sur <keysym>Entr&eacute;e</keysym>, taper
<userinput>bar</userinput> (la cha&icirc;ne avec laquelle vous voulez
remplacer <literal>foo</literal>) et appuyer encore sur
<keysym>Entr&eacute;e</keysym>. Emacs effectuera alors
l'op&eacute;ration de recherche et remplacement que vous venez de
demander.</para>
<para>Si vous vous demandez ce qu'est la touche
<keysym>M&eacute;ta</keysym>, c'est une touche sp&eacute;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&eacute;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&acirc;cher la
touche <keysym>Ctrl</keysym>). S'il y a des fichiers ouverts que vous
n'avez pas sauvegard&eacute;s, Emacs vous demandera si vous voulez les
sauvegarder. (Oubliez que la documentation dit que la m&eacute;thode
habituelle pour quitter Emacs est d'utiliser
<command>C-z</command>&nbsp;-&nbsp;cela laisse Emacs actif en
t&acirc;che de fond et n'est r&eacute;ellement utile que si vous
&ecirc;tes sur un syst&egrave;me qui ne g&egrave;re pas de terminaux
virtuels).</para>
</sect2>
<sect2>
<title>Configurer Emacs</title>
<para>Emacs fait des choses admirables; certaines fonctionnalit&eacute;s
sont incorpor&eacute;es, d'autres doivent &ecirc;tre
configur&eacute;es.</para>
<para>Au lieu d'utiliser un langage de macros-instructions
propri&eacute;taires, Emacs se sert d'une version de Lisp
sp&eacute;cialement adapt&eacute;e aux &eacute;diteurs, connue sous le
nom de Emacs Lisp. Ce peut &ecirc;tre tr&egrave;s utile si vous voulez
aller plus loin et apprendre ensuite par exemple Common Lisp, parce
qu'il est consid&eacute;rablement plus l&eacute;ger que Common Lisp
(quoique qu'encore assez imposant!).</para>
<para>La meilleure fa&ccedil;on d'apprendre Emacs Lisp est de
t&eacute;l&eacute;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&icirc;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&eacute;but. Copiez-le simplement dans votre
r&eacute;pertoire utilisateur et relancez Emacs, s'il s'ex&eacute;cute
d&eacute;j&agrave;; il lira les commandes du fichier et (je
l'esp&egrave;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&eacute;tails; il y a cependant un ou deux points
int&eacute;ressants &agrave; mentionner.</para>
<para>
<itemizedlist>
<listitem>
<para>Tout ce qui commence par un <literal>;</literal> est en
commentaire et est ignor&eacute; par Emacs.</para>
</listitem>
<listitem>
<para>La premi&egrave;re ligne,
<literal>-*-&nbsp;Emacs-Lisp&nbsp;-*-</literal> permet
d'&eacute;diter le fichier <filename>.emacs</filename>
lui-m&ecirc;me sous Emacs et de profiter de toutes les
fonctionnalit&eacute;es li&eacute;es &agrave; l'&eacute;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&eacute;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&egrave;re <token>tabulation</token> dans
votre texte, enfoncer la touche <keysym>Ctrl</keysym> en
m&ecirc;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&eacute;terminant le langage
d'apr&egrave;s le nom du fichier &eacute;dit&eacute;.</para>
</listitem>
<listitem>
<para>Emacs a d&eacute;j&agrave; une fonction
pr&eacute;d&eacute;finie appel&eacute;e
<function>next-error</function>&nbsp;-&nbsp;&ldquo;<foreignphrase>erreur
suivante</foreignphrase>&rdquo;. Dans la fen&ecirc;tre de
r&eacute;sultats d'une compilation, cela vous permet d'aller
d'une erreur &agrave; la suivante avec <command>M-n</command>;
nous d&eacute;finissons la fonction compl&eacute;mentaire
<function>previous-error</function>&nbsp;-&nbsp;&ldquo;<foreignphrase>erreur
pr&eacute;c&eacute;dente</foreignphrase>&rdquo;, qui vous permet
de retourner &agrave; l'erreur pr&eacute;c&eacute;dente avec
<command>M-p</command>. Le plus sympathique est que
<command>C-c C-c</command> ouvrira le fichier source o&ugrave;
l'erreur s'est produite et ira &agrave; la ligne
concern&eacute;e.</para>
</listitem>
<listitem>
<para>Nous activons la possibilit&eacute; qu'a Emacs d'agir comme
serveur, de fa&ccedil;on &agrave; ce que si vous travaillez hors
d'Emacs et voulez &eacute;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&ccedil;on &agrave;
ce que ce soit ce qui se produise chaque fois qu'ils ont besoin
d'&eacute;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&ccedil;u pour &ecirc;tre relu; la variable
;; first-time est utilis&eacute;e pour &eacute;viter les probl&egrave;mes
;; que cela pourra poser.
(defvar first-time t
"Indicateur signifiant que le fichier .emacs est lu pour la premi&egrave;re fois")
;; M&eacute;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&egrave;re tabulation.
(setq backup-by-copying-when-mismatch t)
;; 'y' ou &lt;CR&gt; &eacute;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 &eacute;volu&eacute;
(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&eacute;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&eacute;s")
(defun font-lock-auto-mode-select ()
"S&eacute;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&eacute;c&eacute;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&eacute;c&eacute;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&eacute;er une apparence pour une couleur, &eacute;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 &eacute;crivant directement &agrave; l'&eacute;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&eacute;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&egrave;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 &eacute;t&eacute; lu au moins une fois
(setq first-time nil)
;; Plus besoin de d&eacute;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&egrave;s bien si vous ne voulez programmer
qu'avec les langages d&eacute;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&eacute;
&ldquo;whizbang&rdquo; fait son apparition, avec plein de nouvelles
fonctionnalit&eacute;s attrayantes?</para>
<para>La premi&egrave;re chose &agrave; faire est de regarder si whizbang
s'accompagne de fichiers de configuration d'Emacs pour ce langage.
Ces fichiers ont g&eacute;n&eacute;ralement comme extension
<filename>.el</filename>, raccourci pour &ldquo;Emacs Lisp&rdquo;.
Par exemple, si whizbang est un logiciel port&eacute; pour FreeBSD,
ces fichiers peuvent &ecirc;tre rep&eacute;r&eacute;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&eacute;pertoire du
&ldquo;site Lisp&rdquo; d'Emacs. Sous FreeBSD 2.1.0-RELEASE, c'est le
r&eacute;pertoire
<filename>/usr/local/share/emacs/site-lisp</filename>.</para>
<para>Ainsi par exemple, si la commande pr&eacute;c&eacute;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&eacute;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&eacute;e &agrave; notre fichier <filename>.emacs</filename>,
pour &ecirc;tre s&ucirc;r qu'Emacs puisse utiliser les informations du
fichier <filename>whizbang.el</filename>.</para>
<para>Recherchons l'entr&eacute;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'&eacute;dition d'un
fichier d'extension <filename>.wiz</filename>.</para>
<para>Juste apr&egrave;s, il y a une entr&eacute;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&eacute;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'&eacute;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>