<!--
     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>
