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