<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://www.finiderire.com/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Vim est ton ami.</title>
  <link>http://www.finiderire.com/</link>
  <atom:link href="http://www.finiderire.com/feed/rss2" rel="self" type="application/rss+xml"/>
  <description>Pour les codeurs qui ne perdent pas leur temps avec les IDE.</description>
  <language>fr</language>
  <pubDate>Wed, 28 Jul 2010 14:37:53 +0200</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Oukiléleclavier ? Oukellélasouris ? (ou: la bonne blague de Xorg)</title>
    <link>http://www.finiderire.com/post/2010/05/01/Oukil%C3%A9leclavier-Oukell%C3%A9lasouris-%28ou%3A-la-bonne-blague-de-XOrg%29</link>
    <guid isPermaLink="false">urn:md5:afb6042d2ed71447df41c784b28c528d</guid>
    <pubDate>Wed, 05 May 2010 18:47:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Linuxeries</category>
        <category>Gentoo</category><category>Linux</category><category>pénible</category>    
    <description>&lt;p&gt;&lt;em&gt;Je me suis aperçu qu'il manquait un tag à mes billets.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Comment caractériser toutes ces nuisances qui gachent la vie de l'honnête
administrateur système ?&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;J'inaugure dès à présent le tag &lt;q&gt;pénible&lt;/q&gt; avec Xorg&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Situation de départ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Le but était de faire 'une mise à jour de Xorg sous Gentoo.
&lt;ul&gt;
&lt;li&gt;Pour ma part, il s'agissait de passer le serveur Xorg de la version 1.3 à
la version 1.6.5.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Avis aux mécréants utilisateurs d'autres unixeries que Gentoo :
continuez à lire, ceci concerne au moins également FreeBSD et Arch-Linux.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Echauffement&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Installer Xorg implique souvent la mise à jour d'autres paquets.&lt;/li&gt;
&lt;li&gt;Avant même le passage au paquet &lt;em&gt;xorg-server&lt;/em&gt;, nous rencontrons une
erreur.&lt;/li&gt;
&lt;li&gt;La &lt;em&gt;libpciaccess&lt;/em&gt; (en update) essaie d'installer un exécutable
(&lt;em&gt;scanpci&lt;/em&gt;) mais refuse de remplacer la version précédente.
&lt;ul&gt;
&lt;li&gt;Cet exécutable provoque un conflit, car c'est un autre ebuild qui a
construit la version précédente.&lt;/li&gt;
&lt;li&gt;On ne peut donc pas le supprimer sans réfléchir, car cela risquerait de
casser l'autre ebuild.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Laissez tomber la méthode de résolution suggérée dans les messages, et
faites plutôt:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;equery b scanpci&lt;/code&gt; : vous obtenez le nom du paquet qui
contient l'ancienne version à remplacer.&lt;/li&gt;
&lt;li&gt;Il s'agissait du Xorg que vous tentez d'updater. Ma méthode (votre avis
peut varier) : &lt;code&gt;emerge -C xorg-server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Une fois ceci rêglé, vous pouvez relancer la mise à jour de
&lt;em&gt;xorg-server&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Plus de clavier, plus de souris&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pour le reste, la compilation, se passe plutôt bien.&lt;/li&gt;
&lt;li&gt;Un &lt;code&gt;emerge -va nvidia-drivers&lt;/code&gt; plus tard, Xorg démarre
enfin.&lt;/li&gt;
&lt;li&gt;Et là, plus de souris (huho) ni de clavier (haha).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Rendez moi mon clavier! (et ma souris aussi!)&lt;/h3&gt;
&lt;h5&gt;Sortie de Xorg&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Alors là, attention, c'est technique.
&lt;ul&gt;
&lt;li&gt;Appuyez pendant 5 secondes sur le bouton marche/arrêt du PC.&lt;/li&gt;
&lt;li&gt;Si vous avez ACPI dans le noyau avec un script sur le bouton marche/arrêt,
vous êtes sauvé et la solution déplorable de la ligne du dessus ne sera pas
nécessaire.&lt;/li&gt;
&lt;li&gt;Les heureux utilisateurs d'un réseau local pourront également faire un
&lt;em&gt;ssh&lt;/em&gt; sur la machine coincée. Beaucoup plus propre, mais nécessite un
cable réseau et un autre PC (et un daemon sshd sur la machine bloquée).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Divination avec les logs&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Après le reboot, et en supposant que vous n'avez pas eu de problème de
journalisation, vous vous retrouvez à nouveau devant la console.
&lt;ul&gt;
&lt;li&gt;Si vous n'avez pas de chance, X est relancé aussi sec. Dans ce cas, il va
falloir changer le niveau de démarrage de votre Linux.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Dans le log de Xorg, nous trouvons la source du problème (je ne vous montre
que la partie concernant le clavier, la même chose est observable pour la
souris):&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

$~  less /var/log/Xorg.0.log
(II) LoadModule: &amp;quot;kbd&amp;quot;
(II) Loading /usr/lib/xorg/modules/input//kbd_drv.so
(II) Module kbd: vendor=&amp;quot;X.Org Foundation&amp;quot;
        compiled for 1.3.0, module version = 1.1.0
        Module class: X.Org XInput Driver
        ABI class: X.Org XInput driver, version 0.7
(EE) module ABI major version (0) doesn't match the server's version (4)
(II) UnloadModule: &amp;quot;kbd&amp;quot;
(II) Unloading /usr/lib/xorg/modules/input//kbd_drv.so
(EE) Failed to load module &amp;quot;kbd&amp;quot; (module requirement mismatch, 0)

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Parenthèse pour les paresseux&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Si vous n'avez pas fait de mise à jour de Xorg depuis &lt;em&gt;vraiment&lt;/em&gt;
très longtemps, il se peut que vous ayez un autre problème.&lt;/li&gt;
&lt;li&gt;En effet, dans la config de Xorg, les devices ont changé de nom à un moment
donné.&lt;/li&gt;
&lt;li&gt;Vérifiez donc que votre clavier et votre souris ont bien le driver
convenable.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

Section &amp;quot;InputDevice&amp;quot;

    Identifier  &amp;quot;Keyboard1&amp;quot;
    Driver      &amp;quot;kbd&amp;quot;

(snip)
    Identifier  &amp;quot;Mouse1&amp;quot;
    Driver      &amp;quot;mouse&amp;quot;

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Je ne saurais en dire plus à ce sujet, car je n'ai que de vagues souvenirs
de ce problème.
&lt;ul&gt;
&lt;li&gt;De toutes façons, le problème a dû disparaitre de lui-même, depuis le
temps. (l'optimisme est rare de nos jours, sachons le cultiver.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Revenons à nos moutons&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il vous manque simplement deux mises à jour, oubliées par
&lt;em&gt;emerge&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;emerge -va xf86-input-keyboard&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;emerge -va xf86-input-mouse&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;A noter que le problème se posera probablement également avec votre
joystick, votre tablette graphique, et autres périphériques d'entrée.
&lt;ul&gt;
&lt;li&gt;Un simple &lt;code&gt;eix xf86-input&lt;/code&gt; vous en convaincra aisément.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Keyboard not found. Press F1 to continue.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;J'ai profité de mon clavier retrouvé pour écrire ce billet.&lt;/li&gt;
&lt;li&gt;Comme je ne vais pas non plus tout faire, je vous laisse écrire les
commentaires.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2010/05/01/Oukil%C3%A9leclavier-Oukell%C3%A9lasouris-%28ou%3A-la-bonne-blague-de-XOrg%29#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2010/05/01/Oukil%C3%A9leclavier-Oukell%C3%A9lasouris-%28ou%3A-la-bonne-blague-de-XOrg%29#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/513081</wfw:commentRss>
      </item>
    
  <item>
    <title>MPD : le stream était presque parfait</title>
    <link>http://www.finiderire.com/post/2010/04/27/MPD-%3A-le-stream-%C3%A9tait-presque-parfait</link>
    <guid isPermaLink="false">urn:md5:68cc9eb57ffae22afedbc3ec6cde04fa</guid>
    <pubDate>Wed, 28 Apr 2010 00:11:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Linuxeries</category>
        <category>Gentoo</category><category>Linux</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;Aujourd'hui, ce sont mes aventures pour streamer de la musique avec
mpd.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Car mpd est beau, mpd est grand, mpd streame!&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Merci à Frédéric Jolliton pour le coup de main lors de la mise au point.
(et il a relu et clarifié, en plus)&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;MàJ 13 mai 2010&lt;/strong&gt; : gagner trois ko de bande passante
avec shh&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Résumé des épisodes précédents&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ce n'était pas forcément le plus intéressant, mais le premier billet est
ici:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.finiderire.com/post/2008/07/09/MPD-%3A-Musique-Par-le-Daemon&quot;&gt;MPD - musique par
le daemon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le streaming n'était pas le sujet de ce billet. Dans ma grande bonté, j'en
refais donc un complet.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Comprenons-nous bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ce titre légèrement menaçant fait un peu vendeur de &lt;em&gt;savonnettes
dé-régulées&lt;/em&gt; cherchant à forcer l'entrée de votre habitation. Cette fois,
il ne s'agit que d' une nécessaire introduction à ce qu'est réellement
mpd.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;De l'avantage du stream&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Pourquoi écouter un stream , et ne pas décoder en local ?
&lt;ul&gt;
&lt;li&gt;Vous ne compilerez qu'une fois le player.&lt;/li&gt;
&lt;li&gt;Vous ne dupliquez pas vos fichiers, vous n'avez pas besoin de les promener
sur une clé usb ou un disque externe.&lt;/li&gt;
&lt;li&gt;Vous allez faire l'envie de vos voisins (en général, cet argument suffit à
emporter la décision).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;mpd n'est pas forcément ce que l'on croit&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;mpd est un player dont la sortie sonore se fait en &lt;strong&gt;local&lt;/strong&gt;
par défaut (c'est à dire, sur la machine où mpd est lancé).
&lt;ul&gt;
&lt;li&gt;Les clients de mpd, tels que &lt;strong&gt;ncmpc&lt;/strong&gt; ou
&lt;strong&gt;gmpc&lt;/strong&gt; (client Gnome) ne sont rien d'autre que des télécommandes
pour mpd.&lt;/li&gt;
&lt;li&gt;Aucun d'entre eux ne permet d'écouter un stream.&lt;/li&gt;
&lt;li&gt;Ils ne savent qu'envoyer des commandes au daemon mpd.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Un &lt;em&gt;client mpd&lt;/em&gt; est une télécommande ... donc cela signifie que seul
le PC faisant tourner le serveur est en mesure de sortir du son, et que tous
les clients associés à mpd ne servent qu'à contrôler celui-ci à distance ?
&lt;ul&gt;
&lt;li&gt;Exactement ! Je n'aurais su mieux le dire !&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;mais mpd peut streamer&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Néanmoins, si les clients spécifiques à mpd ne peuvent que le contrôler,
mpd est capable de différents rendus.
&lt;ul&gt;
&lt;li&gt;Les sorties locales, avec la configuration OSS , Alsa ou ... &lt;q&gt;null&lt;/q&gt;
(qui est bien un rendu local)&lt;/li&gt;
&lt;li&gt;Des sorties streamées, avec entre autres un serveur shoutcast, ou son
serveur interne httpd.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous allons utiliser le serveur intégré à mpd, qui streame sans fioritures,
tel une web-radio.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Dès à présent, il est utile de préciser que nous allons utiliser deux
ports.
&lt;ul&gt;
&lt;li&gt;Le port de commande de mpd, sur lequel nous pouvons connecter un client, ou
lancer un &lt;code&gt;telnet&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Le port utilisé par mpd pour servir le stream. Celui-ci n'est actif que
quand de la musique est jouée. Il est fermé dès que la musique est
stoppée.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Préparation et configuration de mpd&lt;/h3&gt;
&lt;h5&gt;Flags de compilation Gentoo&lt;/h5&gt;
&lt;pre&gt;

media-sound/mpd -alsa -ffmpeg mikmod musepack ogg vorbis lame

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Votre avis concernant ffmpeg pourra varier, mais j'ai préféré limiter les
temps de compilation sur une machine un peu limitée.&lt;/li&gt;
&lt;li&gt;J'ai bien sûr retiré toute référence à Alsa (OSS étant inactif par défaut),
vu que la machine hébergeant le serveur n'a même pas de carte son.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Création des répertoires nécessaires&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;mpd peut être lancé par un utilisateur lambda.
&lt;ul&gt;
&lt;li&gt;Vous devriez mettre sa configuration dans le &lt;em&gt;home&lt;/em&gt; de celui-ci, et
ajuster le paramètre &lt;em&gt;user&lt;/em&gt; dans le fichier de configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Fichier de configuration&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Voici mon fichier de configuration.
&lt;ul&gt;
&lt;li&gt;Je n'ai pas inclu tout ce qui ne sert pas, reportez vous au fichier
&lt;q&gt;/etc/mpd.conf&lt;/q&gt; pour plus de précisions.&lt;/li&gt;
&lt;li&gt;Pour vos essais, vous pouvez simplifier la situation en ne mettant pas de
mot de passe, par exemple.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

music_directory  &amp;quot;/home/toto/music&amp;quot;
playlist_directory  &amp;quot;/home/toto/mpd/playlists&amp;quot;
db_file  &amp;quot;/home/toto/mpd/database&amp;quot;
log_file  &amp;quot;/home/toto/mpd/mpd.log&amp;quot;
pid_file  &amp;quot;/home/toto/mpd/mpd.pid&amp;quot;
state_file  &amp;quot;/home/toto/mpd/state&amp;quot;
user  &amp;quot;toto&amp;quot;
bind_to_address  &amp;quot;0.0.0.0&amp;quot;
port  &amp;quot;1234&amp;quot;
password  &amp;quot;password@read,add,control,admin&amp;quot;
default_permissions  &amp;quot;&amp;quot; #pas de bras, pas de chocolat.

input {
        plugin &amp;quot;curl&amp;quot;
}

audio_output {
        type  &amp;quot;httpd&amp;quot;
       name  &amp;quot;My HTTP Stream&amp;quot;
        encoder  &amp;quot;lame&amp;quot;  # optional, vorbis or lame
        port  &amp;quot;5678&amp;quot;
        bitrate  &amp;quot;128&amp;quot;  # do not define if quality is defined
        format  &amp;quot;44100:16:1&amp;quot;
}
filesystem_charset &amp;quot;UTF-8&amp;quot;

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bind_to_address&lt;/strong&gt; : ne mettez &lt;strong&gt;surtout
pas&lt;/strong&gt; &lt;em&gt;localhost&lt;/em&gt; ou &lt;em&gt;127.0.0.1&lt;/em&gt; :
&lt;ul&gt;
&lt;li&gt;Cela provoquerait un bind de mpd sur l'interface loopback. Toute connexion
externe serait alors impossible.&lt;/li&gt;
&lt;li&gt;A la place de 0.0.0.0 on peut mettre l'IP d'une carte réseau. Par exemple
pour une machine directement sur le net (avec une IP publique) on veut pas
forcément rendre mpd accessible. Alors qu'en mettant l'IP de la machine sur le
LAN (disons 192.168.1.1) ça ne sera accessible que sur le réseau local.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;default_permissions&lt;/strong&gt; : pour vos essais en connexion
anonyme (sans mot de passe), vous pouvez mettre les permissions à fond avec
&lt;q&gt;read,add,control,admin&lt;/q&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Premier lancement&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Placez quelques fichiers musicaux dans le répertoire définit comme
&lt;em&gt;music_directory&lt;/em&gt; dans le fichier de configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le premier lancement se fera en local, avec l'utilisateur configuré dans
mpd.conf&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Au passage, nous allons créer la base de données.
&lt;ul&gt;
&lt;li&gt;Par la suite, la commande &lt;q&gt;update&lt;/q&gt; sera envoyée par un client
mpd.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

toto@serveur ~$ mpd --create-db

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;En cas d'erreur, ou de modification de la base, vous pouvez tuer le serveur
avec :
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kill $(pidof mpd)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Par la suite, vous pourrez utiliser les scripts Gentoo (ou de votre
distrib) pour demander le démarrage de mpd au boot.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Test rapide avec telnet&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Plus qu'à tenter un telnet sur le port de votre serveur&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez trouver toutes les commandes comprises par mpd ici:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://mpd.wikia.com/wiki/MusicPlayerDaemonCommands&quot;&gt;commandes
mpd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

toto@serveur ~/.ncmpc $ telnet localhost 1234
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
OK MPD 0.15.0
status
volume: -1
repeat: 0
random: 0
single: 0
consume: 0
playlist: 3
playlistlength: 0
xfade: 0
state: stop
OK
close
Connection closed by foreign host.

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;status&lt;/em&gt; vous permettra d'obtenir rapidement confirmation du
fonctionnement de mpd.
&lt;ul&gt;
&lt;li&gt;Même si la simple réussite de la connexion telnet devrait suffire.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour fermer proprement la session, utilisez &lt;em&gt;close&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;mpc dépanne certes bien...&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Maintenant que le daemon mpd fonctionne, il est temps de tester avec un
logiciel un peu plus évolué, et à distance.
&lt;ul&gt;
&lt;li&gt;Je vous conseille de rester sur le réseau local de mpd, ceci limitera les
ports à ouvrir dans le firewall, et vous pourrez toujours vous passer
d'authentification.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;L'informatique aime les acronymes, et les doublons aussi.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;mpc&lt;/strong&gt; = music player &lt;strong&gt;client&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;ne confondez pas avec les vieux fichiers &lt;em&gt;musepack&lt;/em&gt; (extension
&lt;em&gt;mpc&lt;/em&gt;) que l'on peut jouer avec mpd.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;mpc&lt;/em&gt; est un utilitaire indispensable pour vous éviter des
&lt;code&gt;telnet&lt;/code&gt; rapidement saoulants sur le port du daemon mpd.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Je vous laisse faire &lt;code&gt;man mpc&lt;/code&gt; , le fonctionnement est
trivial.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;...mais ncmpc est toujours le plus beau&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Maintenant que tout semble bien tourner, il est temps de passer au client
qui ne nous quittera plus.&lt;/li&gt;
&lt;li&gt;Avec un nom à coucher dehors, &lt;strong&gt;ncmpc&lt;/strong&gt; est néanmoins le plus
agréable des clients mpd.&lt;/li&gt;
&lt;li&gt;Interprétation personnelle du nom:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;nc&lt;/strong&gt; = &lt;em&gt;ncurses&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mpc&lt;/strong&gt; = &lt;em&gt;music player client&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Version dans Portage (avril 2010)&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;0.14
&lt;ul&gt;
&lt;li&gt;un peu vieille, mais que voulez-vous ...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Flags Gentoo&lt;/h5&gt;
&lt;pre&gt;

media-sound/ncmpc artist-screen colors help-screen key-screen lyrics-screen search-screen song-screen

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Beaucoup de possibilités dans les versions récentes de &lt;em&gt;ncmpc&lt;/em&gt; , y
compris la possibilité d'afficher les paroles des chansons.
&lt;ul&gt;
&lt;li&gt;J'ai activé toutes les options, ça ne mange pas de pain (ni de
ressources).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Erreur possible à la compilation de ncmpc&lt;/h5&gt;
&lt;pre&gt;

match.c:43: attention : implicit declaration of function ‘g_regex_match_simple’
match.c:45: erreur: ‘G_REGEX_CASELESS’ undeclared (first use in this function)

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Dans ce cas, il faut mettre à jour votre glib (pas la glibc , je parle bien
de la glib tout court) et recommencer l'emerge de ncmpc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Fichier de configuration de ncmpc&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il se trouve dans ~/ncmpc/config&lt;/li&gt;
&lt;li&gt;Celui-ci est donné juste pour information. Je n'ai pas encore pris le temps
de fignoler.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

port = 1234
password = &amp;quot;password&amp;quot;
scroll = yes
scroll-sep = &amp;quot; ***** &amp;quot;
enable-colors = yes
color background = black
color list = brightwhite

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Diagnostics&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lancez la lecture d'un fichier avec mpc, ncmpc, telnet, ou ce que vous
voudrez.
&lt;ul&gt;
&lt;li&gt;Ceci doit produire l'envoi du stream sur le port défini pour &lt;em&gt;httpd&lt;/em&gt;
dans la configuration de mpd.&lt;/li&gt;
&lt;li&gt;Le port &lt;em&gt;stream&lt;/em&gt; ne sera ouvert que pendant la génération d'un
stream.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

toto@serveur ~$ netstat -pln | grep mpd
tcp        0      0 0.0.0.0:1234            0.0.0.0:*               LISTEN      3694/mpd
tcp        0      0 0.0.0.0:5678            0.0.0.0:*               LISTEN      3694/mpd

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Les ports utilisés sont ceux définis dans &lt;em&gt;mpd.conf&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Le port de commande de mpd est 1234.&lt;/li&gt;
&lt;li&gt;Le stream est joué sur 5678.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La config du pauvre, mais qui marche tellement bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Et encore j'avais un titre plus long pour cette partie, mais il faut savoir
rester raisonnable.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous allons utiliser un tunnel ssh dans lequel nous ferons passer le flux.
&lt;ul&gt;
&lt;li&gt;Ceci nous évitera de partager nos disques avec la terre entière, ce qui
serait non seulement illégal, mais très consommateur en bande passante.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Tunnel ssh&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Ce n'est pas le sujet de ce billet, je vous donne donc la commande pour
créer un tunnel ssh.
&lt;ul&gt;
&lt;li&gt;Il y a pas mal d'explications à ce sujet un peu partout, les curieux
devraient trouver leur compte facilement.&lt;/li&gt;
&lt;li&gt;Sous MS-Windows, vous pouvez créer facilement des tunnels avec
&lt;em&gt;Putty&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;pour créer un tunnel ssh entre votre machine et le serveur mpd&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

ssh -C -L 5678:localhost:5678 a.b.c.d

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;5678&lt;/em&gt; : port configuré sur mpd pour exporter le stream httpd
(ce n'est &lt;strong&gt;pas&lt;/strong&gt; le port de commande de mpd)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;localhost&lt;/em&gt; : car vous allez vous connecter sur votre machine
pour la redirection de port.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;a.b.c.d&lt;/em&gt; : ip de la machine distante faisant tourner mpd.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;En prime, vous récupérez un shell où vous pourrez lancer &lt;em&gt;ncmpc&lt;/em&gt;
pour controler &lt;em&gt;mpd&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;mpd&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Exporte le flux httpd.&lt;/li&gt;
&lt;li&gt;Les façons de le lancer ont été vues plus haut:
&lt;ul&gt;
&lt;li&gt;en user : &lt;code&gt;mpd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;au démarrage : voir la doc de votre distrib. Avec Gentoo, vous pourrez
utiliser &lt;code&gt;/etc/init.d/mpd start&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;ncmpc&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;à installer sur le serveur pour controler mpd
&lt;ul&gt;
&lt;li&gt;on peut également l'installer sur le client (dans ce cas, pensez à définir
un login/password et à ouvrir le port de commande mpd dans le firewall).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;mplayer&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Reçoit le stream et assure son rendu.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mplayer http://192.168.1.1:5678&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;192.168.1.1&lt;/em&gt; est l'ip de la machine faisant tourner
&lt;em&gt;mpd&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;5678&lt;/em&gt; est le numéro de port utilisé pour envoyer le stream.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Inconvénients de la config du pauvre (mais qui marche tellement bien)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Je ne vous le cache pas, il y a quelques inconvénients.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Overhead du tunnel&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Si vous êtes vraiment court côté débit, sachez qu'un flux à 128kbs (minimum
pour une qualité acceptable) vous pompe 16ko/s de bande passante.
&lt;ul&gt;
&lt;li&gt;Avec le tunneling, vous allez passer à environ 22ko/s de moyenne.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Je n'ai pas testé avec quelque chose de plus compliqué, à base de OpenVPN
par exemple.
&lt;ul&gt;
&lt;li&gt;Si quelqu'un l'a fait, qu'il n'hésite pas à partager son expérience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour gagner un peu de bande passante sur la session SSH, vous pouvez passer
l'option &lt;strong&gt;-N&lt;/strong&gt; à la connexion.
&lt;ul&gt;
&lt;li&gt;Cette option désactive le shell interactif et ne fait qu'établir le
tunnel.&lt;/li&gt;
&lt;li&gt;Vous ne pourrez donc plus controler la playlist directement, mais pour un
streaming tout simple, cela suffit. Vous gagnez environ trois Ko/s.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Latence&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;C'est inhérent au streaming. Pour assurer une liaison sans saccades, tout
est bufferisé.
&lt;ul&gt;
&lt;li&gt;Les modifications côté serveurs (changement de chanson, ou arrêt pur et
simple) mettront quelques secondes avant d'être répercutées à votre
client.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Quand à l'avance/retour rapide dans un morceau, mieux vaut oublier tout de
suite.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Une idée pourrait être de réduire la taille du buffer , sur une liaison de
bonne qualité bien entendu.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Allez, c'est pas si mal finalement&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;De toutes façons, vous n'auriez guère mieux avec un serveur shoutcast,
alors pourquoi se compliquer la vie ?&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Allez hop. Et profitez-en pour mettre Audacious à la poubelle avant de
sortir.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2010/04/27/MPD-%3A-le-stream-%C3%A9tait-presque-parfait#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2010/04/27/MPD-%3A-le-stream-%C3%A9tait-presque-parfait#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/511820</wfw:commentRss>
      </item>
    
  <item>
    <title>La plomberie facile avec mtrace</title>
    <link>http://www.finiderire.com/post/2010/01/10/La-plomberie-facile-avec-mtrace</link>
    <guid isPermaLink="false">urn:md5:6d752c4492850d78a80cd8feced4d22c</guid>
    <pubDate>Mon, 22 Feb 2010 21:37:00 +0100</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Coding</category>
        <category>C</category><category>coding</category><category>debugging</category><category>GCC</category><category>Linux</category>    
    <description>&lt;p&gt;&lt;em&gt;Le C et les fuites mémoires, c'est comme une vieille complainte
sentimentale.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Avec &lt;strong&gt;mtrace&lt;/strong&gt;, et sa couche maxi-absorbante, finissez-en
avec l'incontinence de vos programmes.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;mtrace&lt;/strong&gt; n'est pas disponible en pharmacie, uniquement dans
les bonnes libc.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Ma mémoire prend la fuite!&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Je ne vous fait pas une tartine sur les problèmes de gestion mémoire en C.
&lt;ul&gt;
&lt;li&gt;Si vous avez approché un compilateur C un jour de votre vie, vous savez de
quoi je parle.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour prévenir les problèmes de fuite mémoire, il existe plusieurs
méthodes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Je ne fais rien&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Ne rigolez pas, un OS bien conçu est censé vous rendre la mémoire à la
sortie de votre programme.&lt;/li&gt;
&lt;li&gt;Bon alors, on fait comme ça ?
&lt;ul&gt;
&lt;li&gt;Non, on ne fait pas comme ça. On passe toujours un coup de balai avant de
quitter un programme, question de savoir-vivre et d'éducation.&lt;/li&gt;
&lt;li&gt;Il y a également le fait qu'on ne sait jamais vraiment où le programme
finira par tourner, ni si l'OS réussira réellement à récuperer
&lt;strong&gt;toute&lt;/strong&gt; la mémoire.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;J'écris mon gestionnaire mémoire&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Allez, on l'a tous fait un jour ou l'autre.
&lt;ul&gt;
&lt;li&gt;Ou comment finir avec un wrapper de malloc/free plus ou moins élaboré, qui
génère de jolies listes d'alllocations/libérations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ce n'est pas forcément une mauvaise idée. C'est surtout délicat à gérer
pour toutes sortes de raisons (je ne développe pas, si vous ne comprenez pas,
essayez de faire le votre).&lt;/li&gt;
&lt;li&gt;L'insensé tenant vraiment à explorer la Voie de l'Insomnie pourra toujours
commencer par : &lt;code&gt;man malloc_hook&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;J'utilise mtrace&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Et c'est la prise de conscience sur un titre judicieusement choisi.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;mtrace, principe et utilisation&lt;/h3&gt;
&lt;h5&gt;Prérequis&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Une libc GNU.&lt;/li&gt;
&lt;li&gt;Un compilateur GNU.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Principe&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Le principe consiste à intercepter les appels à &lt;em&gt;malloc&lt;/em&gt; et à
&lt;em&gt;free&lt;/em&gt;, et à tenir registre des allocations/libérations de mémoire.&lt;/li&gt;
&lt;li&gt;Pour cela, vous initialiserez le wrapper de la libc avec
&lt;code&gt;mtrace()&lt;/code&gt; , et vous appellerez en sortie
&lt;code&gt;muntrace()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Utilisation&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il suffit d'inclure &lt;code&gt;mcheck.h&lt;/code&gt; et vous pourrez utiliser les deux
fonctions requises.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mtrace&lt;/code&gt; : avant tout &lt;em&gt;malloc()&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;muntrace&lt;/code&gt; : après le dernier &lt;em&gt;free()&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous aurez également besoin d'une variable shell, pour indiquer où écrire
le fichier de log.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;export MALLOC_TRACE = /path/to/log.txt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Une autre variable shell peut être utilisée: &lt;code&gt;MALLOC_CHECK&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Normalement, son usage est d'indiquer le niveau de log.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;export MALLOC_CHECK = 2&lt;/code&gt; : fait planter le programme si
erreur malloc (je tenais à vous faire partager cette découverte).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Un script Perl (&lt;em&gt;mtrace&lt;/em&gt;) pour mettre en forme le fichier de
log.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;L'exemple tant attendu&lt;/h3&gt;
&lt;h5&gt;Source pour nos essais&lt;/h5&gt;
&lt;pre&gt;
/* mtrace.c */

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;mcheck.h&amp;gt;

int main(void)
{
  mtrace();

  char *freed = malloc(1024);
  char *leaked = malloc(1024);

  if (freed) free(freed);

  muntrace();
  return 0;
}

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Pour compiler ce source, rien de spécial.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gcc -g -Wall mtrace.c -o mtrace&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;N'oubliez pas &lt;strong&gt;-g&lt;/strong&gt; pour avoir les symboles dans la sortie de
&lt;em&gt;mtrace&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Et pour le lancer:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MALLOC_TRACE=&lt;q&gt;/tmp/mtrace.log&lt;/q&gt; ./mtrace&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Le prompt revient, pas de plantages, donc, pas de problèmes.&lt;/li&gt;
&lt;li&gt;Vraiment ?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Utilisation du script Perl &lt;strong&gt;mtrace&lt;/strong&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Tout d'abord, voyons à quoi ressemble le fichier log.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

~test$ cat /tmp/mtrace.log 
= Start
@ ./mtrace:[0x40060f] + 0x1ea7460 0x400
@ ./mtrace:[0x40061d] + 0x1ea7870 0x400
@ ./mtrace:[0x400631] - 0x1ea7460
= End

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;De ce qui précède, on peut deviner aisément que le bloc mémoire situé à
0x1ea7870 n'a pas été libéré.
&lt;ul&gt;
&lt;li&gt;Nous allons cependant rendre plus parlant ce fichier.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le script &lt;strong&gt;mtrace&lt;/strong&gt; s'invoque avec en paramètres l'exécutable
à analyser (pour ses symboles), et le fichier log.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

~test$ MALLOC_TRACE=&amp;quot;/tmp/mtrace.log&amp;quot; mtrace ./mtrace /tmp/mtrace.log 

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000001cb6870    0x400  at /home/jseb/test/mtrace.c:12

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Voila qui est plus parlant.
&lt;ul&gt;
&lt;li&gt;La ligne indiquée correspond au &lt;em&gt;malloc()&lt;/em&gt; sans &lt;em&gt;free()&lt;/em&gt;
correspondant.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;mtrace n'est cependant pas Dieu le Père Tout Puissant&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;mtrace&lt;/em&gt; ne vous protégera bien sûr pas des écrasements mémoire
durant l'exécution de votre programme.&lt;/li&gt;
&lt;li&gt;De même, les problèmes de gestion mémoire ne seront pas détectés. Il peut
cependant vous signaler des &lt;em&gt;free&lt;/em&gt; multiples.&lt;/li&gt;
&lt;li&gt;Sa facilité d'emploi devrait toutefois inciter tout codeur un tant soit peu
consciencieux à l'utiliser.&lt;/li&gt;
&lt;li&gt;Une alternative consiste à laisser tomber &lt;code&gt;malloc&lt;/code&gt; et
&lt;code&gt;free&lt;/code&gt;, mais je laisse ça aux gens qui ont des problèmes de
mémoire.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2010/01/10/La-plomberie-facile-avec-mtrace#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2010/01/10/La-plomberie-facile-avec-mtrace#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/474248</wfw:commentRss>
      </item>
    
  <item>
    <title>Unison et MSYS sont dans le même bateau</title>
    <link>http://www.finiderire.com/post/2009/12/14/Unison-et-MSYS-sont-dans-le-meme-bateau</link>
    <guid isPermaLink="false">urn:md5:02849899f60798a4ddd94dcec12553ec</guid>
    <pubDate>Mon, 21 Dec 2009 19:07:00 +0100</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Tools</category>
        <category>coding</category><category>MS-Windows</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;Vous utilisez MS-Windows, comme des millions d'autre victimes (et moi,
et moi, et moi).&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Vous utilisez également MSYS (comme... euh... moi.)&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Mais avec MSYS, Unison (le synchroniseur de fichiers) est rétif.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;MSYS va apprendre que l'ordinateur est fait pour servir l'homme, et non
l'inverse (muhaHAHAHAA!)&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Il y a ce qu'on a ...&lt;/h3&gt;
&lt;h5&gt;Ce qu'on a&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Pour le moment, nous pouvons utiliser uniquement Unison sous la forme d'un
serveur lancé avec la commande
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;unison --socket &amp;lt;port en écoute&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le client Unison est le même programme, mais lancé avec des paramètres
différents. Il sera utilisé depuis une autre machine pour se connecter à son
serveur.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ce n'est pas une bonne solution, pour trois raisons:
&lt;ul&gt;
&lt;li&gt;Il faut lancer Unison en écoute le serveur à chaque utilisation, ou pire,
le laisser tourner en permanence en écoute.&lt;/li&gt;
&lt;li&gt;Les communications ne sont pas chiffrées.&lt;/li&gt;
&lt;li&gt;Il n'y a pas d'authentification, et changer de port pour l'écoute du
serveur n'est qu'un pis-aller.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Ce qu'on aimerait que ça devienne&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Utiliser le mode &lt;em&gt;commandes ssh&lt;/em&gt; de Unison, qui lance lui même le
serveur, et fait transiter les données dans un canal crypté.
&lt;ul&gt;
&lt;li&gt;Les inconvénients de la situation où Unison est figé en écoute sont
supprimés.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Configuration logicielle&lt;/h3&gt;
&lt;h5&gt;openssh de MSYS&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Ma version de openssh est la 4.7
&lt;ul&gt;
&lt;li&gt;Sans vouloir gâcher un long suspense, nous n'utiliserons pas openssh, mais
&lt;em&gt;plink&lt;/em&gt; de putty.&lt;/li&gt;
&lt;li&gt;Je laisse toutefois mon cheminement avec openssh. Un courageux pourra peut
être compléter dans les commentaires.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;putty 0.59&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Uniquement pour utiliser plink (mais putty est également un excellent
émulateur de terminal).
&lt;ul&gt;
&lt;li&gt;La version 0.60 est disponible sur le &lt;a href=&quot;http://www.chiark.greenend.org.uk/~sgtatham/putty/&quot;&gt;site officiel&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Unison en interface texte&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il s'agit de la version 2.27&lt;/li&gt;
&lt;li&gt;Pour nos tests, nous allons utiliser la version &lt;q&gt;interface texte&lt;/q&gt; de
Unison.
&lt;ul&gt;
&lt;li&gt;Le passage à l'interface graphique de Unison sera abordé à la fin de cet
article.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Profil pour les tests&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Le client d'où est lancé la commande est un banal Windows.&lt;/li&gt;
&lt;li&gt;Le serveur est un banal Linux, avec Unison correctement installé. (ip:
192.168.1.1)&lt;/li&gt;
&lt;li&gt;Un fichier &lt;em&gt;profile&lt;/em&gt; se trouvera dans votre home, dans le
sous-répertoire &lt;strong&gt;.unison&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Exemple de fichier &lt;em&gt;profile&lt;/em&gt; valide, situé dans
&lt;strong&gt;~/.unison/default.prf&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

# Unison preferences file
root = c:\msys\home\jseb\coding
root = ssh://jseb@192.168.1.1//home/jseb/coding

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vous remarquerez que l'encodage des répertoires côté Windows se fait avec
des antislashes, ce qui est logique quand on réfléchit trente secondes.
&lt;ul&gt;
&lt;li&gt;Je dis ça, car mon premier essai m'a pris exactement vingt neuf
secondes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Premier lancement&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Unison est lancé avec les paramètres suivants:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;./&amp;quot;Unison-2.27.57 Text.exe&amp;quot; -debug verbose&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Je passe le début du log. La fin est intéressante:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

Contacting server...
[remote] Shell connection: ssh (ssh, -l, jseb, 192.168.1.1, -e, none, unison, -server)
Uncaught exception Unix.Unix_error(20, &amp;quot;create_process&amp;quot;, &amp;quot;ssh&amp;quot;)

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;On dirait un problème avec ssh, pas vrai Holmes ?
&lt;ul&gt;
&lt;li&gt;Watson, vous m'étonnerez toujours.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Utiliser ssh avec Unison&lt;/h3&gt;
&lt;h5&gt;Vérification (sur l'air de &lt;q&gt;ne négligeons aucune possibilité&lt;/q&gt;)&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;La commande ssh existe pourtant dans MSYS.&lt;/li&gt;
&lt;li&gt;Première chose, s'assurer de son bon fonctionnement.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

$ ssh jseb@192.168.1.1 ls
Password: 
(et une jolie liste de fichiers s'affiche)

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Pas de problèmes de ce côté là.&lt;/li&gt;
&lt;li&gt;Les paramètres passés par Unison ne sont probablement pas compris par
ssh.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Voyons voir ces paramètres...&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Pour rappel, voici la chaine de paramètres utilisée par Unison (vu dans les
logs plus haut)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssh, -l, jseb, 192.168.1.1, -e, none, unison, -server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous allons faire un essai à la main&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

$ ssh jseb@192.168.1.1 unison -server
Password: 
bash: unison: command not found

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Ahah! Effectivement, Unison ne s'appelle pas &lt;q&gt;Unison&lt;/q&gt; sur mon serveur,
pour des raisons historiques (aheeeem!).
&lt;ul&gt;
&lt;li&gt;Son vrai petit nom est &lt;code&gt;unison-2.27&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Hola! Stop! Je vous ai vu! Pas de renommage du binaire sur le serveur,
espèce de sauvage!
&lt;ul&gt;
&lt;li&gt;Le fichier &lt;em&gt;profile&lt;/em&gt; peut se configurer afin de préciser la commande
à lancer.&lt;/li&gt;
&lt;li&gt;Il suffit d'ajouter: &lt;code&gt;servercmd = unison-2.27&lt;/code&gt; dans le
profil.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Avec les nouveaux paramètres...&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;On relance Unison, toujours en mode debug&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

$ ./Unison-2.27.57\ Text.exe -debug verbose
 (...)
[remote] Shell connection: ssh (ssh, -l, jseb, 192.168.1.1, -e, none, unison-2.27, -server)
Uncaught exception Unix.Unix_error(20, &amp;quot;create_process&amp;quot;, &amp;quot;ssh&amp;quot;)

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;C'est un peu mieux, mais ce n'est toujours pas ça.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Passer différemment les paramètres à ssh&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Tout ça sent à plein nez un problème de paramètres passés n'importe comment
à ssh.&lt;/li&gt;
&lt;li&gt;Nous savons comment nous voulons les passer (ligne de commande
ci-dessus).&lt;/li&gt;
&lt;li&gt;Unison est un programme bien fait, il permet de spécifier la commande
ssh.&lt;/li&gt;
&lt;li&gt;Il suffit d'utiliser &lt;strong&gt;sshcmd&lt;/strong&gt; dans le profil.&lt;/li&gt;
&lt;li&gt;Nous ajoutons donc:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sshcmd = c:\msys\home\jseb\.unison\sshcmd.bat&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Bien sûr, il faut un fichier sshcmd qui va contenir la commande ssh
correctement paramétrée.
&lt;ul&gt;
&lt;li&gt;A des fins de test, nous utilisons une commande qui va afficher les
paramètres passés.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;sshcmd.bat&lt;/em&gt; contient donc pour l'instant:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@echo 0=%0 1=%1 2=%2 3=%3 4=%4 5=%5 6=%6 7=%7 8=%8 9=%9&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Notez l'arobase au début de la commande, c'est obligatoire.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Plus qu'à relancer Unison pour voir ce que cela donne.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

$ ./Unison-2.27.57\ Text.exe 
Contacting server...
Fatal error: Received unexpected header from the server:
 expected &amp;quot;Unison 2.27\n&amp;quot; but received &amp;quot;0=c:\\msys\\home\\jseb\.unison\\sshcmd.bat 1=-l 2=jseb 3=192.168.1.1 4=-e 5=none 6=unison-2.27 7=-server 8= 9=\013\n&amp;quot;, which differs at &amp;quot;0&amp;quot;.

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Les paramètres importants sont donc le second et le troisième (le nom
d'utilisateur et l'ip), ainsi que le sixième et le septième (commande&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous pouvons tout de suite modifier la commande ssh.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;sshcmd.bat&lt;/em&gt; devient donc:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@c:\msys\bin\ssh -l %2 %3 -e none %6 %7&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Et alors ? Rien à tirer de openssh&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Quand on relance Unison, la connexion reste en attente et ssh tourne dans
le vide sur le poste client.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il y a bien du dialogue avec le serveur, une écoute avec tcpdump le
montre.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il s'agit d'un problème d'attente du mot de passe ssh, qui n'est pas
transmis sur le shell msys par ssh.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous pourrions tenter des générer une clé privé et de nous connecter sans
mot de passe, mais je trouve cette solution dangereuse.
&lt;ul&gt;
&lt;li&gt;Vous n'êtes pas obligé d'être d'accord. Vous pourriez stocker votre clé
privé sur une clé USB qui ne vous quitterait pas, résolvant les problèmes de
stockage de la clé sur un ordinateur en accès libre.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour ma part, j'ai une approche différente : utiliser &lt;em&gt;plink&lt;/em&gt;
en lieu et place de &lt;em&gt;openssh&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Attention aux essais avec openssh et unison. Quand ssh reste dans un état
bloqué, un ctrl+c rend la main au shell, mais ssh reste en mémoire. Pensez à le
tuer avec le &lt;em&gt;gestionnaire des tâches&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;plink, mon sauveur&lt;/h3&gt;
&lt;h5&gt;plink ?&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;plink&lt;/em&gt; est un utilitaire livré avec &lt;em&gt;putty&lt;/em&gt; (un émulateur de
terminal déja évoqué ci-dessus).&lt;/li&gt;
&lt;li&gt;Son fonctionnement est analogue à la fonction ssh, il peut même servir pour
des sessions &lt;q&gt;interactives&lt;/q&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;En avant avec plink&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Pour l'utiliser, il suffit de modifier le fichier &lt;em&gt;sshcmd.bat&lt;/em&gt; et
d'adapter les paramètres.
&lt;ul&gt;
&lt;li&gt;Voici le nouveau contenu du fichier:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

REM fichier sshcmd.bat
REM %2 = nom d'utilisateur , %7 = mot de passe ssh
REM %3 = ip serveur, %8 = unison-2.27, %9 = -server

@C:\putty\plink -ssh -l %2 -pw %7 %3 %8 %9

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;-pw&lt;/strong&gt; : ce paramètre sert à spécifier un mot de passe
en ligne de commande, et à éviter le lock rencontré avec OpenSSH.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il faut préciser que la commande ssh aura des arguments, on lance donc
Unison avec ces paramètres:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;./&amp;quot;Unison-2.27.57 Text.exe&amp;quot; -sshargs &amp;quot;-pw mot_de_passe&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Si vous rencontrez des problèmes, vous pouvez relancer la commande
ci-dessus en &lt;em&gt;debug verbose&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;./&amp;quot;Unison-2.27.57 Text.exe&amp;quot; -sshargs &amp;quot;-pw mot_de_passe&amp;quot; -debug
verbose&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Il s'agira probablement d'un problème d'ordre de paramètres (vérifiez bien
la chaine de connexion ssh).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Bon et cette interface ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;L'interface texte est pratique, mais l'interface GTK est encore plus
pratique.
&lt;ul&gt;
&lt;li&gt;Oui je sais. &lt;em&gt;clic clic clic&lt;/em&gt;. Bon. Personne n'est parfait.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Si vous avez la lib GTK installée, passer à l'interface graphique de Unison
ne devrait pas poser trop de problèmes.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il suffit de préciser son path dans le script d'invocation de Unison.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Voici un exemple de script, que j'ai appellé &lt;q&gt;unison&lt;/q&gt;, et que j'ai
placé dans le &lt;em&gt;/bin&lt;/em&gt; de msys.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

#!/bin/sh
#nom de ce script: /bin/unison

stty -echo
echo -n &amp;quot;entrez votre mot de passe: &amp;quot;
read p
stty echo

#echo $PATH
&amp;quot;$unison_gtk&amp;quot; -sshargs &amp;quot;-pw $p&amp;quot; 

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Vous remarquerez qu'on passe le mot de passe dans une variable, après
l'avoir demandé au lancement.
&lt;ul&gt;
&lt;li&gt;L'écho local du clavier est bloqué pendant la saisie, au cas où un
malfaisant vous regarderait taper.&lt;/li&gt;
&lt;li&gt;Un script plus complet (pour ceux qui comme moi n'ont pas GTK dans le PATH)
est proposé à la fin de cet article.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Synchro : ok&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A ce stade, vous êtes normalement un codeur heureux.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Terminé les fichiers qui se promènent en clair sur le réseau.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Et pour ceux qui n'aiment ni lire, ni comprendre, voici le résumé du
résumé.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Le profil&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il se trouve dans &lt;strong&gt;~/.unison/votre_profil_unison.prf&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;C'est ici qu'on précise le nom de l'exécutable Unison côté serveur, ainsi
que la commande de remplacement ssh.&lt;/li&gt;
&lt;li&gt;Par défaut, Unison utilise le profil nommé
&lt;strong&gt;default.prf&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

# Unison preferences file
servercmd = unison-2.27
sshcmd = c:\msys\home\jseb\.unison\sshcmd.bat@@
root = c:\msys\home\jseb\coding
root = ssh://jseb@192.168.1.1//home/jseb/coding

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;La commande de remplacement ssh&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Ce batch MS-DOS est invoqué par Unison, qui utilise le contenu du paramètre
&lt;strong&gt;sshcmd&lt;/strong&gt;, défini dans le profil.
&lt;ul&gt;
&lt;li&gt;N'oubliez pas l'arobase avant la commande.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

@C:\putty\plink -ssh -l %2 -pw %7 %3 %8 %9

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Script de lancement (avec support GTK)&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Placez le dans votre path, ou dans &lt;em&gt;/bin&lt;/em&gt;, il s'y trouvera fort
bien.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

#!/bin/sh
#nom de ce script: /bin/unison

stty -echo
echo -n &amp;quot;entrez votre mot de passe: &amp;quot;
read p
stty echo

#attention , pas d'espace autour de '=' dans une affectation!
unison_gtk=&amp;quot;/c/Unison-2.27.57/Unison-2.27.57 Gtk+.exe&amp;quot;
lib_gtk=&amp;quot;/c/Program Files/Fichiers communs/GTK/2.0/bin/&amp;quot;
PATH=&amp;quot;$PATH&amp;quot;:&amp;quot;$lib_gtk&amp;quot;

#les gens qui ont une espace dans leur mot de passe protègeront la variable $p :
# -sshargs &amp;quot;-pw \&amp;quot;$p\&amp;quot;&amp;quot;
# Merci Fred pour la remarque.
&amp;quot;$unison_gtk&amp;quot; -sshargs &amp;quot;-pw $p&amp;quot;

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/12/14/Unison-et-MSYS-sont-dans-le-meme-bateau#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/12/14/Unison-et-MSYS-sont-dans-le-meme-bateau#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/467872</wfw:commentRss>
      </item>
    
  <item>
    <title>Du neuf sans œufs</title>
    <link>http://www.finiderire.com/post/2009/10/01/Du-neuf-sans-%C5%93ufs</link>
    <guid isPermaLink="false">urn:md5:86613bf77f201c491c73d8622047fcc1</guid>
    <pubDate>Sat, 03 Oct 2009 11:41:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Cuisine</category>
        <category>cuisine</category>    
    <description>&lt;p&gt;&lt;em&gt;Un gâteau ?&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Oui, mais celui-ci, il a quelque chose de plus en moins.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Le gâteau sans œufs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Certaines personnes sont allergiques aux œufs, les malheureux.&lt;/li&gt;
&lt;li&gt;Ce n'est pas mon cas, mais je n'en avais plus à portée de main.&lt;/li&gt;
&lt;li&gt;Une recherche internet, et une correction des valeurs saupoudrée de
personnalisation... voici le résultat.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Évoquons les ingrédients.&lt;/h3&gt;
&lt;p&gt;Ingrédients (pour 4 à 6 personnes) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;200 g de farine&lt;/li&gt;
&lt;li&gt;1 pincée de sel&lt;/li&gt;
&lt;li&gt;150 g de sucre en poudre&lt;/li&gt;
&lt;li&gt;150 g de chocolat en morceaux&lt;/li&gt;
&lt;li&gt;120 g de beurre&lt;/li&gt;
&lt;li&gt;20 cl de lait&lt;/li&gt;
&lt;li&gt;1 sachet de levure dite &lt;q&gt;chimique&lt;/q&gt; (en fait, c'est du
bicarbonate)&lt;/li&gt;
&lt;li&gt;1 boite de fruits en conserve&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Saladier, mélanger, und so weiter&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dans un saladier, verser la farine, le sel, la levure et le sucre.
Mélanger.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Faire fondre le beurre et le chocolat dans une casserole, avec un peu d'eau
au fond (pour éviter que cela n'attache).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ajouter le lait dans la casserole, bien mélanger.
&lt;ul&gt;
&lt;li&gt;Ne vous inquiétez pas, le mélange n'est pas très miscible mais ça ne porte
pas à conséquences.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ajouter le contenu de la casserole en trois fois dans le saladier. Mélanger
à chaque étape.
&lt;ul&gt;
&lt;li&gt;A la dernière étape, vous devez obtenir un mélange lisse et onctueux.&lt;/li&gt;
&lt;li&gt;La spirale tracée par la cuillère dans la pâte doit évoquer le nombre d'or.
Continuez à mélanger si ce n'est pas le cas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Badigeonnez un plat en pyrex avec de l'huile (un filet suffit).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Versez dans le plat en pyrex le contenu du saladier.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Placez les fruits en conserve soigneusement égouttés dans le plat.
&lt;ul&gt;
&lt;li&gt;N'hésitez pas à appuyer un peu sur ceux-ci, pour faciliter l'immersion
(noyé dans une mer de chocolat ! Quel destin à la fois horrible et tentant
!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Bon ça y est ? On peut mettre au four ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Mettre dans le four préchauffé à 200°.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Cuisson: 30mn à 200°, puis &lt;em&gt;éventuellement&lt;/em&gt; 5mn à 180°.
&lt;ul&gt;
&lt;li&gt;Vérifiez la cuisson à 30mn!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez vérifier la cuisson en enfoncant la lame d'un couteau au centre
du gâteau.
&lt;ul&gt;
&lt;li&gt;Elle doit ressortir sans emporter de la pate avec elle.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La poule qui a fait l'œuf ou l'œuf qui fit la poule ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Je remercie mes collègues qui ont bien voulu servir de cobayes.
&lt;ul&gt;
&lt;li&gt;Et qui ont aimé ça (c'est pour ça que je les remercie).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/10/01/Du-neuf-sans-%C5%93ufs#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/10/01/Du-neuf-sans-%C5%93ufs#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/446234</wfw:commentRss>
      </item>
    
  <item>
    <title>OSS4 : Alsa ne répond plus.</title>
    <link>http://www.finiderire.com/post/2009/09/16/OSS4-%3A-Alsa-ne-r%C3%A9pond-plus.</link>
    <guid isPermaLink="false">urn:md5:ed2bdff9d72df375de52c84a08f54f46</guid>
    <pubDate>Thu, 17 Sep 2009 20:17:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Linuxeries</category>
        <category>api</category><category>Gentoo</category><category>Linux</category>    
    <description>&lt;p&gt;&lt;em&gt;Plus fort que OSS-117 et Alsa réunis.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Voici ... OSS4 !&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Et dire qu'on l'enterrait déja dans l'indifférence générale.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Alsa prête le flanc à la critique&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OSS4 est le dernier avatar de la lignée presque éteinte OSS. Comme quoi,
tout arrive.&lt;/li&gt;
&lt;li&gt;Alsa rêgne en maître incontesté sur nos cartes sons depuis quelques
années.&lt;/li&gt;
&lt;li&gt;Pourquoi remplacer Alsa par OSS4 ?
&lt;ul&gt;
&lt;li&gt;Alsa n'est pas exempt de bugs.&lt;/li&gt;
&lt;li&gt;Je dirais même plus, mon cher Dupont, de bugs Alsa n'est pas exempt.&lt;/li&gt;
&lt;li&gt;De curieux comportements après une hibernation (plantage de la couche son
pour moi).&lt;/li&gt;
&lt;li&gt;D'autres comportements non moins étranges lors d'un shutdown. (cf
bugs.gentoo.org)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bref, Alsa peut vous laisser comme deux ronds de flan.
&lt;ul&gt;
&lt;li&gt;Il est temps de passer à la concurrence. Cela stimule l'innovation et
l'inventivité, comme disent les adeptes de la concurrence (chez les
autres).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tout ce qui suit est pour Gentoo.&lt;/li&gt;
&lt;li&gt;Vous aurez peut être besoin d'installer &lt;strong&gt;mercurial&lt;/strong&gt;
(&lt;em&gt;layman&lt;/em&gt; vous le signalera, si c'est le cas)&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Overlay&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il faut passer par un overlay Gentoo.&lt;/li&gt;
&lt;li&gt;La question des overlays a déja été discutée sur ce blog
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.finiderire.com/post/2008/04/11/Developpement-pour-contrees-etrangeres&quot;&gt;J'en
parlais justement ici&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour les décideurs pressés, voici le résumé du résumé:
&lt;ul&gt;
&lt;li&gt;installer: &lt;code&gt;layman -a oss-overlay&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;juste pour voir: &lt;code&gt;ls
/usr/local/portage/layman/oss-overlay/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;package.keywords&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;C'est encore assez expérimental, donc:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;media-sound/oss ~amd64&lt;/code&gt; (ou ~x86 ou ...)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Emerge&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Rien de spécial
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;emerge -va oss&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Kernel&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Enlevez les références à Alsa dans le noyau.
&lt;ul&gt;
&lt;li&gt;Ou au minimum, le support Alsa devra être sous forme de modules.&lt;/li&gt;
&lt;li&gt;J'ai tout viré.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pas la peine d'activer OSS dans le kernel, cela ne sert à rien.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;make.conf&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;ajouter à USE oss et oss4, laisser alsa (on n'est pas des sauvages, et on
ne sait jamais).
&lt;ul&gt;
&lt;li&gt;Voici mon USE:&lt;/li&gt;
&lt;li&gt;USE=&amp;quot;-qt3 -qt4 -gnome -kde -ipv6 gtk unicode opengl jpeg truetype type1 oss
oss4 alsa&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Lancer OSS4&lt;/h3&gt;
&lt;h5&gt;Initialiser&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/init.d/oss start&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;C'est super long. Vous pouvez faire un modprobe à la main également.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;N'oubliez pas de baisser le son, par défaut, ça explose les enceintes.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

~$ ossmix vol 15
Value of mixer control vol set to 15.0:15.0
~$ ossmix pcm.main 15
Value of mixer control pcm.main set to 15.0

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Tester&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;osstest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Vous devez entendre un piano à droite, à gauche, en stéréo.&lt;/li&gt;
&lt;li&gt;Voire ailleurs si vous avez un système 5.1&lt;/li&gt;
&lt;li&gt;Moi, j'en suis resté là en tant que salaud de pauvre.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Utilitaires amusants&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ossxmix
&lt;ul&gt;
&lt;li&gt;Un mixer très complet. Enfin complet. Enfin y'a plein de boutons qui
doivent servir à quelque chose.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Et maintenant ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Haha! Vous croyiez vous en tirer à si bon compte ?
&lt;ul&gt;
&lt;li&gt;Il faut recompiler maintenant!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Soit &lt;code&gt;emerge -DuvaN world&lt;/code&gt; (bon courage)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Soit y aller petit à petit: dosbox, sdl, mplayer, mpd, xine, audacious,
wine ...
&lt;ul&gt;
&lt;li&gt;Il ne faudra pas oublier de modifier les fichiers de configuration des
programmes recompilés pour utiliser OSS si vous compilez avec le support OSS et
Alsa.&lt;/li&gt;
&lt;li&gt;Certains programmes feront automatiquement le bon choix, d'autres auront
besoin d'être un peu aidés.&lt;/li&gt;
&lt;li&gt;Comment savoir ? Lancez le programme, et si il n'y a pas de son, c'est
qu'il a besoin d'être un peu aidé. Muhahhaaahaa!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Bon d'accord, arrêtez les tomates. Je vous aide un peu avec
&lt;strong&gt;mpd&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;Si après compilation avec le double support &lt;em&gt;alsa&lt;/em&gt; et &lt;em&gt;oss&lt;/em&gt;,
vous obtenez cette erreur au lancement:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

jseb # /etc/init.d/mpd start
 * Loading ALSA modules ...
 *   Could not detect custom ALSA settings.  Loading all detected alsa drivers.
 *   Unable to find any ALSA drivers. Have you compiled alsa-drivers correctly?
 *   ERROR: Failed to load necessary drivers                              [ ok ]
 * ALSA failed to load.                                                   [ !! ]
 * ERROR:  cannot start mpd as alsasound could not start

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Dans ce cas, éditez le fichier suivant &lt;strong&gt;/etc/init.d/mpd&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Et enlevez la référence à alsasound à la ligne &lt;strong&gt;need&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Crade ? Of course. N'oubliez pas de remettre la référence si vous
réinstallez Alsa.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;OSS et l'hibernation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;hibernation&lt;/em&gt;, le mot qui fait trembler tout linuxien qui se
respecte.
&lt;ul&gt;
&lt;li&gt;Comme on n'est pas sous Windows, ça ne fait pas partie du cahier des
charges.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pas de bol, OSS a un peu de mal à sortir du caisson cryogénique.
&lt;ul&gt;
&lt;li&gt;Remarquez, Alsa, c'était pas tellement mieux.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La bonne nouvelle, c'est qu'un simple &lt;em&gt;restart&lt;/em&gt; de la couche OSS
suffit.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/init.d/mpd restart&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La mauvaise nouvelle, c'est qu'avant, il faudra tuer tous les programmes
qui dépendent de OSS.
&lt;ul&gt;
&lt;li&gt;Oui, y compris gkrellm et son mixer magique.&lt;/li&gt;
&lt;li&gt;OSS étant sympa, il prévient des applications qui le gênent.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

jseb # /etc/init.d/oss restart
 * Stopping OSS ...
Some applications are still using OSS - cannot unload

3311 gkrellm
5591 /usr/bin/mpd --no-create-db /home/jseb/.mpd/mpd.conf

Please stop these applications and run soundoff again
 * Failed to stop OSS                                                     [ !! ]

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Si vous avez compilé le noyau avec &lt;q&gt;CONFIG_MODULE_FORCE_UNLOAD&lt;/q&gt;, vous
pouvez peut être procéder autrement...
&lt;ul&gt;
&lt;li&gt;... mais je ne vous ai rien dit!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Un peu de lecture pour finir&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Mes années de fac m'ont appris de multiples choses, comme par exemple qu'il
ne faut pas mettre les pieds en fac.
&lt;ul&gt;
&lt;li&gt;J'ai également appris qu'une bonne bibliographie, ça vous pose son
homme.&lt;/li&gt;
&lt;li&gt;Normalement, on colle des pages et des pages de bouquins poussiéreux que
personne n'a lu.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Comme nous sommes entre gens de bonne compagnie, voici l'essentiel.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.4front-tech.com/wiki/index.php/Configuring_Applications_for_OSSv4&quot;&gt;la
doc d'OSS4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;N'hésitez pas à repasser, il y aura surement des mises à jour au fur et à
mesure de mes découvertes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/09/16/OSS4-%3A-Alsa-ne-r%C3%A9pond-plus.#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/09/16/OSS4-%3A-Alsa-ne-r%C3%A9pond-plus.#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/442322</wfw:commentRss>
      </item>
    
  <item>
    <title>Google Analytics, c'est chic</title>
    <link>http://www.finiderire.com/post/2009/07/17/Google-Analytics-c-est-chic</link>
    <guid isPermaLink="false">urn:md5:a0514fd1684c7e10c0e05d42194b953e</guid>
    <pubDate>Mon, 03 Aug 2009 19:38:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Et je tenais à vous dire (blablabla)</category>
        <category>Blabla</category>    
    <description>&lt;p&gt;&lt;em&gt;Voici venu le meilleur moment de l'année.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Je parle bien sûr du renouvellement du domaine
&lt;strong&gt;finiderire.com&lt;/strong&gt;.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Le renouvellement, tout le monde s'en moque. Mais ... il y a le bla-bla
annuel !&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Bilan de l'année passée et enseignements qu'il convient d'en tirer.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Quel magnifique titre à rallonge en guise d' introduction.&lt;/li&gt;
&lt;li&gt;Avouez que vous adorez ça, le bla-bla, le futile, l' inutile, le mec qui se
répand dans son blog.&lt;/li&gt;
&lt;li&gt;Mais ceci n'est pas une tentative pour faire remonter mes stats.
&lt;ul&gt;
&lt;li&gt;Les stats ? Elles étaient ... holala ... au moins à
&lt;strong&gt;ça&lt;/strong&gt; il y a trois mois.&lt;/li&gt;
&lt;li&gt;Crise financière ? Dégoût de Vim ? Sectateurs Emacs au travail de
sape efficace ? Toujours est-il que les stats ont plus que chutées.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Ca bugge, c'est sûr!&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Le module stats du blog Gandi étant à peu près aussi digne de confiance que
les résultats d'une élection dans une république bananière, j'ai commencé par
incriminer celui-ci.&lt;/li&gt;
&lt;li&gt;C'est décidé, je passe à la roll's : &lt;strong&gt;Google
Analytics&lt;/strong&gt; !&lt;/li&gt;
&lt;li&gt;Après installation de la chose, deux constatations:
&lt;ul&gt;
&lt;li&gt;Wahh qu'est-ce que c'est précis !&lt;/li&gt;
&lt;li&gt;Tiens... les chiffres sont pratiquement les mêmes que ceux des stats
pourries de Gandi.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;L'analytique, c'est chic.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Les stats fournies par Google sont d'une précision confondante et
terrifiante.&lt;/li&gt;
&lt;li&gt;Pour tout dire, c'est tout juste si on n'a pas la marque du slip du
visiteur.&lt;/li&gt;
&lt;li&gt;Vous disposez bien sûr d'un droit d'accès et de rectification de vos
données chez Google et muhahahaaa! Pardon excusez-moi, c'est nerveux.&lt;/li&gt;
&lt;li&gt;Toujours est-il que les statistiques sont tellement détaillées que
j'envisage de débarquer à l'improviste chez &lt;strong&gt;mon&lt;/strong&gt; visiteur
fidèle, une bouteille de champagne et quelques biscuits de Reims à la
main.&lt;/li&gt;
&lt;li&gt;Le seul problème, c'est qu'il faut que le javascript soit activé sur le
navigateur du visiteur. Alors soyez sympas, faites pas comme moi, et activez
l'exécution des scripts !&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La voila, la triste vérité.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;En vérité mes frères, je vous le dis: Google Analytics est si détaillé que
l' épluchage des statistiques me prend tout mon temps disponible.&lt;/li&gt;
&lt;li&gt;La mise à jour du blog va donc continuer son bonhomme de chemin, au gré de
mes envies, de mes disponibilités, et de mon taux de motivation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Tada et Pan (dans l'ordre, mais sans rapport).&lt;/h3&gt;
&lt;h5&gt;Tada!&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;L'article sur Freeglut et cygwin va être intégré dans la documentation
officielle du projet Freeglut, après traduction bien sûr.
&lt;ul&gt;
&lt;li&gt;Voila des gens au goût raffiné.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://freeglut.sourceforge.net&quot;&gt;Freeglut est ici&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Pan!&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Par ailleurs, je vous en prie: cessez de remplir les commentaires avec des
fécilications si élogieuses qu'elles en deviennent impubliables.
&lt;ul&gt;
&lt;li&gt;Quand de plus, elles se trouvent associées à un site web sans aucun
rapport, vous comprendrez que je tire à vue.&lt;/li&gt;
&lt;li&gt;Les vrais commentaires sont par contre les bienvenus.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/07/17/Google-Analytics-c-est-chic#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/07/17/Google-Analytics-c-est-chic#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/418919</wfw:commentRss>
      </item>
    
  <item>
    <title>Une Page de Python</title>
    <link>http://www.finiderire.com/post/2009/07/25/Une-Page-de-Python</link>
    <guid isPermaLink="false">urn:md5:0ea8fd31f738d43e91ebe7b1334d3795</guid>
    <pubDate>Sat, 25 Jul 2009 13:13:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Tools</category>
        <category>coding</category><category>Gentoo</category><category>Linux</category><category>MS-Windows</category><category>Python</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;Pour utiliser nativement des interfaces avec Python, il y a
&lt;strong&gt;Tkinter&lt;/strong&gt;.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Pour ceux qui n'aiment pas coder les GUI à la main, il reste les
générateurs d'interface.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Ici, je parle de la mise en oeuvre de &lt;strong&gt;Page&lt;/strong&gt;.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Revue de détail&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La revue sera rapide, j'ai testé uniquement &lt;strong&gt;GuiBuilder&lt;/strong&gt; et
&lt;strong&gt;Page&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;GuiBuilder&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Anciennement nommé &lt;strong&gt;SpecTcl&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;+1&lt;/strong&gt; : il permet de générer des interfaces
proportionnelles (le principal intêret de Tk).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-1&lt;/strong&gt; : ne semble plus maintenu, le code généré est
assez horrible.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-1&lt;/strong&gt; : les sources ne semblent pas disponibles&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Page&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;+1&lt;/strong&gt; : propose pas mal de controles, y compris les ttk
(thêmes pour tk)
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_intro.htm&quot;&gt;Voir la doc
ici&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;+1&lt;/strong&gt; : le code généré est plus propre que celui de
&lt;em&gt;GuiBuilder&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;+/-1&lt;/strong&gt; : d'après la doc, adapté aux projets d'un seul
écran (d'où le nom, je suppose). Mais on peut ruser bien sûr.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://page.sourceforge.net/&quot;&gt;On trouve Page ici&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;IInstallation de Page&lt;/h3&gt;
&lt;h5&gt;Prérequis&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Comme d'habitude, je parle pour les possesseurs de Gentoo.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il faut un &lt;strong&gt;Tk&lt;/strong&gt; récent: au moins la version 8.5
&lt;ul&gt;
&lt;li&gt;Attention, c'est une version test pour l'instant. Je n'ai pas eu de
problèmes en l'installant, cependant.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

# eix dev-lang/tk
[I] dev-lang/tk
     Available versions:  8.4.15-r1 8.4.18 8.4.18-r1 (~)8.4.19-r1 (~)8.5.7 {debug threads truetype}
     Installed versions:  8.5.7(20:24:53 24.07.2009)(truetype -debug -threads)

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Ce qui au passage va vous coller un &lt;strong&gt;Tcl&lt;/strong&gt; d'un niveau de
version à peu près équivalent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Si vous n'étiez pas à niveau pour &lt;strong&gt;Tk&lt;/strong&gt;, n'oubliez pas de
recompiler &lt;strong&gt;Python&lt;/strong&gt; avec le flag &lt;strong&gt;tk&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il vous faudra également la lib &lt;strong&gt;pyttk&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Pour l'instant, disponible en version 0.3&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pypi.python.org/pypi/pyttk&quot;&gt;On la trouve ici&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Reprenez l'archive tgz, ça suffira.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Installation&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Dépliez l'archive &lt;strong&gt;Page&lt;/strong&gt;, obtenue sur le site officiel (url
donnée plus haut).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Dépliez l'archive &lt;strong&gt;pyttk&lt;/strong&gt; dans le répertoire racine
&lt;strong&gt;Page&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;Vous devez obtenir un sous-répertoire &lt;strong&gt;pyttk-0.3&lt;/strong&gt; (selon
votre version de ''pyttk', bien sûr)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Lancez le script &lt;em&gt;configure&lt;/em&gt; de Page, qui va positionner quelques
variables dans le script de lancement de Page.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Editez le script de lancement de Page.
&lt;ul&gt;
&lt;li&gt;Ajoutez le chemin de &lt;em&gt;pyttk&lt;/em&gt;, juste avant le
&lt;strong&gt;exec&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;export PYTHONPATH=&amp;quot;$PYTHONPATH&amp;quot;:&amp;quot;$PAGE_HOME&amp;quot;/pyttk-0.3/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cela permettra de tester le code Python au sein de Page.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Test avec code généré&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cela ne devrait pas vous poser de problèmes, il faut juste prendre garde à
&lt;em&gt;pyttk&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Soit utiliser la variable globale python indiquant le chemin des modules:
&lt;ul&gt;
&lt;li&gt;export PYTHONPATH = chemin/vers/pyttk/&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Soit utliser &lt;em&gt;sys.path&lt;/em&gt; dans votre script Python.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;sys.path&lt;/em&gt; donne l'emplacement des modules au script.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

#à mettre au début du script Python
import sys
sys.path.insert (0, '/chemin/vers/pyttk/')

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Attention&lt;/strong&gt; : ce n'est pas une bonne idée que de
modifier un fichier qui a été généré.
&lt;ul&gt;
&lt;li&gt;Il faudra donc passer par un fichier &lt;q&gt;main&lt;/q&gt; qui importera à son tour
les fichiers générés.&lt;/li&gt;
&lt;li&gt;De toutes façons, vous devrez en passer par là pour écrire les fonctions de
l'interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;We thrash with all the rest&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;q&gt;Et le reste ?&lt;/q&gt; demanda le jeune padahouane.&lt;/li&gt;
&lt;li&gt;&lt;q&gt;RTFM&lt;/q&gt; répondit Iota en se reprenant un pastis.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/07/25/Une-Page-de-Python#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/07/25/Une-Page-de-Python#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/420917</wfw:commentRss>
      </item>
    
  <item>
    <title>Glut alors!</title>
    <link>http://www.finiderire.com/post/2009/07/06/Glut-alors</link>
    <guid isPermaLink="false">urn:md5:658ceb2cea2fcd22274d389b319bb07c</guid>
    <pubDate>Fri, 10 Jul 2009 00:18:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Coding</category>
        <category>C</category><category>coding</category><category>jeux video</category><category>MS-Windows</category>    
    <description>&lt;p&gt;&lt;em&gt;Freeglut est une évolution open-source de Glut.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Sous Windows, on peut l'utiliser avec Cygwin.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Facile ? Oui, si on accepte de distribuer
&lt;q&gt;cygwin1.dll&lt;/q&gt;&lt;/em&gt;.&lt;br /&gt;
&lt;em&gt;Et si on ne veut pas ? On lit cet article.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;m.à.j 10/7/2009&lt;/strong&gt; : génération d'une librairie pour
linker depuis la dll.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;m.à.j 25/11/2009&lt;/strong&gt; : correction de la partie
&lt;q&gt;utilisation de la librairie&lt;/q&gt;.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Récupération des sources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reprenez les sources de la version 2.6.0 qui intègre les changements
récents.&lt;/li&gt;
&lt;li&gt;Pour l'instant, il s'agit d'une RC (&lt;em&gt;Release Candidate&lt;/em&gt;), mais la
version finale ne saurait tarder.&lt;/li&gt;
&lt;li&gt;L'utilisation de la 2.6 est préférable à la branche 2.4-stable, de nombreux
bugs étant corrigés.&lt;/li&gt;
&lt;li&gt;Vous trouverez les sources sur le site de Freeglut:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://freeglut.sourceforge.net/&quot;&gt;Site freeglut&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Objectifs et préparation&lt;/h3&gt;
&lt;h5&gt;Objectifs&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Nous allons créer une dll liée à Cygwin, et une bibliothèque statique
indépendante&lt;/li&gt;
&lt;li&gt;Nous créerons également une librairie dynamique, permettant de linker avec
la dll.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Liste des fichiers générés&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;freeglut.dll&lt;/strong&gt; : une dll classique pour le linkage
dynamique.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;libfreeglut.a&lt;/strong&gt; : la bibliothèque statique. Le
programme final est autonome (du moins pour OpenGL).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;libfreeglutdll.a&lt;/strong&gt; : la bibliothèque dynamique. Le
programme final a besoin de &lt;em&gt;freeglut.dll&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Préparation&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Dépliez l'archive freeglut.&lt;/li&gt;
&lt;li&gt;Allez dans le répertoire &lt;strong&gt;src&lt;/strong&gt; (situé à la racine du
répertoire Freeglut), et créez un sous-répertoire &lt;q&gt;Gl&lt;/q&gt;
&lt;ul&gt;
&lt;li&gt;Dans ce sous-répertoire, copiez les fichiers du répertoire
&lt;q&gt;include/Gl&lt;/q&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pourquoi faut-il créer un répertoire &lt;q&gt;Gl&lt;/q&gt; pour la compilation ?
&lt;ul&gt;
&lt;li&gt;C'était juste pour simplifier les choses lors de mes essais.&lt;/li&gt;
&lt;li&gt;Sinon vous pouvez créer directement les répertoires, et copier les fichiers
comme indiqué au point &lt;em&gt;installation&lt;/em&gt; (lire plus loin).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Faites un peu de ménage dans &lt;strong&gt;/lib&lt;/strong&gt; :
&lt;ul&gt;
&lt;li&gt;Effacez toutes les références à la glut, pour ne pas avoir de conflit au
linkage.&lt;/li&gt;
&lt;li&gt;Cette étape est facultative, vous pouvez également choisir de ne faire le
ménage qu' &lt;strong&gt;après&lt;/strong&gt; une compilation réussie de Freeglut.&lt;/li&gt;
&lt;li&gt;Attention à &lt;strong&gt;ne pas&lt;/strong&gt; effacer, dans un enthousiasme
rédempteur, la bibliothèque &lt;em&gt;glu32.lib&lt;/em&gt; (à ne pas confondre avec
&lt;em&gt;glut32.lib&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Compilation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Oubliez le triptyque &lt;code&gt;./configure , make , make install&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;Ca ne marche pas du tout avec Cygwin.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Voici un Makefile qui fera l'affaire:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

#Makefile pour Freeglut 2.6.0-rc et Cygwin
#A placer dans le répertoire &amp;quot;src&amp;quot;

sources=$(wildcard *.c)
objs=$(sources:.c=.o)
libname=freeglut


CFLAGS=-O2 -DTARGET_HOST_MS_WINDOWS -DX_DISPLAY_MISSING -DFREEGLUT_STATIC -I./
LDFLAGS=-lopengl32 -lgdi32 -lwinmm

nocyg=-mno-cygwin -mwindows

all: $(objs)
        #construction dll liée à cygwin1.dll
        gcc $(nocyg) $(objs) -shared $(LDFLAGS) -o $(libname).dll
        nm $(libname).dll  | awk 'BEGIN { print &amp;quot;EXPORTS&amp;quot; } /T _glut/ {sub( /^.*T _/, &amp;quot;\t&amp;quot;); print}' &amp;gt; $(libname).def
        dlltool --dllname $(libname).dll --input-def $(libname).def --output-lib lib$(libname)dll.a

        #construction bibliothèque statique indépendante de cygwin
        ar cr lib$(libname).a $(objs)
        #pas forcément obligatoire (création d'un index pour accélérer les accès)
        ranlib lib$(libname).a

%.o: %.c
        gcc $(nocyg) -c $(CFLAGS) $&amp;lt;

clean:
        rm -f *.o $(libname).dll $(libname).def lib$(libname)dll.a lib$(libname).a

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Quelques remarques sur le makefile&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Ce makefile crée une dll, une bibliothèque statique (une &lt;em&gt;archive&lt;/em&gt;,
en d'autres termes) et la bibliothèque dynamique qui permettra l'utilisation de
la dll.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ne cherchez pas à stripper la bibliothèque statique! Vous ne pourriez plus
compiler en statique.
&lt;ul&gt;
&lt;li&gt;Par contre, vous pouvez stripper l'exécutable final obtenu lors de la
compilation de votre application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;J'ai choisi d'appeller la dll et les bibliothèques par leurs &lt;q&gt;vrais
noms&lt;/q&gt;: &lt;em&gt;freeglut.dll&lt;/em&gt; &lt;em&gt;libfreeglutdll.a&lt;/em&gt; et
&lt;em&gt;libfreeglut.a&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Le script configure recréait (pour des raisons de compatibilité avec
l'ancienne bibliothèque Glut) &lt;em&gt;glut.dll&lt;/em&gt; et &lt;em&gt;libglut.a&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Lors des mes essais, j'ai eu des conflits avec une authentique &lt;q&gt;glut&lt;/q&gt;
qui trainait dans mon &lt;q&gt;/lib&lt;/q&gt;. J'ai décidé d'appeller les choses par leur
nom, afin d'éviter les confusions.&lt;/li&gt;
&lt;li&gt;Rien ne vous empêche de renommer la dll, si vous avez besoin d'utiliser des
programmes Glut que vous ne pouvez pas recompiler.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La bibliothèque dynamique est générée à partir de la dll.
&lt;ul&gt;
&lt;li&gt;Par souci de concision, j'ai utilisé &lt;strong&gt;awk&lt;/strong&gt;. Il génère le
fichier d'exports utilisé par &lt;strong&gt;dlltool&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;La seule chose notable est la sélection des fonctions dont le nom commence
par &lt;em&gt;_glut&lt;/em&gt;, afin d'éviter d'inclure dans la librairie dynamique des
fonctions sans rapport avec &lt;em&gt;freeglut&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;ensuite, on utilise &lt;strong&gt;dlltool&lt;/strong&gt; de façon très classique.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

nm $(libname).dll  | awk 'BEGIN { print &amp;quot;EXPORTS&amp;quot; } /T _glut/ {sub( /^.*T _/, &amp;quot;\t&amp;quot;); print}' &amp;gt; $(libname).def
dlltool --dllname $(libname).dll --input-def $(libname).def --output-lib lib$(libname)dll.a

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Copiez &lt;em&gt;libfreeglut.a&lt;/em&gt;, &lt;em&gt;libfreeglutdll.a&lt;/em&gt; dans le répertoire
&lt;em&gt;/lib&lt;/em&gt; de Cygwin.&lt;/li&gt;
&lt;li&gt;Copiez &lt;em&gt;freglut.dll&lt;/em&gt; dans le &lt;em&gt;system32&lt;/em&gt; de Windows (ce qui
est pratique, mais pas propre!).&lt;/li&gt;
&lt;li&gt;Copiez les fichiers headers de Freeglut (&lt;em&gt;/include/gl&lt;/em&gt;) dans
&lt;em&gt;/usr/include/Gl&lt;/em&gt; de Cygwin.&lt;/li&gt;
&lt;li&gt;Copiez les fichiers headers (toujours &lt;em&gt;/include/gl&lt;/em&gt;) dans
&lt;em&gt;/usr/include/mingw/Gl&lt;/em&gt; : ceci sert aux compilations avec le flag
&lt;strong&gt;-mno-cygwin&lt;/strong&gt;, qui utilise alors les includes de
&lt;strong&gt;mingw&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;Vous aurez éventuellement besoin d'écraser d'anciens fichiers include,
correspondants à Glut, si vous l'avez installé avec Cygwin.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Utilisation de la librairie&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Nous allons tester avec le programme &lt;em&gt;shapes&lt;/em&gt;, présent dans
&lt;em&gt;progs/demos/shapes&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;-mno-cygwin&lt;/strong&gt; sert à forcer l'utilisation de Mingw sans la
grosse dépendance &lt;em&gt;cygwin1.dll&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-mwindows&lt;/strong&gt; sert uniquement à enlever l'horrible fenêtre
shell (très utile pour la mise au point, par contre).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-L.&lt;/strong&gt; (notez le point après le
&lt;q&gt;&lt;strong&gt;L&lt;/strong&gt;&lt;/q&gt;) : j'ai laissé &lt;em&gt;libfreeglut.a&lt;/em&gt;,
&lt;em&gt;libfreeglutdll.a&lt;/em&gt; et &lt;em&gt;freeglut.dll&lt;/em&gt; dans le répertoire de test,
le temps des tests justement.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Compilation en librairie statique freeglut, sans cygwin&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Toute l'astuce réside dans le &lt;em&gt;define&lt;/em&gt; :
&lt;code&gt;-DFREEGLUT_STATIC&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Il sert à obtenir la bonne décoration des noms de fonctions dans les
imports de la lib Freeglut.&lt;/li&gt;
&lt;li&gt;Vous pouvez essayer sans et prendre un éditeur hexa pour voir les
différences dans l'objet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;attention&lt;/strong&gt; à l'ordre des bibliothèques :
&lt;strong&gt;-lfreeglut&lt;/strong&gt; (statique) doit se trouver avant la déclaration des
bibliothèques dynamiques.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gcc shapes.c -L. -lfreeglut -lopengl32 -lwinmm -lgdi32 -mno-cygwin
-mwindows -DFREEGLUT_STATIC&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Compilation avec dll freeglut, sans cygwin&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Pour le define, même remarque que ci-dessus&lt;/li&gt;
&lt;li&gt;L'ordre des bibliothèques n'a plus d'importance.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gcc shapes.c -L. -lopengl32 -lwinmm -lgdi32 ./freeglut.dll
-mno-cygwin -DFREEGLUT_STATIC&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;On précise le chemin de la dll, ainsi que son extension
(&lt;strong&gt;./freeglut.dll&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Le chemin de la dll (si la dll n'est pas dans le path) doit être précisé,
car le flag &lt;q&gt;-L&lt;/q&gt; ne la concerne plus.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Compilation avec dll freeglut, avec Cygwin&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Cet exemple est donné uniquement pour référence, le thème de ce billet
étant de se débarrasser de Cygwin.
&lt;ul&gt;
&lt;li&gt;Disons que ça peut servir pendant la mise au point (et encore).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gcc shapes.c -L. -lopengl32 -lwinmm -lgdi32
./freeglut.dll&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Où sont les dooooocs ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Freeglut est livré avec sa documentation, plus très à jour.
&lt;ul&gt;
&lt;li&gt;Il semble qu'il y ait un problème avec la doc Glut originale. Non seulement
elle ne correspond pas forcément au fonctionnement de Freeglut, mais de plus,
son auteur (Mark Kilgard) l'a copyrighté. Sa distribution est donc
difficile.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Jocelyn Fréchot a entrepris une mise à niveau des docs pour la version
2.6.0. On peut les trouver sur son site pour l'instant:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://jocelyn.frechot.free.fr/freeglut/&quot;&gt;Docs Freeglut
2.6.0rc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Quelque chose a survécu ...&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;J'ai également testé la recompilation des démos de la lib Glut originelle
(paix à ses cendres).
&lt;ul&gt;
&lt;li&gt;Rien de particulier à signaler.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Merci à tous les mainteneurs courageux de Freeglut, qu'on croyait mort,
mais qui bouge encore.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/07/06/Glut-alors#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/07/06/Glut-alors#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/416515</wfw:commentRss>
      </item>
    
  <item>
    <title>Et un fichier exe pour les gouverner tous!</title>
    <link>http://www.finiderire.com/post/2009/06/02/Et-un-fichier-exe-pour-les-gouverner-tous</link>
    <guid isPermaLink="false">urn:md5:c273c9e974d6c23f769d003194bd2e27</guid>
    <pubDate>Tue, 09 Jun 2009 00:07:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Coding</category>
        <category>C</category><category>coding</category><category>Linux</category><category>MS-Windows</category>    
    <description>&lt;p&gt;&lt;em&gt;La question du fichier ressources regroupant toutes les données est
récurrente.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Les solutions sont multiples et ont fait couler beaucoup
d'encre.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Voici une solution sans développement, ce qui est toujours
intéressant.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Inclure vos données dans un seul fichier&lt;/h3&gt;
&lt;h5&gt;Principe&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Lorsque votre programme contient des données séparées, l'amour de
l'esthétisme et un légitime souci d'exclusivité peuvent conduire à distribuer
un minimum de fichiers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Fichier &lt;em&gt;ressources&lt;/em&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Une solution courante est de distribuer un fichier exécutable, et un
fichier &lt;em&gt;ressources&lt;/em&gt; qui contiendra l'ensemble des données.&lt;/li&gt;
&lt;li&gt;Le fichier &lt;em&gt;ressources&lt;/em&gt; peut être une simple concaténation des
données, une archive ou une base de données.
&lt;ul&gt;
&lt;li&gt;La &lt;em&gt;concaténation de données&lt;/em&gt; nécessite de maintenir un index, et
souvent de recréer l'ensemble du fichier à la moindre modification. C'est par
contre la plus rapide à l'exécution.&lt;/li&gt;
&lt;li&gt;L' &lt;em&gt;utilisation d'un fichier ressources&lt;/em&gt; est également rapide (moins
les temps de décompression éventuelle), mais aura au moins une dépendance (si
vous projetez d'écrire un nouveau packer/depacker... c'est une mauvaise idée).
Par contre, vous aurez des possibilités proches d'un système de fichier pour la
gestion de votre fichier ressources.&lt;/li&gt;
&lt;li&gt;L' &lt;em&gt;utilisation d'une base de données&lt;/em&gt; est à réserver aux gros
projets et sort largement du cadre de ce billet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Les codeurs n'ont pas froid aux oreilles&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;On peut faire encore plus fort, et tout coller dans le même fichier.&lt;/li&gt;
&lt;li&gt;Dans ce cas, on n'a plus trop le choix, et il s'agit bien sûr de
l'exécutable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Choix retenu&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Ici nous allons utiliser le fichier exe pour stocker nos données.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;avantages&lt;/strong&gt; : un seul fichier executable à distribuer.
On ne risque pas de se tromper quand on distribue les mises à jour.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;inconvénients&lt;/strong&gt; : il faut tout redistribuer à chaque
modification de l'exécutable. Les temps de linkage sont allongés.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Options techniques&lt;/h3&gt;
&lt;h5&gt;xxd : solution la plus portable&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xxd -i data.dat&lt;/code&gt; : génère un dump de &lt;em&gt;data.dat&lt;/em&gt; au
format C.&lt;/li&gt;
&lt;li&gt;Nous n'étudierons pas cette possibilité.&lt;/li&gt;
&lt;li&gt;En deux mots, elle consiste à définir les datas dans le code source, et à
compiler celui-ci.&lt;/li&gt;
&lt;li&gt;Son inconvénient principal est la lourdeur des codes sources générés.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Injection des données dans l'exécutable&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Utilisation de &lt;strong&gt;objdump&lt;/strong&gt; et &lt;strong&gt;objcopy&lt;/strong&gt; (ou
&lt;strong&gt;ld&lt;/strong&gt; en remplacement de &lt;em&gt;objcopy&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Nous allons utiliser les fichiers suivants:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;data.txt&lt;/strong&gt; : données à insérer dans l'exécutable (ici,
ça sera du texte).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;main.c&lt;/strong&gt; : le source C de l'exécutable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;objcopy, objdump&lt;/h3&gt;
&lt;h5&gt;objcopy&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il s'agit tout d'abord de transformer le fichier &lt;em&gt;data.txt&lt;/em&gt; en un
fichier objet.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Formats d'entrée et de sortie de &lt;em&gt;objcopy&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;objcopy --info&lt;/code&gt; : informations sur les formats
d'entrée/sortie pour &lt;em&gt;objcopy&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Linux et Windows:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;objcopy -I binary -O elf32-i386 --binary-architecture i386 data.txt
data.o&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Explication des flags
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;-I&lt;/strong&gt; : (attention il s'agit d'un
&lt;q&gt;&lt;strong&gt;i&lt;/strong&gt;&lt;/q&gt; majuscule) &lt;em&gt;input target&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-O&lt;/strong&gt; : &lt;em&gt;output target&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;rappel&lt;/strong&gt; : &lt;code&gt;objcopy --info&lt;/code&gt; donne une liste
des input/output potentiels.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Parenthèse sur &lt;strong&gt;ld&lt;/strong&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Une manipulation équivalente à la commande &lt;em&gt;objcopy&lt;/em&gt; ci-dessus:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ld -r -b binary data.txt -o data.o data.txt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Explication des flags
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;-r&lt;/strong&gt; : &lt;em&gt;link incrémental&lt;/em&gt;. Le fichier généré en
sortie par &lt;em&gt;ld&lt;/em&gt; pourra reservir comme entrée à &lt;em&gt;ld&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-b&lt;/strong&gt; : &lt;em&gt;input format&lt;/em&gt; (et non pas
&lt;em&gt;binary&lt;/em&gt;, je sais, le raccourci est tentant).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;objdump&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Permet d'obtenir toutes sortes d'informations sur vos objets.&lt;/li&gt;
&lt;li&gt;Nous l'utilisons pour avoir le nom des symboles du fichier objet.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;objdump -s data.o&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;donne le format du fichier , et le contenu des sections&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;objdump -x data.o&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;montre tous les headers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour avoir uniquement la table des symboles, utiliser le flag
&lt;strong&gt;-t&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

$ objdump.exe -t data.o

data.o:     file format pe-i386

SYMBOL TABLE:
[  0](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _binary_data_txt_start
[  1](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000001c _binary_data_txt_size
[  2](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000001c _binary_data_txt_end

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;plus court, même chose:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

$ nm data.o
0000001c D _binary_data_txt_end
0000001c A _binary_data_txt_size
00000000 D _binary_data_txt_start

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Utilisation des symboles dans le source&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Maintenant que nous avons la liste des symboles, nous pouvons y faire
référence dans le source en C.&lt;/li&gt;
&lt;li&gt;Les symboles seront traités comme de vulgaires buffers.&lt;/li&gt;
&lt;li&gt;Ils sont faciles à utiliser, voici un source d'exemple:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
/* main.c */

#include &amp;lt;stdio.h&amp;gt;

extern int binary_data_txt_end;
extern int binary_data_txt_size;
extern int binary_data_txt_start;

int main(void)
{
  int size = (int)&amp;amp;binary_data_txt_size;
  char *data = (char *)&amp;amp;binary_data_txt_start;
  char *end = (char *)&amp;amp;binary_data_txt_end;
    
  printf(&amp;quot;taille: %d\n&amp;quot;, size);
  printf(&amp;quot;buffer: %s&amp;quot;, data);
  printf(&amp;quot;start: 0x%p ; end: 0x%p\n&amp;quot;,data,end);

  return 0;
}

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Juste une petite remarque pour Windows.&lt;/li&gt;
&lt;li&gt;* Sous Windows, la décoration des noms n'est pas la même que sous Unix.
&lt;ul&gt;
&lt;li&gt;Par exemple: &lt;code&gt;_extern int binary_stdout_txt_start&lt;/code&gt; deviendra
&lt;code&gt;extern int binary_stdout_txt_start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Il faut enlever le premier underscore pour chaque symbole.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Et qu'est-ce qu'on fait maintenant ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Il faut simplement compiler le source, et ajouter au linkage notre fichier
précédemment pré-linké.&lt;/li&gt;
&lt;li&gt;Cela va plus vite à écrire qu'à expliquer:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gcc -W -Wall main.c data.o&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Je vous laisse la joie d'exécuter tout ça, et vous épargne le
screenshot.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Docteur Hacker et Monsieur Lamer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Bien entendu, la contre-mesure est assez évidente pour qui a compris tout
ce qui précède.&lt;/li&gt;
&lt;li&gt;Je ne doute pas que Docteur Hacker, qui me lit (et je j'en suis fort
honoré) a déja deviné.&lt;/li&gt;
&lt;li&gt;Dans le cas où Monsieur Lamer me lirait également, je n'en dirai pas
plus.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/06/02/Et-un-fichier-exe-pour-les-gouverner-tous#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/06/02/Et-un-fichier-exe-pour-les-gouverner-tous#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/407167</wfw:commentRss>
      </item>
    
  <item>
    <title>Toc toc token</title>
    <link>http://www.finiderire.com/post/2009/04/26/Toc-toc-token</link>
    <guid isPermaLink="false">urn:md5:e6c401ba91ad3862bad31507ade07b25</guid>
    <pubDate>Fri, 01 May 2009 20:38:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Coding</category>
        <category>C</category><category>coding</category><category>debugging</category><category>Linux</category>    
    <description>&lt;p&gt;&lt;em&gt;Un billet sur la fonction strtok...&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;... avec en prime une petite devinette.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;man strtok&lt;/h3&gt;
&lt;h5&gt;définition très personnelle du token&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;La première fois que l'on m'a parlé du &lt;em&gt;token&lt;/em&gt;, je me suis bien
demandé ce que c'était.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Une définition courte et lapidaire serait:
&lt;ul&gt;
&lt;li&gt;un &lt;em&gt;token&lt;/em&gt; est un &lt;strong&gt;élément indivisible&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Je tente donc de préciser quelque peu:
&lt;ul&gt;
&lt;li&gt;un token est un élément atomique d'un surensemble.&lt;/li&gt;
&lt;li&gt;par exemple: dans une phrase, on admet généralement que le mot est
l'élément atomique (on ne descend pas au caractère).&lt;/li&gt;
&lt;li&gt;la notion de &lt;em&gt;token&lt;/em&gt; suppose celle de &lt;em&gt;séparateur&lt;/em&gt;, pour
différencier les token du surensemble.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;strtok dans la bibliothèque standard&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;strtok&lt;/strong&gt; : fonction de la bibliothèque
&lt;em&gt;string.h&lt;/em&gt;. Elle extrait des token d'une chaine.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;strtok (char *chaine, char *separateurs)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;une invocation singulière
&lt;ul&gt;
&lt;li&gt;le premier appel de &lt;em&gt;strtok&lt;/em&gt; doit comporter un pointeur sur la
chaine à découper en token.&lt;/li&gt;
&lt;li&gt;les appels suivant à &lt;em&gt;strtok&lt;/em&gt; doivent comporter un pointeur NULL en
lieu et place de la chaine à découper.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

char *chaine=&amp;quot;ceci;est;une;chaine'';
char *token = strtok(chaine,&amp;quot;;&amp;quot;); //premier appel
while (token = strtok(NULL,&amp;quot;;&amp;quot;); //appels suivant

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La devinette&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Maintenant que vous savez tout sur les token, voici la devinette.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ce source provoque un core-dump sous Linux.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

char * get_token(char *string, char *sep)
{
  static char *token = 0;
  if (token) string=NULL;
  token = strtok (string, &amp;quot;sep&amp;quot;);

  return token;
}


int main(void)
{
  char *token = 0;
  while (token=get_token(&amp;quot;ceci;est;une;chaine&amp;quot;,&amp;quot;;&amp;quot;)) {
    printf(&amp;quot;token = %s\n&amp;quot;,token);
  }

  return 0;
}

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;strace est ton ami&lt;/h3&gt;
&lt;h5&gt;chaine littérale et strtok&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Tout réside dans l'appel de la fonction &lt;em&gt;get_token&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Le paramètre passé à cette fonction est une chaine définie à la compilation
(une chaine &lt;em&gt;littérale&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Cette chaine est donc placée dans un segment
&lt;strong&gt;read-only&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Sans même débugger, on peut le vérifier avec un &lt;em&gt;strace&lt;/em&gt; qui
indiquera la violation mémoire lors de l'appel à &lt;em&gt;strtok&lt;/em&gt; :&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gcc -Wall -W token_test.c &amp;amp;&amp;amp; strace ./a.out&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;mmap2(NULL, 4096, &lt;strong&gt;PROT_READ|PROT_WRITE&lt;/strong&gt;,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7dde000&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;résolution&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il ne faut donc jamais passer de chaines &lt;q&gt;en dur&lt;/q&gt; dans votre code à
&lt;em&gt;strtok&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Il faut soit recopier la chaine dans la fonction d'arrivée, soit passer un
pointeur sur un buffer contenant votre chaine.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Attention! Passer un pointeur sur une chaine définie à la compilation
provoquera également un plantage.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;char *chaine=&amp;quot;ceci;est;une;chaine&amp;quot;;&lt;/code&gt; :
&lt;strong&gt;core-dump&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;char chaine&lt;a href=&quot;http://www.finiderire.com/post/2009/04/26/[&quot; title=&quot;[&quot;&gt;[&lt;/a&gt;]=&amp;quot;ceci;est;une;chaine&amp;quot;;&lt;/code&gt; : &lt;strong&gt;ok&lt;/strong&gt; , car ce
n'est pas une chaine littérale, mais une liste d'initialisation de tableau (
(c) Fred. J. )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Encore une chose: &lt;em&gt;strtok&lt;/em&gt; modifie la chaine source passée en
paramètre. En voici la preuve:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main(void)
{
  char chaine[]=&amp;quot;ma;chaine&amp;quot;;

  printf(&amp;quot;origine: %s\n&amp;quot;,chaine);
  strtok(chaine,&amp;quot;;&amp;quot;);
  for (int i=0; i&amp;lt;sizeof(chaine); i++) 
    printf(&amp;quot;[0x%X]%c &amp;quot;,chaine[i],chaine[i]);

  return 0;
}

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ce programme donne en sortie:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

/tmp$ ./a.out 
origine: ma;chaine
[0x6D]m [0x61]a [0x0] [0x63]c [0x68]h [0x61]a [0x69]i [0x6E]n [0x65]e [0x0] 

&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Notez que le point-virgule a été remplacé par la valeur zéro, ce qui risque
de donner des résultats assez comiques si vous réutilisez le buffer par la
suite.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Et tok.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A noter qu'aux dernières nouvelles, MS-Windows ne passait pas ses chaines
dans un segment en lecture seule.
&lt;ul&gt;
&lt;li&gt;Encore un bon exemple des pièges qui attendent les courageux adeptes du
multiplateforme.&lt;/li&gt;
&lt;li&gt;On peut certe remplacer &lt;em&gt;courageux&lt;/em&gt; par &lt;em&gt;les fous qui font tout
en C&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La &lt;em&gt;libc&lt;/em&gt;, c'est la bonne humeur au quotidien. Alors mangez-en, et
parlez-en à vos amis.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/04/26/Toc-toc-token#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/04/26/Toc-toc-token#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/397339</wfw:commentRss>
      </item>
    
  <item>
    <title>Arrêtez vos cloneries.</title>
    <link>http://www.finiderire.com/post/2009/03/17/Arretez-vos-cloneries</link>
    <guid isPermaLink="false">urn:md5:625691fd1366fd86d539f311a4838d8a</guid>
    <pubDate>Thu, 02 Apr 2009 18:38:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Linuxeries</category>
        <category>Linux</category><category>MS-Windows</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;Vous changez de disque dur, et ne voulez pas réinstaller votre
OS&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Exigence ô combien légitime!&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Avec Linux, c'est simple, il suffit de tout recopier d'un disque à
l'autre.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Mais avec MS-Windows ... rien n'est jamais simple.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Terrifiant comme un ghost, beau comme un Adonis.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Le problème est simple : recopier un MS-Windows d'un disque vers un
autre, en gardant les réglages d'origine.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La plupart des utilisateurs font appel pour cela à &lt;em&gt;Ghost&lt;/em&gt; ou à
&lt;em&gt;Adonis True Image&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Ghost&lt;/em&gt; pose problème lors du démarrage de MS-Window, au
login : tous les comptes sont désactivés. Pas de message d'erreur, ni de
demande de réactivation, on ne peut simplement plus se logger.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Adonis&lt;/em&gt; semble mieux fonctionner, mais c'est également un logiciel
payant.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Heureusement, il reste &lt;strong&gt;dd&lt;/strong&gt; , le meilleur ami de vos disques
durs.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Merci à Frédéric Jolliton qui m'a incité à utiliser &lt;strong&gt;dd&lt;/strong&gt;, et
qui m'a expliqué l'astuce du mode LBA.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Avant de passer aux choses sérieuses, veuillez lire le disclaimer de
rigueur, qui suit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Comme d'habituuudeuhh...&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Rien n'est garanti.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous opérez en toute connaissance de cause.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous avez lu le manuel, vous l'avez compris, et vous assumez les
conséquences des manipulations.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Les plaintes concernant les pertes de données, consécutives à de mauvaises
manipulations, ne recueilleront qu'un rire moqueur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Dédé à la rescousse&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Le principe est simple:
&lt;ul&gt;
&lt;li&gt;Nous allons profiter du fait que les problèmes de géométrie de disques ont
disparus depuis l'arrivée du LBA.&lt;/li&gt;
&lt;li&gt;Avec le LBA, les disques sont vus comme une simple succession de secteurs,
ce qui convient très bien à &lt;strong&gt;dd&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le disque dur de destination peut avoir une taille supérieure ou égale au
disque source.
&lt;ul&gt;
&lt;li&gt;Cependant, il est préférable que la partition MS-Windows à cloner
corresponde physiquement au premier secteur du disque.&lt;/li&gt;
&lt;li&gt;C'est le cas si votre partition d'installation correspond à la première
partition physique du disque dur.&lt;/li&gt;
&lt;li&gt;La manipulation est faisable si MS-Windows est intallé sur la 6ème
partition logique de la 4ème partition étendue. Il faudra copier tout ce qui se
trouve auparavant, et éventuellement pas la suite, utiliser un utilitaire de
redimensionnement de disque.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour l'exemple qui suit, nous nous plaçons dans le cas le plus courant:
&lt;ul&gt;
&lt;li&gt;MS-Windows est installé sur la première partition physique du disque.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;L'exemple que nous attendions tous.&lt;/h3&gt;
&lt;h5&gt;Structure du disque source&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;J'ai coupé un peu la sortie du fdisk pour garder ce qui est
intéressant&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
#~ fdisk -l /dev/sda

Périphérique Amorce    Début         Fin      Blocs    Id  Système
/dev/hda1   *           1        3851     8192984    c  W95 FAT32 (LBA)
/dev/hda2            3852      114781   236003575    f  W95 Etendu (LBA)
/dev/hda5            3852       17623    29299911+   b  W95 FAT32
/dev/hda6           17624      114539   206188771+   7  HPFS/NTFS

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Première étape: copie brute avec dd&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Nous voulons donc copier la partition primaire numéro un du disque sda vers
sdb.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous utilisons dd, et nous faisons fi des notions de partitions. Ici, nous
n'allons copier que des secteurs.
&lt;ul&gt;
&lt;li&gt;la MBR sera donc bien sûr copiée au passage, et le disque restera
parfaitement bootable avec son menu d'origine.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour copier les 9 premiers gigas du disque sda, vers le disque sdb:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dd if=/dev/sda of=/dev/sdb bs=1k count=8500&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Seconde étape: fignolage avec fdisk&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;La première partition physique est copiée entièrement (si vous avez bien
calculé la taille).
&lt;ul&gt;
&lt;li&gt;Mais dd ne s'est pas arrêté à la fin de la première partition physique, et
a commencé à vous ramener le reste.&lt;/li&gt;
&lt;li&gt;Nous allons utiliser le &lt;strong&gt;fdisk&lt;/strong&gt; de Linux pour corriger
cela.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Attention&lt;/strong&gt; : ne pas rebooter sous MS-Windows avant
d'avoir procédé à la correction.
&lt;ul&gt;
&lt;li&gt;Si à ce stade vous utilisez un utilitaire MS-Windows (tel que
&lt;strong&gt;diskmgmt.msc&lt;/strong&gt;) pour manipuler les partitions, vous allez
fusiller votre disque (pas physiquement, rassurez-vous), et vous serez bon pour
recommencer depuis le début.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;fdisk&lt;/strong&gt; version Linux, donc:
&lt;ul&gt;
&lt;li&gt;Virez les parititions surnuméraires.&lt;/li&gt;
&lt;li&gt;Recréez les.&lt;/li&gt;
&lt;li&gt;Eventuellement, formatez les nouvelles partitions (mais vous pourrez le
faire sans risque depuis MS-Windows).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Reboot&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Il ne vous reste plus qu'à rebooter sur votre nouveau disque, et achever la
copie des données de l'ancien disque sur celui-ci
&lt;ul&gt;
&lt;li&gt;Seule la partition système nécessite d'être copiée avec &lt;em&gt;dd&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;A force de beurrer des tartines (chachacha!)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;C'est tellement simple en fait que je me demande si ça valait le coup d'en
faire une telle tartine.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Je vous ai quand même épargné les screenshots du shell, contrairement à
&lt;em&gt;une certaine presse&lt;/em&gt; Linux.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/03/17/Arretez-vos-cloneries#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/03/17/Arretez-vos-cloneries#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/339236</wfw:commentRss>
      </item>
    
  <item>
    <title>Du pain et ... c'est tout.</title>
    <link>http://www.finiderire.com/post/2009/03/10/Du-pain-et-c-est-tout</link>
    <guid isPermaLink="false">urn:md5:d486ca22efcd3c661197fc61248b84eb</guid>
    <pubDate>Tue, 10 Mar 2009 18:52:00 +0100</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Cuisine</category>
        <category>cuisine</category>    
    <description>&lt;p&gt;&lt;em&gt;Du pain et des jeux ?&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Ah, mais nous sommes sous Linux.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Il n'y a pas de jeux.&lt;/em&gt;&lt;br /&gt;
&lt;strong&gt;MàJ 24 mars 2009 :&lt;/strong&gt; &lt;em&gt;ajustement proportions, plus
astuce gonflante.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;C'est dans la STL ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Une recette de cuisine! Enfin!&lt;/li&gt;
&lt;li&gt;Il est vrai que ce n'est pas le thême de ce blog.&lt;/li&gt;
&lt;li&gt;Aujourd'hui, nous faisons notre pain.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Ingrédients&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;10 doigts et deux avant-bras qui n'ont pas peur.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;450 g de farine (j'ai pris une marque distributeur).&lt;/li&gt;
&lt;li&gt;1 sachet de levure de boulanger (8 g).&lt;/li&gt;
&lt;li&gt;1 cuillère de sel (rase).&lt;/li&gt;
&lt;li&gt;24 cl d'eau pure du robinet (2 verres à moutarde).&lt;/li&gt;
&lt;li&gt;1 pincée de sucre.&lt;/li&gt;
&lt;li&gt;Du papier cuisson.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;C'est parti.&lt;/h3&gt;
&lt;h5&gt;Préparation de la levure&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Versez tout de suite la levure dans un verre d'eau tempérée (12 cl
environ).&lt;/li&gt;
&lt;li&gt;Ajoutez dans le verre une pincée de sucre.&lt;/li&gt;
&lt;li&gt;Remuez légèrement et laissez reposer le temps de préparer le reste.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Préparation de la farine&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Versez 450 g de farine dans un plat.&lt;/li&gt;
&lt;li&gt;Ajoutez la cuillère rase de sel.&lt;/li&gt;
&lt;li&gt;Remuez avec une spatule pour mélanger le sel à la farine.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NB&lt;/strong&gt; : si il fait moins de 20 degrés chez vous, allumez
votre four à la température la plus basse.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Partie pénible&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Ajoutez le verre de levure diluée à la farine.&lt;/li&gt;
&lt;li&gt;Sans lui laissez le temps de se reprendre, ajoutez tout de suite un autre
verre d'eau.&lt;/li&gt;
&lt;li&gt;Mélangez le tout avec une spatule.&lt;/li&gt;
&lt;li&gt;Dès que c'est vaguement mélangé, plongez vos mains pleines de doigts et
pétrissez.
&lt;ul&gt;
&lt;li&gt;Si de la farine ne veut pas s'incorporer au mélange et reste au fond du
plat, enlevez la pate, et tapissez le fond d'un peu d'eau. Remettez ensuite la
pate et incorporez.&lt;/li&gt;
&lt;li&gt;Vous pouvez arrêter de pétrir dès que la pate ne vous colle plus au main
(il ne faut pas non plus que ce soit trop friable, si c'est le cas, ajoutez
quelques centilitres d'eau). Ceci prend (selon la quantité d'eau) de 5mn à
25mn. D'où l'intêret de ne pas trop mettre d'eau et d'en rajouter si besoin
est.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Premier arrêt&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Couvrez le plat, et laissez reposer au moins une heure.&lt;/li&gt;
&lt;li&gt;Si il fait froid chez vous, coupez le four préchauffé &lt;strong&gt;au
minimum&lt;/strong&gt; et placez le plat à l'intérieur.&lt;/li&gt;
&lt;li&gt;Quelques minutes avant de passer au second pétrissage, préparez votre
grille de cuisson en étalant dessus du papier cuisson, légèrement fariné.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Repétrissage et gonflage magique&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Une fois le papier cuisson disposé et fariné, il faut pétrir à nouveau la
pate.&lt;/li&gt;
&lt;li&gt;Dès qu'elle a un bel aspect lisse et pas collant, faites en une boule.&lt;/li&gt;
&lt;li&gt;Centrez cette boule sur votre papier cuisson, et saupoudrez la légèrement
de farine.&lt;/li&gt;
&lt;li&gt;Couvrez cette boule d' un saladier en plastique.
&lt;ul&gt;
&lt;li&gt;J'utilise le saladier qui a servi à la préparation (pas de vaisselle
inutile), mais tout récipient de taille convenable suffira.&lt;/li&gt;
&lt;li&gt;Cette astuce permet de ne plus avoir à manipuler le pain, et de le passer
directement au four une fois la seconde levée achevée.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Second arrêt&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Laissez reposer 1h30.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Mise au four&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Retirez le saladier en plastique, et mettez la grille au four, préchauffé à
180°.&lt;/li&gt;
&lt;li&gt;Cuisson: 210° pendant 35 minutes (surveillez la cuisson à partir de 30
minutes).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Et c'est tout&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Une fois cuit, laissez refroidir un peu.&lt;/li&gt;
&lt;li&gt;Prévoyez au moins 3/4h avant dégustation.&lt;/li&gt;
&lt;li&gt;Même si vous êtes pressé, attendez 15mn avant de couper votre pain. Plus il
est chaud, plus il est dur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Economie appréciable&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Si vous avez un grand four, vous pouvez préparer deux pains afin de
rentabiliser les 40 minutes d'electricité nécessaires à la cuisson.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La mort du petit commerce.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Terminé les excursions matinales dans une aube blême, à la recherche d'une
improbable baguette.
&lt;ul&gt;
&lt;li&gt;Vous allez pouvoir coder toute la nuit sans arrière pensée, et profiter
d'un pain excellent.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vu que le prix du pain semble indexé sur un matériau rare qui augmenterait
sans cesse, de notables économies sont à la clé.
&lt;ul&gt;
&lt;li&gt;Plus besoin d'aller vous faire ratisser chez le boulanger poujadiste du
coin.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Et il est bon au moins ce pain ?
&lt;ul&gt;
&lt;li&gt;Admirez la belle tenue. N'a-t-il pas l'air appétissant ?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://www.finiderire.com/public/images/painJs_resized.jpg&quot;&gt;&lt;img src=&quot;http://www.finiderire.com/public/images/.painJs_resized_m.jpg&quot; alt=&quot;PainFaitMaison&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;PainFaitMaison, oct. 2009&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/03/10/Du-pain-et-c-est-tout#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/03/10/Du-pain-et-c-est-tout#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/335349</wfw:commentRss>
      </item>
    
  <item>
    <title>GCC passe la seconde</title>
    <link>http://www.finiderire.com/post/2009/02/22/GCC-passe-la-seconde</link>
    <guid isPermaLink="false">urn:md5:823e7af414144e65648dd388b429b096</guid>
    <pubDate>Sun, 22 Feb 2009 22:27:00 +0100</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Coding</category>
        <category>C</category><category>coding</category><category>GCC</category><category>jeux video</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;Insupportable attente des compilations !&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Le quad-core refroidi à l'azote tire la langue. Son remplacement est
envisagé.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Avant de courir à &lt;q&gt;mon-galet&lt;/q&gt;, lisez ce qui suit.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;    &lt;h3&gt;Vroum ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Quelques secondes de compilation ? C'est toujours trop long.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous avons déja vu comment utiliser un cache de compilation avec Gentoo,
voici quelques astuces supplémentaires.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La situation de départ est celle-ci:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
~$ time g++ test.cpp -lIrrlicht -lpng -ljpeg -lGL -lXv -lXxf86vm -I/usr/include/irrlicht 

real    0m1.513s
user    0m1.298s
sys     0m0.204s
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les gens attentifs auront remarqué que la causerie de ce jour va utiliser
Irrlicht en guise d'exemple.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Irrlicht&lt;/em&gt; est un moteur 3D très sympathique, qui charge fortement
le processeur à la compilation.&lt;/li&gt;
&lt;li&gt;Les principes énoncés sont bien sûr universels (c'est beau ce que je
raconte, on croirait du &lt;em&gt;Zéro-Nain Informatique&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Au menu:
&lt;ul&gt;
&lt;li&gt;Précompilation des entêtes.&lt;/li&gt;
&lt;li&gt;Utilisation de librairies dynamiques, par opposition à la compilation
statique.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Quelques précisions sur les libs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Rappel:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;libIrrlicht.a&lt;/strong&gt; : lib &lt;em&gt;statique&lt;/em&gt; , liée à la
compilation (les objets de la lib dont les symboles sont référencés dans le
code seront intégrés à l'exécutable)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;libIrrlicht.so&lt;/strong&gt; : lib &lt;em&gt;dynamique&lt;/em&gt; (shared
object) , liée à l'exécution (le code est externe à l'exécutable, équivalent
des DLLs de MS-Windows)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Par défaut, si GCC trouve à la fois une librairie statique et une librairie
dynamique du même nom, il choisira la librairie dynamique.
&lt;ul&gt;
&lt;li&gt;On peut forcer l'utilisation de la librairie statique avec
&lt;strong&gt;-static&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ajouter temporairement un chemin de recherche pour les librairies
dynamiques:
&lt;ul&gt;
&lt;li&gt;utiliser la variable d'environnement du shell :
&lt;strong&gt;LD_LIBRARY_PATH&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;pour les changements permanents : &lt;code&gt;man ldconfig&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour les tests sur une machine donnée, on peut se simplifier la vie en
utilisant le flag &lt;strong&gt;-rpath&lt;/strong&gt; .
&lt;ul&gt;
&lt;li&gt;ce flag sert à spécifier en dur dans l'exécutable le chemin de recherche
des librairies dynamiques.&lt;/li&gt;
&lt;li&gt;ceci n'a aucune influence sur le temps de linkage.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;g++ test.cpp -lIrrlicht -lpng -ljpeg -lGL -lXv -lXxf86vm
-I/usr/include/irrlicht -L&amp;quot;$HOME&amp;quot;/sources/irrlicht-1.5/lib/Linux/
-Wl,-rpath=&amp;quot;$HOME&amp;quot;/sources/irrlicht-1.5/lib/Linux/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Préparation du moteur&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Par défaut, Irrlicht est compilé en statique.
&lt;ul&gt;
&lt;li&gt;c'est à dire, une simple archive qui sera intégrée dans l'exécutable à la
compilation.&lt;/li&gt;
&lt;li&gt;c'est à dire également, quelques megaoctets de choses inutiles pour le
développement.&lt;/li&gt;
&lt;li&gt;pour en savoir plus sur la préparation d'une bibliothèque statique:
&lt;code&gt;man ar&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Bien sûr, tout ceci est surtout valable pour le développement.
&lt;ul&gt;
&lt;li&gt;Pour la distribution, je vous conseille de repasser en statique, afin
d'être sûr de la version distribuée.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Aller dans les sources de Irrlicht
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;make sharedlib&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Par défaut, Irrlicht est construit avec les symboles de debug.
&lt;ul&gt;
&lt;li&gt;Il peut être utile de ne pas les avoir (on ne débuggera pas forcément tout
le temps).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Aller dans le répertoire &lt;em&gt;libs&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Vous devez trouver un fichier de ce type:
&lt;strong&gt;libIrrlicht.so.1.5&lt;/strong&gt; (ou un autre numéro de version).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mv libIrrlicht.so.1.5 libIrrlicht_debug.so.1.5&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Retourner dans le répertoire source de Irrlicht
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;make clean&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make NDEBUG=1 sharedlib&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ne pas oublier de créer les liens
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ln -s libIrrlicht_debug.so.1.5 libIrrlicht_debug.so&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ln -s libIrrlicht.so.1.5 libIrrlicht.so&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous pouvons déja tester le progrès avec la librairie dynamique
&lt;ul&gt;
&lt;li&gt;Nous indiquons le chemin de la lib dynamique avec le flag
&lt;strong&gt;-L&lt;/strong&gt; de GCC&lt;/li&gt;
&lt;li&gt;Si nous ne faisons pas cela, les chemins par défaut seront utilisés, et
Irrlicht sera linké en statique.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
~$ time g++ test.cpp -lIrrlicht -lpng -ljpeg -lGL -lXv -lXxf86vm -I/usr/include/irrlicht -L&amp;quot;$HOME&amp;quot;/sources/irrlicht-1.5/lib/Linux/

real    0m0.879s
user    0m0.770s
sys     0m0.101s
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Compilation des entêtes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;On ne dirait pas, mais un &lt;em&gt;include&lt;/em&gt; peut augmenter significativement
le temps de compilation.
&lt;ul&gt;
&lt;li&gt;de même que VisualC++, GCC peut les précompiler pour gagner du temps.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le fichier source doit débuter par un &lt;em&gt;include&lt;/em&gt; qui contiendra lui
même tous les includes du projet.
&lt;ul&gt;
&lt;li&gt;Ex: &lt;code&gt;#include &amp;quot;projet.h&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;projet.h&lt;/em&gt; contiendra:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
#include &amp;lt;math.h&amp;gt;
#include &amp;lt;irrlicht.h&amp;gt;
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;On le compile de cette façon:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;g++ projet.h -I/usr/include/irrlicht&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Normalement, vous devez obtenir un gros fichier nommé
&lt;strong&gt;projet.h.gch&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Si vos entêtes ne sont pas dans le chemin de recherche de gcc, n'oubliez
pas d'utiliser le flag &lt;strong&gt;-I&lt;/strong&gt; , comme je l'ai fait ci-dessus.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Plus qu'à tester:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
~/coding/irrlicht$ time g++ test.cpp -lIrrlicht -lpng -ljpeg -lGL -lXv -lXxf86vm -I/usr/include/irrlicht -L&amp;quot;$HOME&amp;quot;/sources/irrlicht-1.5/lib/Linux/ -Wl,-rpath=&amp;quot;$HOME&amp;quot;/sources/irrlicht-1.5/lib/Linux/

real    0m0.519s
user    0m0.444s
sys     0m0.069s
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Le gain par rapport au temps mis par la compilation en introduction est
sans appel.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Un makefile sera tout de même appréciable, ne serait-ce que pour gérer les
dépendances des entêtes.
&lt;ul&gt;
&lt;li&gt;Sa conception est laissée à titre d'exercice au lecteur.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Vroum!&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Et voila, avec quelques manoeuvres simples, nous nous retrouvons avec une
machine à la nouvelle jeunesse.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Avec l'argent économisé, vous pouvez faire un don &lt;del&gt;sur mon compte
offshore&lt;/del&gt; à ma fondation pour la réinsertion des Anciens de l'AS/400.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2009/02/22/GCC-passe-la-seconde#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2009/02/22/GCC-passe-la-seconde#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/329474</wfw:commentRss>
      </item>
    
  <item>
    <title>Passons la brosse au délégué</title>
    <link>http://www.finiderire.com/post/2008/12/09/Passons-la-brosse-au-delegue</link>
    <guid isPermaLink="false">urn:md5:6bbee767a5dfb967d86a057b726bc812</guid>
    <pubDate>Sat, 17 Jan 2009 09:37:00 +0100</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Coding</category>
        <category>C</category><category>coding</category><category>ImageMagick</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;Aujourd'hui, on passe la brosse.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Rassurez-vous, il ne s'agit pas d'un vil fayotage de bas étage.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Le délégué en question est un filtre ImageMagick&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Etendre ImageMagick&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ImageMagick présente une pléthore de formats.
&lt;ul&gt;
&lt;li&gt;Malgré tout, il arrive que certains formats ne soient pas supportés.&lt;/li&gt;
&lt;li&gt;Vous pouvez aussi avoir envie de voir votre propre format supporté.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;A titre d' exemple, je vous propose le format &lt;strong&gt;gbr&lt;/strong&gt; (Gimp
Brush, ce sont les brosses de Gimp).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La doc du format se trouve dans les sources de Gimp (cherchez le fichier
&lt;q&gt;gbr.txt&lt;/q&gt; ).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;gbr&lt;/strong&gt; est supporté depuis la version 6.4.6-5 de ImageMagick.
&lt;ul&gt;
&lt;li&gt;L'arbre portage de Gentoo ne contient pas une version supportant le format
&lt;em&gt;gbr&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Vous pouvez évidemment récupérer une version plus récente, ou vous servir
sur le cvs de ImageMagick.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Mise au point&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Je vous présente ici quelques pièges classiques , rencontrés lors du
développement de filtres.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Problèmes de conversion&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;En C, une erreur redoutable est le problème de conversion signed/unsigned
lors de la copie de données.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;-Wall&lt;/strong&gt; signale pas mal de choses, mais pas ces problèmes de
conversions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-Wconversion&lt;/strong&gt; vous le signalera, et devrait être
obligatoire pour arrêter les tractions capillaires lors de la mise au
point !&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Cas typique signalé par &lt;strong&gt;-Wconversion&lt;/strong&gt; :
&lt;ul&gt;
&lt;li&gt;Débordement des valeurs envoyées dans un buffer de type &lt;code&gt;char
*buffer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;En effet, ce buffer est &lt;em&gt;signed&lt;/em&gt; (déclaration par défaut du type
&lt;em&gt;char&lt;/em&gt;), ce qui n'est probablement pas ce que vous voulez.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Chargement et sauvegarde de structures&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Les structures sont la plaie du C, quand il s'agit de les charger ou les
décharger.
&lt;ul&gt;
&lt;li&gt;Pas d'autres choix que de sauver distinctement chacun des membres.&lt;/li&gt;
&lt;li&gt;Le chargement se fait également membre par membre.&lt;/li&gt;
&lt;li&gt;Ne vous amusez pas à packer vos structures afin d'éviter le padding du
compilateur. C'est une très mauvaise idée pour la portabilité, même au sein
d'une même architecture.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Problèmes liés au format TGA&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Attention, le format TGA est codé en BGR, et non pas en RGB.&lt;/li&gt;
&lt;li&gt;Exemple d'une conversion avec la source en 24 bits, et la destination en 32
bits (on ajoute juste le channel alpha, bloqué à 255).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
 for (i=0; i &amp;lt; tga_i-&amp;gt;tga_x * tga_i-&amp;gt;tga_y * 3; i+=3) {
   b_dst[j] = b_src[i+2]; //RGB -&amp;gt; BGR
   b_dst[j+1] = b_src[i+1];
   b_dst[j+2] = b_src[i];
   b_dst[j+3] = 255; //alpha
   j+=4;
} 
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Problèmes liés au format GBR&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Les entiers (type &lt;em&gt;int&lt;/em&gt;) de Gimp sont au format Motorola
(&lt;em&gt;Big-Endian&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La conversion vers le format &lt;em&gt;Little-Endian&lt;/em&gt; se fera à l'aide de
deux fonctions.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Une fonction pour lire les entiers :&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
int read_uint32 (unsigned char *p)
{
  return p[3] + (p[2]*256) + (p[1]*65536) + (p[0]*16777216);
} 
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une fonction pour écrire les entiers :&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
void write_uint32 (int i, FILE *fp)
{
  unsigned char c[4]={0};
  c[0] = (i&amp;gt;&amp;gt;24)&amp;amp;0xff;
  c[1] = (i&amp;gt;&amp;gt;16)&amp;amp;0xff;
  c[2] = (i&amp;gt;&amp;gt;8)&amp;amp;0xff;
  c[3] = i&amp;amp;0xff;

  writebuf (c, sizeof(int), fp);
} 
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pour mes conversions, j'ai été obligé de faire un flip horizontal
&lt;strong&gt;et&lt;/strong&gt; vertical de l'image, avant de l'enregistrer au format
&lt;em&gt;gbr&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Il suffit de reprendre le contenu du buffer TGA, et de le recopier en
l'inversant, et en tenant compte du fait qu'il est stocké au format BGR
(BlueGreenRed).&lt;/li&gt;
&lt;li&gt;Pour info :&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
//gbr-&amp;gt;datas[] est le buffer source
// flipped_pic est le buffer destination (qui contient les données flippées de la brosse)

 for (h = 0; h &amp;lt; gbr-&amp;gt;height; h++) {
   h_beg=h*gbr-&amp;gt;width*4;
   h_end=(gbr-&amp;gt;height*gbr-&amp;gt;width*4)-(h*gbr-&amp;gt;width*4);

   for (w = 0; w &amp;lt; gbr-&amp;gt;width*4; w+=4) {
      flipped_pic[h_end-1-(w+3)] = gbr-&amp;gt;datas[h_beg+(gbr-&amp;gt;width*4)-w-4];
      flipped_pic[h_end-1-(w+2)] = gbr-&amp;gt;datas[h_beg+(gbr-&amp;gt;width*4)-w-3];
      flipped_pic[h_end-1-(w+1)] = gbr-&amp;gt;datas[h_beg+(gbr-&amp;gt;width*4)-w-2];
      flipped_pic[h_end-1-(w)] =   gbr-&amp;gt;datas[h_beg+(gbr-&amp;gt;width*4)-w-1];
   }
} 
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;delegates.xml&lt;/h3&gt;
&lt;h5&gt;Principe&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Le fichier &lt;strong&gt;delegates.xml&lt;/strong&gt; sert à la configuration des
filtres ImageMagick.
&lt;ul&gt;
&lt;li&gt;Ces filtres sont appellés des &lt;q&gt;delegates&lt;/q&gt; dans la terminologie
ImageMagick.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez le trouver avec un &lt;em&gt;locate&lt;/em&gt;. Pour ma part, il se trouve
ici:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/usr/lib64/ImageMagick-6.3.7/config/delegates.xml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Dans ce fichier, vous trouverez la description des filtres et leur
paramétrage.
&lt;ul&gt;
&lt;li&gt;Plutot que de vous livrer une longue liste de paramètres, je vous invite à
lire ce fichier : tout ce qui est important est décrit en commentaires, au
début du fichier.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Le delegate le plus simple du monde&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;renommez l'extension d'un fichier &lt;strong&gt;png&lt;/strong&gt; en
&lt;strong&gt;pong&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;créez un fichier &amp;quot;pong_convert&amp;quot;, rendez le exécutable, et insérez-y ces
lignes:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
#!/bin/bash

if [[ x&amp;quot;$1&amp;quot; != x&amp;quot;&amp;quot; &amp;amp;&amp;amp; x&amp;quot;$2&amp;quot; != x&amp;quot;&amp;quot; ]]
then
  cp $1 $2
  echo &amp;quot;$1&amp;quot; a été converti en &amp;quot;$2&amp;quot;
else
  echo &amp;quot;Usage: $0 source.pong dest.png&amp;quot;
fi
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ajoutez dans votre fichier fichier &lt;em&gt;delegates.xml&lt;/em&gt; la ligne
suivante:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
&amp;lt;delegate decode=&amp;quot;pong&amp;quot; encode=&amp;quot;png&amp;quot; command='&amp;quot;/tmp/pong_convert &amp;quot;%i&amp;quot; &amp;quot;%o&amp;quot;'/&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez maintenant utiliser votre convertisseur
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;convert source.pong dest.png&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Utiliser tout ça ensemble&lt;/h3&gt;
&lt;h5&gt;Mais tout a déja été dit&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Je pense que l'essentiel a été dit.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Je pourrais bien sûr reprendre les paragraphes précédents, et détailler la
méthode pour la conversion des fichiers &lt;em&gt;gbr&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Mais je ne ferais que répéter ce que vous avez déja lu, sans apporter grand
chose d'intéressant.
&lt;ul&gt;
&lt;li&gt;Si vous avez des questions, n'hésitez pas, les commentaires sont là pour
ça.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Et les sources ?&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Je ne publie pas mes sources, car:
&lt;ul&gt;
&lt;li&gt;la partie TGA est assez ancienne (2002) et mériterait un bon
nettoyage.&lt;/li&gt;
&lt;li&gt;Un filtre &lt;em&gt;gbr&lt;/em&gt; est disponible dans le cvs de ImageMagick, et ne
tardera donc pas à être intégré aux releases.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le post des sources dans ce billet est donc sans intêret.
&lt;ul&gt;
&lt;li&gt;Si néanmoins, et pour une raison qui m'échappe, vous désirez les sources du
convertisseur, demandez les en commentaire et je les posterai.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2008/12/09/Passons-la-brosse-au-delegue#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2008/12/09/Passons-la-brosse-au-delegue#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/306812</wfw:commentRss>
      </item>
    
  <item>
    <title>Coup de bash sur les alias</title>
    <link>http://www.finiderire.com/post/2008/12/23/Coup-de-bash-sur-les-alias</link>
    <guid isPermaLink="false">urn:md5:724109907587fb6bf8cd38e7ccf7ca39</guid>
    <pubDate>Tue, 23 Dec 2008 23:05:00 +0100</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Linuxeries</category>
        <category>Linux</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;Le blog n'est pas abandonné!&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Un (tout) petit billet pour vous le prouver, fidèles lecteurs anonymes et
desespérés.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Aujourd'hui, les &lt;strong&gt;alias&lt;/strong&gt;&lt;/em&gt;.&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Votre shell et les alias&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Si vous utilisez un shell Unix, il y a fort à parier que celui-ci supporte
les &lt;em&gt;alias&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Un &lt;em&gt;alias&lt;/em&gt; est un raccourci pour une commande.
&lt;ul&gt;
&lt;li&gt;Par exemple, &lt;q&gt;fusck&lt;/q&gt; pourrait être un alias pour &lt;q&gt;rm -rf /&lt;/q&gt;.
(ceci est un exemple. Ne faites pas ça chez vous, les enfants).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;.bashrc et les alias&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Bash ne déroge pas à la rêgle, en tant que shell le plus répandu.&lt;/li&gt;
&lt;li&gt;Ce n'est pas le meilleur, mais c'est celui que j'utilise.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Jetons un coup d'oeil dans son fichier de configuration,
&lt;q&gt;.bashrc&lt;/q&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
export PS1='\w\$ '
alias ls=&amp;quot;ls --color -hs&amp;quot;
export LESSCHARSET='latin1'
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il n'y a pas grand chose, mais je l'aime bien.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;On remarque un alias sur &lt;em&gt;ls&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Cet alias est incorrect, et pourtant, je le traine depuis un bout de temps
(depuis mes débuts sous Linux en fait.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Que fait &lt;em&gt;ls --color -hs&lt;/em&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;--color&lt;/strong&gt; sert à coloriser la sortie (ça se paramètre, mais
ce n'est pas le sujet ici).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-hs&lt;/strong&gt; : &lt;strong&gt;s&lt;/strong&gt;ize , &lt;strong&gt;h&lt;/strong&gt;uman
readable (la taille en octet est convertie dans une unité plus parlante).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Que fait la police ?!&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La grosse erreur ici consiste dans les paramètres.&lt;/li&gt;
&lt;li&gt;Vous allez me dire que c'est ennuyeux, vu qu'une commande aliasée sans
paramètres, ça ne sert pas à grand chose.&lt;/li&gt;
&lt;li&gt;Pour corriger:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;--color=auto&lt;/strong&gt; : va supprimer la coloration automatique
si la commande passe à travers un pipe.&lt;/li&gt;
&lt;li&gt;enlever le &lt;strong&gt;-hs&lt;/strong&gt; qui perturbe aussi les pipes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Testons&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;sans les modifications du .bashrc :&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
~$ ls / | head -1
total 56K
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;avec les modifications du .bashrc:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
~$ ls / | head -1
bin
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Et si on veut garder ses alias pourris ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Deux solutions:
&lt;ul&gt;
&lt;li&gt;appeller la commande avec le path complet: &lt;code&gt;/bin/ls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;préfixer la commande avec un slash: &lt;code&gt;\ls&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ces deux méthodes empêche l'aliasing par le shell.
&lt;ul&gt;
&lt;li&gt;Il vaut mieux cependant créer de nouvelles commandes pour les alias
paramétrés.&lt;/li&gt;
&lt;li&gt;Ex: &lt;code&gt;alias lls='ls --lh'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La morale de cette histoire&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La morale de cette histoire, c'est qu'il faut pas gonfler Gérald Lambert
quand il aliase son shell.
&lt;ul&gt;
&lt;li&gt;C'est la morale de ce billet, moi j'la trouve chouette, pas vous ? Ah
bon.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Sur ce: joyeux noel, paix dans le monde, et à l'année prochaine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2008/12/23/Coup-de-bash-sur-les-alias#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2008/12/23/Coup-de-bash-sur-les-alias#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/311879</wfw:commentRss>
      </item>
    
  <item>
    <title>Prototypons, petit patapon</title>
    <link>http://www.finiderire.com/post/2008/10/30/Prototyper-avec-Python</link>
    <guid isPermaLink="false">urn:md5:0d8f5d379efbfe41ad3fb2e7374ff41c</guid>
    <pubDate>Sun, 23 Nov 2008 23:16:00 +0100</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Coding</category>
        <category>C</category><category>coding</category><category>debugging</category><category>prototypage</category><category>Python</category>    
    <description>&lt;p&gt;&lt;em&gt;Prototypons! Avec Python!&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Mais pourquoi donc avec Python ?&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Parce que ça rime!&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;Remerciements à &lt;strong&gt;Frédéric Jolliton&lt;/strong&gt; pour son aide
permanente.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Prototyper: quoi, quand, où, pourquoi, avec qui ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;quoi&lt;/strong&gt; : prototyper, c'est écrire du code vite fait
pour vérifier qu'une idée est bonne (ou mauvaise, ce qui peut aussi s'avérer
utile).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;quand&lt;/strong&gt; : quand vous voulez ! Le plus tôt est peut
être le mieux.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;où&lt;/strong&gt; : dans vos projets dont la taille du listing
dépasse une feuille A4.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;pourquoi&lt;/strong&gt; : &lt;q&gt;parce qu'il faut tester!&lt;/q&gt; ( (c)
F.J.)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;avec qui&lt;/strong&gt; : avec un langage faisant office de glue ,
et collant rapidement les morceaux.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Ah bon! Et en clair ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;L'idée est d'utiliser Python pour tester rapidement des routines en C.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Cela évite d'avoir à écrire un cadre d'exécution complet en C.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Cela permet également de continuer à exécuter le programme, tout en faisant
des modifications à la volée.
&lt;ul&gt;
&lt;li&gt;Avec un squelette python de boucle principale, on peut modifier les
routines satellites écrites en C sans tout réinitialiser à chaque fois.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Différence entre extending et embedding.&lt;/h3&gt;
&lt;h5&gt;Extending&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;extending&lt;/strong&gt; : consiste à appeller du C depuis Python.
Nous avons deux possibilités:
&lt;ul&gt;
&lt;li&gt;Créer un &lt;strong&gt;module&lt;/strong&gt; Python, utilisé ensuite avec un simple
&lt;q&gt;import module&lt;/q&gt;. Ce module aura le même comportement que les modules
Python habituels.&lt;/li&gt;
&lt;li&gt;Utiliser &lt;strong&gt;ctypes&lt;/strong&gt; pour appeller des fonctions C depuis
Python. Ceci ne nécessite pas la création d'un module Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ctypes&lt;/strong&gt; est beaucoup plus simple à mettre en oeuvre que la
création d'un module.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;De plus, &lt;strong&gt;ctypes&lt;/strong&gt; est intégré à Python depuis la version
2.5&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Embedding&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;embedding&lt;/strong&gt; : consiste à faire tourner une machine
virtuelle Python dans un programme C.
&lt;ul&gt;
&lt;li&gt;non traité dans ce billet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Principe de l'extending avec ctypes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Comme il faut bien commencer par quelque chose, autant faire au plus
simple.
&lt;ul&gt;
&lt;li&gt;Nous utiliserons donc &lt;strong&gt;ctypes&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;On va utiliser une dll ou un .so (selon votre OS), que nous allons écrire
en C.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;On importe cette bibliothèque depuis Python, qu'on peut ensuite utiliser
comme n'importe quel module importé.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous allons également écrire un wrapper dans Python, ce qui présentera
plusieurs avantages:
&lt;ul&gt;
&lt;li&gt;Ne pas afficher les valeurs de retour de chaque sous-fonctions, lors de
l'appel d'une fonction. En effet, les fonctions Python vont retourner &amp;quot;None&amp;quot; ,
ce qui ne sera pas affiché dans le shell interactif. Ceci est valable pour mon
exemple, et n'est pas forcément souhaitable. Bien entendu, les valeurs
renvoyées par la bibliothèque C sont renvoyées au wrapper, à charge pour lui de
les traiter.&lt;/li&gt;
&lt;li&gt;Simplifier l'initialisation depuis Python: le wrapper comprendra du code
d'initialisation.&lt;/li&gt;
&lt;li&gt;Masquer la complexité des appels en C: le wrapper se chargera de passer les
paramètres éventuels, et de tester les codes de retour.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Faire appel au bon type&lt;/h3&gt;
&lt;h5&gt;Définir un type&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;ctypes&lt;/em&gt; permet de définir des types compatibles avec ceux du
C.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;De manière générale, il suffit de rajouter le préfixe &lt;strong&gt;c&lt;/strong&gt;_
au type C.
&lt;ul&gt;
&lt;li&gt;Quelques exemples (voir la doc de &lt;em&gt;ctypes&lt;/em&gt;) : c_char , c_int,
c_long, c_float&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Cas des pointeurs&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Les pointeurs :&lt;/li&gt;
&lt;li&gt;c_char_p et c_wchar_p : char * et wchar_t *&lt;/li&gt;
&lt;li&gt;c_void_p : void *&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Les types définis par &lt;em&gt;ctypes&lt;/em&gt; sont tous &lt;strong&gt;mutables&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;Cela signifie que vous pouvez les modifier à la volée dans Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Attention&lt;/strong&gt; : la modification d'une zone mémoire
déréférencée par un pointeur &lt;em&gt;ctypes&lt;/em&gt; crée une copie du contenu du
pointeur, et non pas une modification de la zone précédemment pointé.
&lt;ul&gt;
&lt;li&gt;Pourquoi ? Parce que les strings ne sont pas mutables en Python
(&lt;em&gt;c_void_p&lt;/em&gt; est logé à la même enseigne que les strings).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Si vous utilisez une fonction C qui a besoin d'un pointeur sur une zone
mémoire modifiable, il faut utiliser &lt;strong&gt;create_string_buffer&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;L'objet créé est accédé via les méthodes &lt;q&gt;raw&lt;/q&gt; et &lt;q&gt;string&lt;/q&gt; ,
selon que vous voulez la représentation &lt;em&gt;string&lt;/em&gt; ou pas
(&lt;em&gt;string&lt;/em&gt; : chaine terminée par zéro).&lt;/li&gt;
&lt;li&gt;Je sens qu'un exemple serait le bienvenu:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

#string python : pas mutable
&amp;gt;&amp;gt;&amp;gt; buffer_python=&amp;quot;Jean-Seb&amp;quot;
&amp;gt;&amp;gt;&amp;gt; buffer_python[2]=&amp;quot;x&amp;quot;
Traceback (most recent call last):
  File &amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;, line 1, in &amp;lt;module&amp;gt;
TypeError: 'str' object does not support item assignment


#buffer ctypes : mutable
&amp;gt;&amp;gt;&amp;gt; buffer_c=ctypes.create_string_buffer(&amp;quot;Jean-Seb&amp;quot;)
&amp;gt;&amp;gt;&amp;gt; type(buffer_c)
&amp;lt;class 'ctypes.c_char_Array_9'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; buffer_c.raw
'Jean-Seb\x00'
&amp;gt;&amp;gt;&amp;gt; buffer_c.raw=&amp;quot;0wned&amp;quot;
&amp;gt;&amp;gt;&amp;gt; buffer_c.raw
'0wnedSeb\x00'

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Les structures&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez directement définir et adresser des structures C en Python.
&lt;ul&gt;
&lt;li&gt;Pour cela, il faut utiliser &lt;strong&gt;ctypes.Structure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Il faut dériver de &lt;strong&gt;ctypes.Structure&lt;/strong&gt; une nouvelle classe,
et définir un attribut &lt;strong&gt;_fields&lt;/strong&gt;_.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;_fields&lt;/strong&gt;_ est un tuple contenant un champs &lt;em&gt;nom&lt;/em&gt; et
un champs &lt;em&gt;type&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Tous les types de &lt;strong&gt;ctypes&lt;/strong&gt; peuvent être utilisés.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Voici le code en C qui définit, puis affiche une structure&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

typedef struct {
  char *name;
  int age;
} MASTRUCT;

void print_struct(MASTRUCT *mastruct)
{
  printf(&amp;quot;je suis %s et j'ai %d ans\n&amp;quot;, 
          mastruct-&amp;gt;name, mastruct-&amp;gt;age);
}

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Et voici comment créer une structure avec Python, pour la passer ensuite à
la fonction en C.
&lt;ul&gt;
&lt;li&gt;On passe le pointeur à la structure en utilisant
&lt;strong&gt;ctypes.byref&lt;/strong&gt; . Cette fonction retourne un pointeur, mais ce
pointeur est uniquement utilisable en tant qu'argument de fonction. Sinon, il
faudra utiliser &lt;strong&gt;ctypes.pointer&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

&amp;gt;&amp;gt;&amp;gt; import ctypes
&amp;gt;&amp;gt;&amp;gt; dll = ctypes.CDLL(&amp;quot;./malib.so&amp;quot;)

&amp;gt;&amp;gt;&amp;gt; class mastruct(ctypes.Structure) :
        _fields_ = [ (&amp;quot;nom&amp;quot;, ctypes.c_char_p),
                            (&amp;quot;age&amp;quot;, ctypes.c_int) ]
        
&amp;gt;&amp;gt;&amp;gt; ms = mastruct(&amp;quot;Marcel&amp;quot;, 42)
&amp;gt;&amp;gt;&amp;gt; print ms
&amp;lt;__main__.mastruct object at 0x2abfcecf6af0&amp;gt;
&amp;gt;&amp;gt;&amp;gt; print ms.age , ms.nom
42 Marcel
&amp;gt;&amp;gt;&amp;gt; dll.print_struct(ctypes.byref(ms))
je suis Marcel et j'ai 42 ans

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Module &lt;em&gt;util&lt;/em&gt; de &lt;em&gt;ctypes&lt;/em&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;ctypes&lt;/em&gt; possède un module fort utile, judicieusement nommé
&lt;em&gt;util&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;import ctypes.util&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La fonction la plus utile de ce module est &lt;strong&gt;find_library&lt;/strong&gt;,
qui permet d'avoir le nom complet d'une bibliothèque.
&lt;ul&gt;
&lt;li&gt;Attention à ne pas ajouter &lt;q&gt;lib&lt;/q&gt; sous Linux, sinon, la fonction ne
trouvera rien.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

&amp;gt;&amp;gt;&amp;gt; ctypes.util.find_library(&amp;quot;c&amp;quot;)
'libc.so.6'

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La grande ruse du rechargement de bibliothèque.&lt;/h3&gt;
&lt;h5&gt;Avertissement façon Java&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Pour recharger une bibliothèque, on utilise normalement un module python,
que l'on rechargera en cas de modification de la bibliothèque.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Bien que ce soit la méthode habituelle et recommandée, elle a pour
inconvénient d'être plus contraignante que la méthode que je vais vous
présenter.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour le développement d'une DLL de centrale nucléaire ou d'un accélérateur
de particule, je vous conseille toutefois la méthode classique.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Concernant ce passage, Fred souhaite ajouter cela : &lt;q&gt;bon, en tout
cas, je ne veux pas être associé a tes bidouilles avec dlopen/dlclose
&lt;img src=&quot;/themes/default/smilies/smile.png&quot; alt=&quot;:)&quot; class=&quot;smiley&quot; /&gt;&lt;/q&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Le problème&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Normalement, on ne peut importer une bibliothèque qu'une seule fois.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;malib = ctypes.CDLL(&amp;quot;./malib.so&amp;quot;)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;malib&lt;/em&gt; ne sera pas rechargée si vous appellez à nouveau le code
ci-dessus.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ce comportement peut poser problème, notamment dans le cas d'une
bibliothèque en développement, ce qui est souvent le cas quand on fait du
prototypage.
&lt;ul&gt;
&lt;li&gt;En effet, l'ajout ou la modification de fonctions dans la bibliothèque
n'est pas pris en compte dans la même session Python.&lt;/li&gt;
&lt;li&gt;Cela ne pose pas de problèmes dans le cas d'un script Python, mais est très
gênant si vous souhaitez garder un shell Python ouvert, et faire des
modifications à la volée.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;La solution&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Alors, on pleure ? Non. On ruse.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;L'astuce consiste à passer à &lt;strong&gt;ctypes.CDLL&lt;/strong&gt; un handle sur une
bibliothèque déja ouverte.
&lt;ul&gt;
&lt;li&gt;En cas de modification de cette bibliothèque, rien n'empêche de la fermer,
puis de la recharger de la même manière.&lt;/li&gt;
&lt;li&gt;Les modifications seront bien prises en compte.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Tout ceci nécessite l'utilisation de la bibliothèque &lt;strong&gt;libdl&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Nous l'initialisons de façon classique, et nous récupérons des pointeurs
sur les fonctions que nous allons utiliser.&lt;/li&gt;
&lt;li&gt;Il convient de préciser le type de retour pour la fonction &lt;em&gt;dlopen&lt;/em&gt;
, qui par défaut est un type long. Nous voulons à la place un pointeur void, ce
qui correspond au prototype de &lt;em&gt;dlopen&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

&amp;gt;&amp;gt;&amp;gt; import ctypes
&amp;gt;&amp;gt;&amp;gt; libdl = ctypes.CDLL(&amp;quot;libdl.so.2&amp;quot;)
&amp;gt;&amp;gt;&amp;gt; dlopen = libdl.dlopen   #récupère un pointeur de fonction
&amp;gt;&amp;gt;&amp;gt; dlclose = libdl.dlclose

&amp;gt;&amp;gt;&amp;gt; print dlopen.restype
&amp;lt;class 'ctypes.c_long'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; dlopen.restype = ctypes.c_void_p

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;L'initialisation est terminée, nous allons maintenant utiliser
&lt;em&gt;dlopen&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;dlopen&lt;/em&gt; sert à ouvrir une bibliothèque, et récupérer son
handle.&lt;/li&gt;
&lt;li&gt;Le premier paramètre est évident: c'est le nom de la bibliothèque à
ouvrir.&lt;/li&gt;
&lt;li&gt;Le second l'est moins, et correspond à un flag. Nous allons utiliser
&lt;strong&gt;RTLD_NOW&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;La valeur des flags de la fonction est défini ici:
&lt;code&gt;/usr/include/bits/dlfcn.h&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Je vais rentrer en dur la valeur du flag, qui a l'air universelle. En cas
de problèmes, vérifiez cette valeur.&lt;/li&gt;
&lt;li&gt;En résumé: &lt;code&gt;#define RTLD_NOW 0x00002 /* Immediate function call
binding */&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

&amp;gt;&amp;gt;&amp;gt; monhandle = dlopen(&amp;quot;./hello_extend.so&amp;quot;, 2)

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maintenant que nous avons obtenu un handle sur notre bibliothèque, nous
pouvons l'utiliser avec &lt;strong&gt;ctypes.CDLL&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Par défaut, &lt;strong&gt;CDLL&lt;/strong&gt; s'occupe de l'ouverture de la
bibliothèque.&lt;/li&gt;
&lt;li&gt;On peut toutefois lui passer en paramètre le handle d'une bibliothèque déja
ouverte. Ainsi, il ne s'occupera pas de l'ouverture de la bibliothèque, et nous
pourrons demander sa fermeture (ce qui est impossible si on délègue l'ouverture
à &lt;em&gt;CDLL&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

&amp;gt;&amp;gt;&amp;gt; malib = ctypes.CDLL(&amp;quot;./hello_extend.so&amp;quot;, handle = monhandle)

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Voila, vous pouvez à présent utiliser normalement la bibliothèque.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Procédure pour recharger la bibliothèque :
&lt;ul&gt;
&lt;li&gt;faire un &lt;em&gt;dlclose&lt;/em&gt; avec le handle de cette bibliothèque.&lt;/li&gt;
&lt;li&gt;obtenir un nouvea handle sur cette bibliothèque avec &lt;em&gt;dlopen&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;utiliser &lt;em&gt;ctypes.CDLL&lt;/em&gt; avec le nouveau handle en paramètre.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

&amp;gt;&amp;gt;&amp;gt; dlclose(monhandle)
&amp;gt;&amp;gt;&amp;gt; monhandle = dlopen(&amp;quot;./hello_extend.so&amp;quot;,2)
&amp;gt;&amp;gt;&amp;gt; malib = ctypes.CDLL(&amp;quot;./hello_extend.so&amp;quot;, handle = monhandle)

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Et pour MS-Windows ?&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Je n'ai pas testé. Voici quelques pistes pour ceux qui voudront s'y
atteler.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le principe est le même que pour Unix, à part pour les noms de fonctions de
gestion de bibliothèque.
&lt;ul&gt;
&lt;li&gt;Par exemple, &lt;em&gt;dlopen&lt;/em&gt; deviendra &lt;em&gt;LoadLibrary&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Bien entendu, les paramètres ne seront pas les mêmes, je vous laisse
consulter le MSDN.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Si vous faites le test, merci d'écrire un commentaire ou de m'envoyer un
mail. Je complèterai le billet.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Mise en oeuvre : bibliothèque C utilisable depuis Python via un
wrapper.&lt;/h3&gt;
&lt;h5&gt;bibliothèque C : &lt;strong&gt;hello_extend.c&lt;/strong&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Rien de particulier à signaler dans le fichier source qui exporte ces
fonctions:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;get_version()&lt;/code&gt; : retourne un entier correspondant au
numéro de version&lt;/li&gt;
&lt;li&gt;&lt;code&gt;print_persion()&lt;/code&gt; : imprime sur la sortie standard le
numéro de version.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;test_version(int version_attendue)&lt;/code&gt; : teste la version de
la bibliothèque.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;print_struct (MASTRUCT *mastruct)&lt;/code&gt; : affiche une structure
(détails dans la partie consacrée aux types).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Compilez avec:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gcc -shared -fPIC -Wall -W hello_extend.c -o
hello_extend.so&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Pour les systèmes MS-Windows, enlevez le paramètre &lt;code&gt;-fPIC&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le source en lui même est du C de base, je n'encombre pas le billet avec.
&lt;ul&gt;
&lt;li&gt;Vous trouverez le fichier source dans l'archive en annexe.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Module d'importation Python : &lt;strong&gt;dll.py&lt;/strong&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Ce module a été amplement décrit plus haut.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il sera appelé automatiquement lors de l'initialisation du wrapper Python.
&lt;ul&gt;
&lt;li&gt;Vous n'avez donc pas à vous soucier de son initialisation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Par la suite, en cas de modification de la bibliothèque C, il faudra la
recharger
&lt;ul&gt;
&lt;li&gt;depuis le module dll: &lt;code&gt;dll.restart()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ou depuis le wrapper (voir plus loin):
&lt;code&gt;hello_wrapper.restart()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Wrapper Python : &lt;strong&gt;hello_wrapper.py&lt;/strong&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Important&lt;/strong&gt; : le nom du module Python doit être
différent du nom de la bibliothèque C (les extensions ne comptent pas pour la
différenciation).
&lt;ul&gt;
&lt;li&gt;Dans le cas contraire, vous obtiendrez une erreur assez cryptique lors de
l'import du wrapper dans Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le wrapper va appeler pour vous les fonctions de la bibliothèque, et tester
les paramètres, ainsi que les codes de retour.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il est important de tester les paramètres depuis le code Python. Prenons
pour exemple la fonction d' affichage de structure.
&lt;ul&gt;
&lt;li&gt;Le strict minimum dans le code C serait de tester un pointeur &lt;em&gt;null&lt;/em&gt;
et de ne pas exécuter la fonction en cas de pointeur invalide.&lt;/li&gt;
&lt;li&gt;Ce genre de test ne sert pas à grand chose. Même si le pointeur nul n'est
pas exclu, il y a plus de probabilités pour qu'un objet d'un type invalide soit
passé. Ce dernier cas &lt;q&gt;passerait&lt;/q&gt; le test du pointeur nul, mais provoquera
probablement un beau plantage.&lt;/li&gt;
&lt;li&gt;Il faut donc tester depuis Python que l'on passe bien une structure valide,
afin de limiter les dégats potentiels. Je dis &lt;q&gt;limiter les dégats&lt;/q&gt;, car le
fait de passer une structure valide ne présume en rien de son contenu.&lt;/li&gt;
&lt;li&gt;Voici un exemple de test de paramètre, pour la fonction d'affichage de
structure: on teste si l'objet est bien la structure réglementaire.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;

def print_struct(obj):
   if isinstance (obj, mastruct):
     dll.malib.print_struct (ctypes.byref(obj))
   else:
     print &amp;quot;Objet invalide, ce n'est pas une structure &amp;lt;mastruct&amp;gt;&amp;quot;
     print &amp;quot;type de l'objet :&amp;quot;, type(obj)

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les tests sur les codes de retour sont évidents, et n'appelent pas de
commentaires particuliers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h5&gt;Et enfin, appel du code depuis Python&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;import hello_wrapper&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;ensuite, vous pouvez appeller classiquement les fonctions.&lt;/li&gt;
&lt;li&gt;Par exemple: &lt;code&gt;hello_wrapper.print_version()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;En cas de modification de la bibliothèque, rechargez la depuis python avec
&lt;code&gt;hello_wrapper.restart()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;C'est terminé, mais quelle est donc cette perplexité ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Voici la fin d'un gros morceau. J'espère que c'était clair et que ça vous a
plu.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Je n'ai rien inventé, et tout se trouve dans le lien qui suit. Lisez au
moins le tutorial, très bien fait:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.python.org/doc/2.5.2/lib/module-ctypes.html&quot;&gt;La doc de
ctypes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.python.org/library/ctypes.htm&quot;&gt;Une autre
approche&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Après toute cette partie théorique, nous allons nous pencher sur la mise en
pratique des connaissances acquises.
&lt;ul&gt;
&lt;li&gt;Cela fera l'objet d'un projet billet, je vous laisse digérer celui-ci en
attendant &lt;img src=&quot;/themes/default/smilies/wink.png&quot; alt=&quot;;)&quot; class=&quot;smiley&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
          <enclosure url="http://www.finiderire.com/public/exemple_ctypes.tar.bz2"
      length="1459" type="text/plain" />
    
    
          <comments>http://www.finiderire.com/post/2008/10/30/Prototyper-avec-Python#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2008/10/30/Prototyper-avec-Python#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/289466</wfw:commentRss>
      </item>
    
  <item>
    <title>Conversion rituelle d'un fichier textuel</title>
    <link>http://www.finiderire.com/post/2008/10/18/Conversion-rituelle-d-un-fichier-egare</link>
    <guid isPermaLink="false">urn:md5:e15c99dce3631a96238b805e296acc07</guid>
    <pubDate>Thu, 23 Oct 2008 21:33:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Vim</category>
        <category>vim</category>    
    <description>&lt;p&gt;&lt;em&gt;Halte au paganisme chez les fichiers texte!&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Convertissez les tous, Vim reconnaitra les siens!&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Oecuménisme débridé&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dans l'informatique, il n'est plus question de tolérance ni de droit à la
différence.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Et pourtant, quelle pire jungle que les fichiers textes ?&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Nous allons nous faire les apôtres d'une conversion de masse, et plus
jamais aucun fichier ne vous narguera.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Le Dos au mur.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;L'édition d'un fichier venant de Dos/Windows est très pénible.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Notamment si vous le rendez exécutable, et que vous ajoutez une ligne de ce
style en guise d'entête:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#!/usr/bin/python&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Si votre fichier est enregistré au format Dos/Windows, c'est à dire avec
&lt;strong&gt;0xD 0xA&lt;/strong&gt; en guise de terminateur de ligne, vous allez vous
faire insulter à l'exécution:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/bin/python^M: bad interpreter&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez toujours courir pour éliminer le caractère &lt;strong&gt;0xD&lt;/strong&gt;
sous Vim.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:%s/^M//g&lt;/code&gt; : no matches (comment ça &amp;quot;no matches&amp;quot; ?!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous pourriez le convertir avec Sed
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cat foo.py | sed 's/^M/g' &amp;gt;foo2.py &amp;amp;&amp;amp; mv foo2.py
foo.py&lt;/code&gt; : un peu lourdingue, mais fonctionne&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il y a plus simple. Il suffit de prévenir Vim que vous utilisez un OS de
Vrai Mec.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:set ff=unix&lt;/code&gt; , puis sauvez le fichier.&lt;/li&gt;
&lt;li&gt;et voila. Le fichier est converti.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La conversion inverse est possible (quelle idée bizarre):
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:set ff=dos&lt;/code&gt; : pour faire des farces à vos camarades.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Définition du format de fichier au démarrage de Vim&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pour choisir le format de fichier adapté au démarrage de Vim, il vous
suffit de placer dans &lt;em&gt;.vimrc&lt;/em&gt; :
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;set ff=x&lt;/code&gt; (avec x = &lt;em&gt;dos&lt;/em&gt;, &lt;em&gt;unix&lt;/em&gt; ou &lt;em&gt;mac&lt;/em&gt;
)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Le problème est que vous ne pouvez plus reprendre votre &lt;em&gt;.vimrc&lt;/em&gt; sur
un OS différent sans modifier la ligne positionnant le format.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il vaut mieux détecter l'OS au démarrage, et faire le &lt;q&gt;ff&lt;/q&gt;
correspondant.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vim est un curieux, et il peut vous dire beaucoup de chose sur sa
plate-forme d'exécution: &lt;code&gt;help feature-list&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Il faut que Vim ait été compilé avec +feature-list (c'est le cas des
versions MS-Windows précompilées).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour tester, créez un fichier &lt;strong&gt;.detecte_os.vim&lt;/strong&gt; , et insérez
le code ci-dessous.
&lt;ul&gt;
&lt;li&gt;Pour charger ce fichier depuis Vim: &lt;code&gt;:so .detecte_os.vim&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Pour exécuter la fonction: &lt;code&gt;:call Detecte_OS()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
&amp;quot;fichier: .detecte_os.vim
&amp;quot;doc: help feature-list

&amp;quot;les noms de fonction commencent par une majuscule
function! Detecte_OS()

if has(&amp;quot;unix&amp;quot;)
   echo &amp;quot;version Unix detectée&amp;quot;
   set ff=unix
elseif has(&amp;quot;macunix&amp;quot;)
   echo &amp;quot;MacOS X detecté&amp;quot;
   set ff=mac
else
   echo &amp;quot;Version de Vim inconnue. Surement Windows.&amp;quot;
   set ff=dos
endif

endfunction
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez appeller cette fonction au démarrage de Vim, en insérant ceci
dans votre &lt;em&gt;.vimrc&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
so ~/.detecte_os.vim
autocmd VimEnter * call Detecte_OS()
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;L'encodage des fichiers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Le format de fichier est une chose, l'encodage en est une autre.
&lt;ul&gt;
&lt;li&gt;La phrase précédente n'apportant pas grand chose dans ce grand cri
numérique qu'est Internet, je précise ma pensée.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;le &lt;strong&gt;format&lt;/strong&gt; de fichier: il concerne la structure du fichier,
c'est à dire la façon dont sont encodées les fins de lignes (0x0D0A pour la
famille Dos, 0x0A pour le reste du monde).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;l' &lt;strong&gt;encodage&lt;/strong&gt; des fichiers : il concerne les tables de
caractères utilisés pour les fichiers (UTF-8, iso-8859-x etc.).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Typiquement, les problèmes d'encodages se repèrent avec les accents dans
les fichiers texte.
&lt;ul&gt;
&lt;li&gt;un bel accent ascii tel que celui ci: &lt;strong&gt;é&lt;/strong&gt; , sera encodé sous
cette forme en UTF-8: &lt;strong&gt;Ã©&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;l'encodage des fichiers se règle sous Vim avec les variables
&lt;strong&gt;encoding&lt;/strong&gt; , &lt;strong&gt;fileencoding&lt;/strong&gt; et
&lt;strong&gt;fileencodings&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;encoding&lt;/strong&gt; détermine l'encodage des caractères utilisé au
sein de Vim.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fileencoding&lt;/strong&gt; détermine l'encodage à utiliser lors de la
&lt;strong&gt;sauvegarde&lt;/strong&gt; d'un fichier (eh oui, c'est subtil)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fileencodings&lt;/strong&gt; (avec un &lt;q&gt;s&lt;/q&gt; final) donne une liste de
tables d'encodage à utiliser lors de l'édition d'un nouveau fichier. Vim tente
d'utiliser la première de la liste, puis la seconde, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Sans plus attendre, sautons au paragraphe suivant pour nous vautrer dans le
concret.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Illustration des problèmes d'encodage de fichiers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Un exemple type des problèmes que vous allez rencontrer avec les encodages
de fichier est le mapping des touches dans Vim.&lt;/li&gt;
&lt;li&gt;Pour remapper une touche, vous utilisez la commande &lt;q&gt;map&lt;/q&gt;,
généralement placée dans votre .vimrc (si vous voulez un comportement
permanent).
&lt;ul&gt;
&lt;li&gt;Ex: &lt;code&gt;map µ :set cursorline! cursorcolumn!&amp;lt;CR&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Dans l'exemple précédent, on utilise une touche qui va être encodée sur
deux caractères en UTF-8.
&lt;ul&gt;
&lt;li&gt;Si votre fichier &lt;em&gt;.vimrc&lt;/em&gt; est encodée en latin1et que votre terminal
fonctionne en Unicode, le code caractère ne correspondra pas.&lt;/li&gt;
&lt;li&gt;Si vous avez un doute, &lt;em&gt;hexdump&lt;/em&gt; peut vous aider à être sûr de
l'encodage utilisé.&lt;/li&gt;
&lt;li&gt;Le plus simple est de vérifier avec &lt;code&gt;:set fileencoding&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Dans mon cas, j'utilise un terminal unicode (c'est &lt;em&gt;urxvt&lt;/em&gt;, que je
vous recommande).
&lt;ul&gt;
&lt;li&gt;J'ai simplement choisi l'encodage des fichiers en UTF-8, et j'ai sauvé le
fichier.&lt;/li&gt;
&lt;li&gt;Résultat: plus de problèmes pour la prise en compte de mes raccourcis
claviers.&lt;/li&gt;
&lt;li&gt;la commande magique: &lt;code&gt;set fileencoding=UTF-8&lt;/code&gt; (suivi d'un
&lt;em&gt;write&lt;/em&gt;, bien sûr).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Baptême de masse avec Skippy (et &lt;em&gt;iconv&lt;/em&gt;)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tout cela est bien beau, mais vous pourriez vous retrouver avec une masse
de fichiers à convertir.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Dans ce cas, hors de question des les ouvrir un par un avec Vim.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Heureusement, Skippy pense à vous, et vous propose un baptême de masse.
Avec siphonnage des comptes bancaires associés, bien sûr.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour ce faire:
&lt;ul&gt;
&lt;li&gt;rasez-vous le crane.&lt;/li&gt;
&lt;li&gt;mettez vos lunettes noires.&lt;/li&gt;
&lt;li&gt;ressortez votre peignoir.&lt;/li&gt;
&lt;li&gt;et, j'allais l'oublier, n'oubliez pas &lt;strong&gt;iconv&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Voici un exemple de commande pour vous montrer la bête en action.
&lt;ul&gt;
&lt;li&gt;Ceci converti les sources C d'un répertoire et de ses descendants de
iso-8859-1 vers UTF-8.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;find . -iname &amp;quot;*.c&amp;quot; | while read filename; do iconv -f iso-8859-1 -t
UTF-8 &amp;quot;$filename&amp;quot; &amp;gt; ${filename%.*}_utf8.c ; done&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Quelques remarques sur l'exemple précédent:
&lt;ul&gt;
&lt;li&gt;On utilise l'astuce du while (merci Frédéric) : ceci permets de
traiter les résultats du &lt;q&gt;find&lt;/q&gt; avec une redirection.&lt;/li&gt;
&lt;li&gt;Sans redirection (nécessaire dans le cas de &lt;em&gt;iconv&lt;/em&gt; pour créer le
fichier cible), nous aurions pu utiliser &lt;em&gt;xargs&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;n'oubliez pas que &lt;code&gt;iconv -l&lt;/code&gt; va vous lister les jeux de
caractères supportés en entrée et en sortie de &lt;em&gt;iconv&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Parenthèse en guise de conclusion&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Une astuce que je viens de découvrir avec &lt;em&gt;xargs&lt;/em&gt; (merci Frédéric)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xargs -I{} echo {} {}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cela sert à réutiliser plusieurs fois le nom que l'on passe par le tube. On
met ce qu'on veut comme identifiant (&lt;strong&gt;-I&lt;/strong&gt;), bien sûr.&lt;/li&gt;
&lt;li&gt;Mais nous nous éloignons carrément du sujet. Fermons là le ban.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2008/10/18/Conversion-rituelle-d-un-fichier-egare#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2008/10/18/Conversion-rituelle-d-un-fichier-egare#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/289351</wfw:commentRss>
      </item>
    
  <item>
    <title>Make Mayday</title>
    <link>http://www.finiderire.com/post/2008/10/02/Make-Mayday</link>
    <guid isPermaLink="false">urn:md5:0f0d8652c3d9f38bce927d6a6d174012</guid>
    <pubDate>Fri, 03 Oct 2008 19:03:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Tools</category>
        <category>coding</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;On ne présente plus Make, le gestionnaire de projets.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;D'ailleurs, je ne vais pas le présenter.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Sans plus attendre, le livre de cuisine de Make&lt;/em&gt;&lt;br /&gt;
&lt;strong&gt;Mise à jour 14 oct.&lt;/strong&gt; : ajout d'une rêgle de génération de
noms de fichiers.&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Les points sur les &lt;q&gt;i&lt;/q&gt; en guise d'introduction&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ce texte ne reprend pas les explications de base.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Prenez le comme un condensé de rêgles et d'astuces utiles, découvertes au
fur et à mesure de mes développements.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La doc complète se trouve &lt;a href=&quot;http://www.gnu.org/software/make/manual/make.html&quot;&gt;ici&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Comme d'habitude, j' enrichirai ce billet à mesure de mes découvertes et de
vos nombreux commentaires.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Rêgles génériques&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La plus courante: compiler les fichiers &lt;em&gt;*.c&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;%.o: %.c&lt;/strong&gt; : définition de la boucle de
compilation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;$&amp;lt;&lt;/strong&gt; : substituer avec le fichier à droite des deux
points de la rêgle (ici: &lt;q&gt;%.c&lt;/q&gt; )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
%.o: %.c
         gcc -c $&amp;lt;
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Quelques autres variables internes à Make:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;$@&lt;/strong&gt; = cible (valeur à gauche des deux points de la
rêgle).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;$^&lt;/strong&gt; = affiche la valeur source avec tout ses prérequis
(peut servir à obtenir le path complet d'un fichier)&lt;/li&gt;
&lt;li&gt;Pour les autres: &lt;strong&gt;10.5.3 Automatic Variables&lt;/strong&gt; dans la page
&lt;em&gt;info&lt;/em&gt; de Make.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La cible .PHONY&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La cible .PHONY sert à spécifier une rêgle qui ne correspond pas à la
génération d'un fichier.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Elle correspond à une commande à exécuter quand on le demande
explicitement.
&lt;ul&gt;
&lt;li&gt;Les rêgles &lt;em&gt;PHONY&lt;/em&gt; sont généralement utilisées pour les opérations
de nettoyage et d'installation.&lt;/li&gt;
&lt;li&gt;Corollaire: elles permettent donc d'exécuter une rêgle Make si un fichier
porte le même nom.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Exemple (avec les rêgles &lt;em&gt;all&lt;/em&gt; et &lt;em&gt;clean&lt;/em&gt;) :
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.PHONY: all clean&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Dans l'exemple précédent, on déclare deux cibles &lt;em&gt;all&lt;/em&gt; et
&lt;em&gt;clean&lt;/em&gt;. Si des fichiers de même nom existent, il n'y aura pas
conflit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Détection d'une plateforme&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Utiliser la commande &lt;strong&gt;shell&lt;/strong&gt; qui permet de lancer des
commandes.&lt;/li&gt;
&lt;li&gt;Une fois la variable &lt;em&gt;win32&lt;/em&gt; positionnée (ou non), on peut faire un
test avec &lt;strong&gt;ifdef / else / endif&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
OS=$(shell uname | cut -f1 -d'_')
ifeq ($(OS),MINGW32)
win32=1
endif
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Fonction d'affichage coloré&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Définition d'une fonction &lt;em&gt;print&lt;/em&gt; colorée (Fred adore).
&lt;ul&gt;
&lt;li&gt;Définir les codes couleurs au format ANSI.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
info=\033[40;33;01m
warn=\033[41;36;01m
help=\033[41;33;01m
rem=\033[40;34;01m
define print
        @echo -e &amp;quot;$($(2)) $(1) \033[0m&amp;quot;
endef
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Utilisation de la fonction &lt;em&gt;print&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$(call print,&amp;quot;all done&amp;quot;,warn)&lt;/code&gt; : une chaine toute
simple.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$(call print,Construction de $(exe),info)&lt;/code&gt; : on peut
également substituer des variables.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Génération des dépendances&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;J'en parle dans un autre post de ce blog :
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.finiderire.com/post/2007/09/24/Jai-decroche-de-ma-dependance-grace-a-GCC&quot;&gt;
génération des dépendances avec GCC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;En bref:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
deps:
        @echo génération des dépendances
        @rm -f mes_deps
        @$(CC) -MM *.c* &amp;gt;&amp;gt;mes_deps

-include mes_deps
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Fichiers sources situés dans plusieurs répertoires&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;On peut éviter de préfixer chaque fichier source par son répertoire.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;VPATH permet d'indiquer où chercher les fichiers sources.
&lt;ul&gt;
&lt;li&gt;Syntaxe: &lt;code&gt;VPATH=foo:bar:baz&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Comment utiliser un fichier qui n'est pas dans le répertoire courant ?
&lt;ul&gt;
&lt;li&gt;Il faut utiliser la variable automatique &lt;strong&gt;$^&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour la compilation, nous allons donc utiliser cette variable
automatique.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
 %.o : %.c
        $(CC) -c $^ -o $@ $(CFLAGS)
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pour linker , même principe:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
$(exe): $(obj)
        $(CC) $^ -o $@ $(LDFLAGS) $(libs)
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Et pour générer les dépendances:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
deps:
        @rm -f mes_deps
        @$(CC) -I$(VPATH) -MM *.c* $(VPATH)/*.c* &amp;gt;&amp;gt;mes_deps
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Fichiers sources dispersés, objets dans un répertoire spécifique&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dans le cas précédent, les objets vont se retrouver dans le répertoire
racine de Make.&lt;/li&gt;
&lt;li&gt;Il est plus agréable de les regrouper dans un répertoire dédié.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;On utilise toujours la variable &lt;strong&gt;VPATH&lt;/strong&gt; pour indiquer les
répertoires.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Préparation des variables:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;path_obj&lt;/em&gt; est le répertoire où les obj seront placés&lt;/li&gt;
&lt;li&gt;&lt;em&gt;objets_avec_chemin&lt;/em&gt; sera utilisé par le linker (ce sont les objets
préfixés par leur chemin complet)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
OBJS=morph_dots.o cglfw.o memory.o
path_obj=./objets
objets_avec_chemin=$(patsubst %,$(path_obj)/%,$(OBJS))
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez insérer cette rêgle dans votre makefile, pour créer le
répertoire des objets si il n'existe pas.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;__dummy := $(shell mkdir -p $(path_obj))&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour compiler et linker:
&lt;ul&gt;
&lt;li&gt;Notez que pour linker, on peut utiliser la variable automatique
&lt;em&gt;&lt;strong&gt;$&amp;lt;&lt;/strong&gt;&lt;/em&gt; , car les fichiers objets sont préfixés par
leur répertoire dans la définition de la cible.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
$(exe): $(objets_avec_chemin)
        $(CC) $^ $(libs) -o $(exe)

$(path_obj)/%.o: %.cpp
        $(CC) $(CXXFLAGS) -c $&amp;lt; -o $@
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pour générer les dépendances, on utilisera toujours la même méthode.
&lt;ul&gt;
&lt;li&gt;Il faut juste insérer le répertoire de destination des objets. Il faut le
faire à la main avec &lt;strong&gt;sed&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
deps:
        @rm -f mes_deps
        @$(CC) -I$(VPATH) -MM *.c* $(VPATH)/*.c* &amp;gt;&amp;gt;mes_deps

#rajoute $(path_obj) sur les lignes qui ne commencent pas par \t ou space
        @sed 's:^\([^\t\ ]\):$(path_obj)/\1:g' &amp;lt; mes_deps &amp;gt;mes_deps.tmp
        @mv mes_deps.tmp mes_deps
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Quelques fonctions.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La fonction &lt;em&gt;wildcard&lt;/em&gt; permet de récupérer les noms de fichiers
satisfaisants à une rêgle.
&lt;ul&gt;
&lt;li&gt;ex: SOURCES=$(wildcard *.c)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La fonction &lt;em&gt;basename&lt;/em&gt; récupère la racine d'un nom de fichier.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$(basename toto.c)&lt;/code&gt; : renvoie &lt;em&gt;toto&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Vous voulez compiler tous les fichiers d'un répertoire, mais vous ne savez
pas à l'avance leur nom.
&lt;ul&gt;
&lt;li&gt;Ici, j'utilise un fichier texte qui va être transformé en fichier html
après un petit traitement.&lt;/li&gt;
&lt;li&gt;&lt;q&gt;SOURCES&lt;/q&gt; utilise un &lt;em&gt;wildcard&lt;/em&gt; pour ramener tous les fichiers
avec l'extension &lt;em&gt;txt&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;q&gt;DESTS&lt;/q&gt; est le résultat d'une substitution de chaine sur la variable
&lt;q&gt;SOURCES&lt;/q&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
SOURCES=$(wildcard *.txt)
DESTS=$(SOURCES:.txt=.html)

all: $(DESTS)
        @echo Terminé

%.html: %.txt
        @crock $&amp;lt; &amp;gt;$@
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Salut Make&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;make clean&lt;/li&gt;
&lt;li&gt;make all&lt;/li&gt;
&lt;li&gt;make install&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2008/10/02/Make-Mayday#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2008/10/02/Make-Mayday#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/282763</wfw:commentRss>
      </item>
    
  <item>
    <title>JH rech. un bug mortel.</title>
    <link>http://www.finiderire.com/post/2007/09/23/JH-rech-un-bug-mortel</link>
    <guid isPermaLink="false">urn:md5:5c6903dea729e9a85bc3108bbb8e38de</guid>
    <pubDate>Mon, 29 Sep 2008 21:35:00 +0200</pubDate>
    <dc:creator>Jean-Seb</dc:creator>
        <category>Coding</category>
        <category>C</category><category>coding</category><category>debugging</category><category>tools</category>    
    <description>&lt;p&gt;&lt;em&gt;Vous recherchez un bug ?&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Faites confiance à GDB, spécialiste de la mise en relation.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;GDB&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;C'est le debugger GNU.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Il n'y a pas vraiment de concurrence, à part peut être IDA-Pro (mais c'est
payant).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;GDB est rebutant au premier abord, ne vous découragez pas. Il devient
rapidement très agréable à utiliser.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Si votre principal reproche est l'absence d'interface, vous pouvez
commencer par lire le paragraphe: &lt;q&gt;un secret bien gardé: le mode
TUI&lt;/q&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Ici, je ne vais qu'effleurer le sujet, mais je mettrai à jour au fur et à
mesure de mes expérimentations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Trouver l'aide&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;help&lt;/strong&gt; ou &lt;strong&gt;help&lt;/strong&gt; &lt;em&gt;domaine&lt;/em&gt; :
donne les commandes de &lt;em&gt;domaine&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;apropos&lt;/strong&gt; &lt;em&gt;domaine&lt;/em&gt; : donne toutes les commandes
&lt;strong&gt;liées&lt;/strong&gt; à &lt;em&gt;domaine&lt;/em&gt; (y compris les alias).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;info&lt;/strong&gt; &lt;em&gt;domaine&lt;/em&gt; : tout le paramétrage d'un
domaine. Exemple:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;info breakpoints&lt;/strong&gt; : liste des breakpoints.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;info display&lt;/strong&gt; : liste des variables en display (voir
plus bas).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;info function&lt;/strong&gt; : prototypage des fonctions +
symboles.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;help&lt;/strong&gt; &lt;em&gt;commande&lt;/em&gt; : la documentation complète
d'une commande appartenant à un domaine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Fichier de configuration&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Il n'y a pas de configuration à proprement parler.&lt;/li&gt;
&lt;li&gt;Au démarrage, GDB recherche un fichier &lt;em&gt;.gdbinit&lt;/em&gt; dans le home, puis
dans le répertoire courant.&lt;/li&gt;
&lt;li&gt;Si le fichier existe dans les deux répertoires, il sera évalué à chaque
fois.&lt;/li&gt;
&lt;li&gt;Ce fichier va contenir des commandes GDB.
&lt;ul&gt;
&lt;li&gt;Vous pouvez vous en servir pour personnaliser votre GDB (type de base
désirée, messages à afficher, etc..)&lt;/li&gt;
&lt;li&gt;Vous pouvez aussi l'utiliser pour démarrer plus rapidement une session de
debuggage.&lt;/li&gt;
&lt;li&gt;Le fichier suivant change le prompt de GDB, charge le fichier
&lt;em&gt;a.out&lt;/em&gt; (compilé avec les symboles de debug), pose un point d'arrêt sur
&lt;em&gt;main&lt;/em&gt;, lance l'exécution et liste le programme à l'endroit où GDB a
stoppé.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
~/temp$ cat .gdbinit 
set prompt debug-test.elf &amp;gt; 
file a.out
break main
run test.c
list
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La base&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Compiler avec les symboles de debug: &lt;code&gt;gcc -ggdb foo.c&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;On peut également compiler avec le plus classique &lt;q&gt;-g&lt;/q&gt;, mais
&lt;strong&gt;-ggdb&lt;/strong&gt; est spécifique à GDB.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Lancer gdb: &lt;code&gt;gdb votre_programme&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Lancer le programme depuis gdb: &lt;code&gt;run &amp;quot;argument 1&amp;quot; ... &amp;quot;argument
n&amp;quot;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;on peut également jouer sur les arguments avec &lt;em&gt;show / set args &lt;q&gt;liste
arguments&lt;/q&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kill&lt;/strong&gt; pour stopper GDB ou &lt;em&gt;ctrl+c&lt;/em&gt; si vous êtes pris
dans une boucle.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;continue&lt;/strong&gt; pour continuer le programme à partir de la
position courante, jusqu'à le terminer ou à atteindre le prochain
breakpoint.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;quit&lt;/strong&gt; pour sortir de GDB.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Exécuter le programme en mode &lt;em&gt;run&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;step&lt;/strong&gt; : passe à l'instruction suivante, rentre dans
les appels de fonctions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;next&lt;/strong&gt; : passe à l'instruction suivante, et exécute les
fonctions d'un bloc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;nexti&lt;/strong&gt; et &lt;strong&gt;stepi&lt;/strong&gt; : même chose que
précédemment, mais au niveau désassemblage.&lt;/li&gt;
&lt;li&gt;On peut également ajouter un nombre d'occurrences pour &lt;em&gt;next&lt;/em&gt; et
&lt;em&gt;step&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;step 10&lt;/strong&gt; : va exécuter 10 fois step, éventuellement en
partant dans un sous-programme.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;next 10&lt;/strong&gt; : avance 10 fois, les sous-programmes
comptent pour une avancée.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;continue&lt;/strong&gt; éventuellement suivi d'un nombre, qui
correspondra au nombre de fois où GDB ignorera le breakpoint d'où nous sommes
reparti.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;call fonction()&lt;/strong&gt; : appeler directement un
sous-programme (exemple: pour nettoyer et sortir).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;finish&lt;/strong&gt; : appelle &lt;q&gt;step&lt;/q&gt; de façon continue,
jusqu'à la fin de la fonction, et retour à l'appelant (affiche la valeur de
retour).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;list&lt;/strong&gt; : lister le programme.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;list &lt;em&gt;début,fin&lt;/em&gt;&lt;/strong&gt; : lister de la ligne
&lt;em&gt;début&lt;/em&gt; à la ligne &lt;em&gt;fin&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;list ,n&lt;/strong&gt; : lister &lt;em&gt;n&lt;/em&gt; lignes à partir de
l'instruction courante.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;list fonction&lt;/strong&gt; : lister une fonction.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;file &lt;em&gt;foo.exe&lt;/em&gt;&lt;/strong&gt; : pour charger
&lt;em&gt;foo.exe&lt;/em&gt;. Si ce n'est pas le premier chargement, il est rechargé. Dans
ce dernier cas, le source sera également rechargé.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Manipuler les variables
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;print &lt;em&gt;var&lt;/em&gt;&lt;/strong&gt; : examiner une variable (le
&lt;q&gt;$&lt;/q&gt; suivi d'un nombre est juste un compteur de référence).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;display &lt;em&gt;var&lt;/em&gt;&lt;/strong&gt; : même comportement que
&lt;em&gt;print&lt;/em&gt;, mais affiche la variable à chaque retour au prompt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;undisplay &lt;em&gt;var&lt;/em&gt;&lt;/strong&gt; : annuler l'affichage
automatique de &lt;em&gt;var&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;set var = x&lt;/strong&gt; : modifier une variable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;whatis &lt;em&gt;var&lt;/em&gt;&lt;/strong&gt; : obtenir le type d'une
variable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ptype &lt;em&gt;struc&lt;/em&gt;&lt;/strong&gt; : détail d'une structure&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;show values&lt;/strong&gt; : réafficher les 10 dernières valeurs
affichées&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Les dumps&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Si on demande un print du pointeur &lt;em&gt;char *buffer&lt;/em&gt;, on obtient une
sortie peu agréable.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;print &lt;em&gt;buffer&lt;/em&gt;&lt;/strong&gt; affichera l'adresse du buffe et un
dump sour forme de char.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;print *buffer&lt;/strong&gt; : pour afficher le premier caractère du
buffer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour dumper une zone mémoire, il vaut mieux utiliser la commande
&lt;strong&gt;x&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La commande &lt;strong&gt;x&lt;/strong&gt; : &lt;code&gt;x/(itérations)(format et
taille) (adresse)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;itérations&lt;/em&gt; : facultatif, 1 par défaut.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Format&lt;/em&gt; = o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char), s(string).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Taille&lt;/em&gt; = b(byte), h(halfword), w(word), g(giant, 8 bytes).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Exemple (le mieux étant de faire quelques essais vous-même)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
debug-test.elf &amp;gt; x/c buffer
0x602250:       35 '#'

debug-test.elf &amp;gt; x/8c buffer
0x602250:       35 '#'  105 'i' 110 'n' 99 'c'  108 'l' 117 'u' 100 'd' 101 'e'

debug-test.elf &amp;gt; x/2s buffer
0x602250:        &amp;quot;#include &amp;lt;stdio.h&amp;gt;\n#include &amp;lt;stdlib.h&amp;gt;\n\nchar *buffer=0;\n\nint lecture(const char *file)\n{\n  FILE *fp=0;\n  int fsize=0;\n#define TAILLE_MAX 1024*1024\n\n  fp=fopen(file,\&amp;quot;rb\&amp;quot;);\n  if (fp) {\n    fseek(fp,0,SE&amp;quot;...
0x602318:        &amp;quot;EK_END);\n    fsize=ftell(fp);\n    fseek(fp,0,SEEK_SET);\n\n    if (fsize&amp;gt;TAILLE_MAX) {\n      printf(\&amp;quot;Taille fichier trop important: %d octets.\\n\\\n&amp;quot;, ' ' &amp;lt;repeats 14 times&amp;gt;, &amp;quot;Taille maximum autorisée: %d octets.\\n\&amp;quot;,\n&amp;quot;...

debug-test.elf &amp;gt; x/2xw buffer
0x602250:       0x636e6923      0x6564756c

debug-test.elf &amp;gt; x/2xg buffer
0x602250:       0x6564756c636e6923      0x2e6f696474733c20
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Les points d'arrêts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;help breakpoints&lt;/strong&gt; : tout ce qu'il faut savoir sur les
points d'arrêt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;break &lt;em&gt;nom fonction / num ligne&lt;/em&gt;&lt;/strong&gt; : poser un
breakpoint sur l'entrée d'une fonction, ou sur un numéro de ligne (ligne en
cours, si pas de paramètre spécifié)
&lt;ul&gt;
&lt;li&gt;on peut ajouter le nom du fichier où se trouve le code à interrompre :
&lt;code&gt;break nom_fichier:nom_fonction&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;delete &lt;em&gt;n&lt;/em&gt;&lt;/strong&gt; : efface le breakpoint numéro
&lt;q&gt;n&lt;/q&gt; . Si &lt;q&gt;n&lt;/q&gt; est omis, tous les breakpoints sont effacés.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;clear &lt;em&gt;fonction/numero de ligne/adresse
mémoire&lt;/em&gt;&lt;/strong&gt; : efface le breakpoint en donnant sa ligne, le nom
d'une fonction ou une adresse mémoire (précédée par &lt;strong&gt;*0x&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;info breakpoints&lt;/strong&gt; : donne la liste des
breakpoints.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tbreak&lt;/strong&gt; : même fonction que &lt;em&gt;break&lt;/em&gt;, mais le
breakpoint est temporaire.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;break &lt;em&gt;line&lt;/em&gt; if &lt;em&gt;cond&lt;/em&gt;&lt;/strong&gt; : arrêt à la
ligne &lt;em&gt;line&lt;/em&gt; si la condition &lt;em&gt;cond&lt;/em&gt; est remplie. Conditions
multiples (avec des booléens) admises.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;break pixel_test if x==1 &amp;amp;&amp;amp; y==1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;On remarquera que les comparaisons se font avec la double égalité
&lt;strong&gt;==&lt;/strong&gt; (comme en C).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Parcourons la pile d'appel&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La pile d'appel, ou &lt;strong&gt;call stack&lt;/strong&gt;, sert à stocker les
&lt;strong&gt;stacks frames&lt;/strong&gt; (ou &lt;em&gt;cadres de piles&lt;/em&gt;, traduction
médiocre de l'espace utilisé pour sauver le contexte lors de l'appel d'une
fonction).&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Une &lt;strong&gt;stack frame&lt;/strong&gt; contient les registres sauvés lors de
l'appel d'une fonction, les arguments passés à la fonction ainsi que les
variables locales.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;where&lt;/strong&gt; (ou &lt;strong&gt;backtrace&lt;/strong&gt; , au choix) :
sort le contenu de la call stack.
&lt;ul&gt;
&lt;li&gt;Attention au sens de lecture: la frame la plus récente se trouve à la
position zéro.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;info frame&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;info locals&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;up&lt;/strong&gt; , &lt;strong&gt;down&lt;/strong&gt; (éventuellement suivi du nombre
de positions) : se déplacer dans la pile des appels.
&lt;ul&gt;
&lt;li&gt;permet d'afficher les variables locales d'un contexte.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Gestion de l'historique des commandes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pour ne pas tout retaper à chaque session debug identique.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Sauvegarde de l'historique de commandes
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;set history filename &lt;em&gt;fname&lt;/em&gt;&lt;/strong&gt; : choisir le nom
du fichier historique (par défaut: &lt;em&gt;./.gdb_history&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;set history save on/off&lt;/strong&gt; : activer/désactiver la
sauvegarde de l'historique (par défaut, on ne sauve rien).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;set history size &lt;em&gt;taille&lt;/em&gt;&lt;/strong&gt; : taille de
l'historique (par défaut : 256 commandes)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;show history&lt;/strong&gt; : état des paramètres ci-dessus.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Charger et exécuter un fichier de commandes
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;source &lt;em&gt;commandes&lt;/em&gt;&lt;/strong&gt; : &lt;em&gt;commandes&lt;/em&gt;
contient des commandes GDB&lt;/li&gt;
&lt;li&gt;avec l'option &lt;strong&gt;-v&lt;/strong&gt; , on active le mode verbose :
&lt;code&gt;source -v commandes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;pas de demande de confirmation pour les commandes qui en demandent
habituellement une.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;readline en quelques mots&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GDB utilise la bibliothèque &lt;em&gt;readline&lt;/em&gt; pour la gestion du
clavier.&lt;/li&gt;
&lt;li&gt;Plutôt que de tout détailler, je vous renvoie à la doc de GDB.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Voici le minimum vital:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;alt+f&lt;/strong&gt; , &lt;strong&gt;alt+b&lt;/strong&gt; : curseur en
avant/arrière d'un mot.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ctrl+f&lt;/strong&gt; , &lt;strong&gt;ctrl+b&lt;/strong&gt; : curseur en
avant/arrière d'un caractère.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ctrl+w&lt;/strong&gt; : effacer un mot avant le curseur.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;alt+d&lt;/strong&gt; : effacer un mot après le curseur.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ctrl+k&lt;/strong&gt; : effacer du curseur jusqu'à la fin de la
ligne.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ctrl+y&lt;/strong&gt; : &lt;q&gt;yank&lt;/q&gt; (coller) d'un mot ou d'une
séquence de mots précédemment effacé(s).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tab&lt;/strong&gt; : complétion automatique.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ctrl+p&lt;/strong&gt; , &lt;strong&gt;ctrl+n&lt;/strong&gt; : historique
arrière/avant des commandes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ctrl+r&lt;/strong&gt; , &lt;strong&gt;ctrl+s&lt;/strong&gt; : chercher en
arrière/avant dans l'historique des commandes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La liste est longue, mais passer un peu de temps sur readline en vaut la
peine, car le shell utilise également cette bibliotheque.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Un secret bien gardé: le mode TUI&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Un certain nombre de projets destinés à donner une interface à GDB
existent.
&lt;ul&gt;
&lt;li&gt;Citons en vrac DDD, divers front-ends ncurses revampant la sortie de GDB,
le mode natif pour Emacs etc.&lt;/li&gt;
&lt;li&gt;En réalité, même si certains de ces développements apportent un plus à GDB
(notamment DDD avec ses graphes d'appels), la majorité des personnes les
utilisant ne s'intéressent qu'au côté GUI.&lt;/li&gt;
&lt;li&gt;Réjouissez-vous, GDB possède un GUI intégré. Seul pré-requis: le compiler
avec le support &lt;em&gt;ncurses&lt;/em&gt;. Pour le build msys, vous pouvez oublier, par
contre, il est linké par défaut avec &lt;em&gt;ncurses&lt;/em&gt; dans Cygwin.&lt;/li&gt;
&lt;li&gt;Ce mode s'appelle le mode TUI (Text User Interface). Il permet d'afficher
plusieurs fenêtres sur le même écran.&lt;/li&gt;
&lt;li&gt;Les fenêtres affichables sont: commandes, source, désassemblage, registres
(avec possibilité de choisir la famille de registres)&lt;/li&gt;
&lt;li&gt;On ne peut pas afficher plus de 3 fenêtres, sachant que la fenêtre
&amp;quot;commandes&amp;quot; est toujours présente.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Pour activer/désactiver le mode TUI:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ctrl-x&lt;/strong&gt; puis &lt;strong&gt;a&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;ou encore (équivalent): &lt;strong&gt;ctrl-xa&lt;/strong&gt; (x, puis a sans relacher
ctrl)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Affichage des différentes fenêtres:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ctrl-x 1&lt;/strong&gt; , &lt;strong&gt;ctrl-x 2&lt;/strong&gt; : afficher une
ou deux fenêtres (en plus de la fenêtre &lt;em&gt;commandes&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ctrl-x o&lt;/strong&gt; : pour cycler entre les fenêtres.&lt;/li&gt;
&lt;li&gt;help layout&lt;/li&gt;
&lt;li&gt;&lt;em&gt;layout next / prev&lt;/em&gt; pour passer entre les différentes
configurations d'affichage.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Personnalisation de la fenêtre registres
&lt;ul&gt;
&lt;li&gt;On peut choisir la famille de registres que l'on souhaite afficher :
&lt;code&gt;help tui reg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Paramètres possibles à &lt;q&gt;tui reg&lt;/q&gt; : float, general, system,
next&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Focus sur une fenêtre:
&lt;ul&gt;
&lt;li&gt;focus src / asm / regs / cmd&lt;/li&gt;
&lt;li&gt;note: si on n'a pas le focus sur la fenêtre &lt;em&gt;commandes&lt;/em&gt;, on peut
toujours rappeller les commandes avec &lt;em&gt;ctrl+p&lt;/em&gt; et &lt;em&gt;ctrl+n&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Changer la taille d'une fenêtre: winheight &lt;em&gt;nom&lt;/em&gt; +-&lt;em&gt;nbr
lignes&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Mise à jour:
&lt;ul&gt;
&lt;li&gt;de l'écran: &lt;strong&gt;ctrl+l&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;de la fenêtre source: &lt;code&gt;update&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Cosmétique:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;help set tui border-mode / active-border-mode /
border-kind&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;On peut également voir les paramètres avec &lt;q&gt;show&lt;/q&gt; à la place de
&lt;q&gt;set&lt;/q&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Mode &lt;q&gt;single&lt;/q&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ctrl-x s&lt;/strong&gt; pour entrer dans le mode &lt;em&gt;single&lt;/em&gt;. Toutes
les commandes nécessitent désormais l'appui d'une seule touche.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;c&lt;/strong&gt; : continue , &lt;strong&gt;d&lt;/strong&gt; : frame down ,
&lt;strong&gt;u&lt;/strong&gt; : frame up , &lt;strong&gt;f&lt;/strong&gt; : finish
,&lt;strong&gt;s&lt;/strong&gt; : step , &lt;strong&gt;n&lt;/strong&gt; : next ,
&lt;strong&gt;r&lt;/strong&gt; : run , &lt;strong&gt;v&lt;/strong&gt; : affiche les locales,
&lt;strong&gt;w&lt;/strong&gt; : where&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;q&lt;/strong&gt; : quitter le mode &lt;em&gt;single&lt;/em&gt;. (&lt;strong&gt;ctrl-x
s&lt;/strong&gt; à nouveau fonctionne également)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Bien entendu, les raccourcis claviers de &lt;em&gt;readline&lt;/em&gt; s'appliquent
toujours, &lt;ins&gt;sauf&lt;/ins&gt; en mode &lt;em&gt;single&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Sortie d'un programme sur un tty différent&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Les sorties textes qui se mélangent aux données GDB ne sont pas pratiques.
Il faut donc les rediriger vers un autre terminal.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;La commande &lt;strong&gt;tty &lt;em&gt;dev&lt;/em&gt;&lt;/strong&gt; positionne le stdin &amp;amp;
stdout pour la prochaine exécution.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Sous un Unix, pas de problème, il sufit de lancer la commande &lt;em&gt;tty&lt;/em&gt;
sous GDB, en indiquant le tty désiré (/dev/tty1 par exemple)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Sous Cygwin, avant de pouvoir utiliser cette commande, il faut ajouter à la
variable locale &lt;strong&gt;CYGWIN&lt;/strong&gt; le paramètre &lt;strong&gt;tty&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Cette opération est à faire &lt;strong&gt;avant&lt;/strong&gt; de lancer le shell
Cygwin.&lt;/li&gt;
&lt;li&gt;Le mieux est de copier &lt;em&gt;cygwin.bat&lt;/em&gt; et d'ajouter dedans: &lt;code&gt;set
CYGWIN=tty&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Je vous conseille de copier le cygwin, car dans certains cas, il peut être
préférable de ne pas utiliser le support &lt;em&gt;termio&lt;/em&gt; de Cygwin.&lt;/li&gt;
&lt;li&gt;Notamment, il semble qu'il ne faille pas l'utiliser avec xterm ou
rxvt.&lt;/li&gt;
&lt;li&gt;On peut très bien utiliser &lt;em&gt;screen&lt;/em&gt; en mode tty : les sessions
créées dans screen ont un tty tout à fait valide.&lt;/li&gt;
&lt;li&gt;Si tout s'est bien passé, une fois le shell lancé, vous pouvez tester:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
~$ tty
/dev/tty0
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Je ne savais pas où coller ça&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;-mno-cygwin&lt;/strong&gt; : argument du gcc Cygwin pour ne pas
compiler avec les dépendances Cygwin.
&lt;ul&gt;
&lt;li&gt;C'est dans la faq de Cygwin, mais ma bonté me perdra.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;N'hésitez pas à abuser des abréviations
&lt;ul&gt;
&lt;li&gt;par exemple: &lt;strong&gt;info breakpoints&lt;/strong&gt; s'abrège en &lt;strong&gt;i
b&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;en général, une seule lettre suffit pour les commandes les plus
courantes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Choisir/afficher la base utilisée pour les entrées/sorties.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;set/show input-radix&lt;/strong&gt; : pour les entrées, à faire
suivre de la base désirée (8, 10 ou 16)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;set/show output-radix&lt;/strong&gt; : idem que ci-dessus, pour les
sorties de GDB.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;set/show radix&lt;/strong&gt; : idem que ci-dessus, pour les
entrées/sorties de GDB.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Coredump et puis s'en va&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;C'est un billet qui a demandé pas mal de synthèse. Je pense avoir fait le
tour du plus important. N'hésitez pas à compléter en commentaire si je suis
passé à côté de quelque chose.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;GDB possède bien plus de possibilités que ce qui a été évoqué ici. Le mieux
est de lire la doc GNU officielle, très claire et agréable. Près de 450 pages
tout de même, et pas de blabla inutile.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://www.finiderire.com/post/2007/09/23/JH-rech-un-bug-mortel#comment-form</comments>
      <wfw:comment>http://www.finiderire.com/post/2007/09/23/JH-rech-un-bug-mortel#comment-form</wfw:comment>
      <wfw:commentRss>http://www.finiderire.com/feed/atom/comments/157789</wfw:commentRss>
      </item>
    
</channel>
</rss>