Cross-compilation de Boost pour Windows sous Linux

À propos de l\’auteur : Fabien Danieau est doctorant à Rennes, entre l\’INRIA et Technicolor. Titulaire d\’un diplôme d\’Ingénieur en Cognitique, ses travaux portent actuellement sur l\’application des interfaces haptiques pour le multimédia.

 

Récemment j\’ai eu besoin de cross-compiler la librairie Boost nécessaire à un projet. Ce ne fût pas chose évidente, j\’ai pensé qu\’un retour d\’expérience pourrait être utile à plus d\’un.
Dans notre cas nous allons voir comment compiler Boost 1.47 pour Windows 32 bits sous une machine Linux ( la procédure décrite a été testée sous Debian Squeeze 64bits et Fedora 14 64bits).

Pré-requis

La librairie Boost se récupère aisément sur le site officiel. Pour la compilation j\’ai utilisé mingw-w32-bin_x86_64-linux_20110818. Le nom indique qu\’il va compiler des projets pour Windows 32bits (w32) et cette compilation se fera sous une machine linux 64 bits (x86_64-linux). On trouve ce compilateur sur le site officiel de mingw.
Pour la suite du tuto nous considéreront que les deux archives récupérées sont décompressées dans un dossier \ »BoostBuild\ » situé à la racine de notre home. Nous obtenons donc l\’architecture suivante.

BoostBuild
-- boost_1_47
-- mingw-w32-bin_x86_64-linux_20110818

Plaçons nous dans le répetoire boost_1_47 et attaquons les choses sérieuses!

cd ~
cd BoostBuild/boost_1_47

Procédure

Premièrement il faut créer un petit fichier de configuration pour indiquer à boost d\’utiliser mingw comme compilateur.

echo \"using gcc : mingw64 : i686-w64-mingw32-g++ : 4.6;\" > user-config.jam

Ceci ne suffisant pas pour que l\’emplacement du compilateur soit trouvé, nous allons modifier temporairement la variable PATH. Le compilateur (i686-w64-mingw32-g++) se trouve dans le dossier mingw-w32-bin_x86_64-linux_20110818/bin.

PATH=/home/fabien/BoostBuild/mingw-w32-bin_x86_64-linux_20110818/bin:$PATH

Cette commande fonctionnera chez les utilisateurs de Debian et autres dérivés. Les possesseurs d\’une Fedora utiliseront plutôt celle-ci.

setenv PATH /home/fabien/BoostBuild/mingw-w32-bin_x86_64-linux_20110818/bin:$PATH

Ensuite, comme indiqué dans la documentation de Boost, il faut appeler le script bootstrap.sh.

sh bootstrap.sh

Dans mon cas le script n\’a pas abouti pour cause de \ »Permission Denied\ ». En effet celui-ci essaie d\’en appeler une autre, build.sh, qui n\’est pas exécutable. D\’où l\’échec… Pour remédier à cela il suffit de faire:

chmod +x tools/build/v2/engine/build.sh

Enfin nous arrivons à la dernière étape, la fameuse compilation de boost. Il faut lancer la commande «./b2» comme nous l\’indique le script bootstrap.sh une fois sa tâche terminée. Cependant nous devons lui passer quelques paramètres spécifique à notre cross-compilation.

./b2 --user-config=user-config.jam --layout=versioned --toolset=gcc-mingw64 define=BOOST_USE_WINDOWS_H address-model=32 variant=debug,release link=static,shared threadapi=win32 target-os=windows stage

\ »user-config\ » et \ »toolset\ » indiquent le compilateur à utiliser. \ »define\ », \ »address-model\ » et \ »target-os\ » spécifient que l\’os cible est windows 32 bits. \ »variant\ » et \ »link\ » déterminent que l\’on veut compiler ici les librairies dynamiques, statiques en version release et debug. Ces arguments sont à modifier suivant vos besoins. L\’argument \ »layout\ » impose ici d\’indiquer ces informations de version dans le nom des fichiers produits.
La compilation est en route, vous devriez voir les librairies apparaître dans le dossier boots_1_47/stage/lib. Cette étape peut prendre un peu de temps suivant les performances de votre machine. Pour une compilation plus rapide n\’hésitez pas à utiliser l\’argument supplémentaire \ »-j n\ » avec n le nombre de processeurs que vous possèdez.

Compilation pour Win64

Si cette article est dédiée à la compilation de la librairie Boost pour windows 32 bits, il est facile de l\’adapter à windows 64 bits. Il vous faudra alors télécharger mingw64-w64 et modifier un peu les arguments de la dernière commande (address-model=64 entre autres). Je n\’ai pas testé mais cela devrait fonctionner.

Anciennes versions de Boost

Si vous voulez compiler une ancienne version de boost (boost_1_46_1 par exemple) il ne faudra pas appeler \ »./b2\ » lors de la dernière étape mais \ »./bjam\ ». L\’ensemble des arguments restent les mêmes.

Références

Quelques références utiles.

 

Trier et supprimer les doublons d\’un fichier sous Linux

\"Terminal\"Dans le cadre du débuggage d\’un programme C, j\’ai été amené à écrire dans un fichier plus de 5 millions de valeurs numériques dans le but de les trier ensuite et de supprimer les doublons (\ »Ah le mec qui debug avec des printf()!\ » – Ouai ben des fois y\’a que ça d\’efficace!) . Une fois ce fichier généré, soit environ 40Mo, je me suis posé la question de l\’outil à utiliser pour effectuer les opérations dont j\’avais besoin. J\’ai pensé à plusieurs choses :

  • Ouvrir le fichier avec LibreOffice Calc mais il se trouve que celui-ci est limité à un peu plus de 100 000 lignes et ne permet donc pas d\’exploiter mon fichier.
  • Insérer en base de données les valeurs et effectuer les opérations en SQL. Problème : Il faut une base de données à disposition d\’une part et si c\’est le cas, MySQL via PhpMyAdmin refuse d\’importer le fichier car il est, semble-t-il, trop volumineux.
  • Écrire un programme qui lit le fichier, stocke toutes la valeurs dans un tableau et effectue les opérations nécessaires. Seulement voilà, on n\’a pas forcément l\’envie ni le temps d\’écrire un programme pour un traitement aussi commun.

Bref, c\’est là qu\’intervient Linux et la puissance des outils qui lui sont associés. Dans un terminal :

$ sort -g mon_fichier | uniq > mon_nouveau_fichier

C\’est aussi simple que ça! Et le temps d\’exécution est très raisonnable :

$ time sort -g mon_fichier | uniq > mon_nouveau_fichier 

real	0m8.013s
user	1m0.326s
sys	0m0.403s

Quelques brèves explications :

  • sort -g permet le tri en prenant l\’ordre des valeurs numériques et pas l\’ordre alphanumérique classique. Sans cette option, on aurait un résultat de ce type : 1, 10, 100, 1000, 11, 110, 1110, …
  • uniq permet de supprimer les doublons et de renvoyer les valeurs uniques.

Certes ce n\’est pas quelque chose dont on a besoin tous les jours mais ça permet de montrer encore une fois la diversité et la puissance des outils fournis sous Linux. Et ça encourage à chercher du côté de ces petits utilitaires avant de tenter des choses improbables ou de réinventer la roue…

Manuel de sort
Manuel de uniq

EDIT : Il est aussi possible d\’effectuer le tout (tri + suppression des doublons) en ajoutant -u au sort. On aura donc sort -gu mon_fichier > mon_nouveau_fichier. Au niveau du temps d\’exécution il n\’y a aucune différence et le résultat est identique. Merci AP pour l\’info!

Mettre à jour la liste de boot de Grub 2

\"LinuxPour peu qu\’on ait un dual-boot géré par Grub 2, la liste des noyaux proposée au démarrage s\’allonge au fur et à mesure des nouvelles versions. Dans la version précédente de Grub, l\’édition du fichier /boot/grub/menu.lst permettait de personnaliser cette liste et en particulier de supprimer de l\’affichage les noyaux antérieurs pour ne garder par exemple que les deux derniers.

Grub 2, lui, génère automatiquement cette liste en fonction des versions du noyau présentes dans /boot. Du coup, pour s\’éviter une liste à rallonge au démarrage, la procédure est la suivante :

  1. Créez dans /boot un dossier old
    $ sudo mkdir /boot/old
    
  2. Déplacez les anciennes versions des noyaux pour ne garder que la dernière (celle fournie par uname -r), le memtest et éventuellement l\’avant-dernière version par sécurité. Dans la commande suivante, nous ne garderons que la dernière version du noyau et le memtest :
    $ sudo mv `find /boot -maxdepth 1 -type f ! -name *$( uname -r )* ! -name memtest*` /boot/old
    

    Petite explication : on déplace (mv) les fichiers trouvés (find) dans /boot en spécifiant :

    • -maxdepth 1 pour ne parcourir que /boot et pas les dossiers sous-jacents
    • -type f pour ne trouver que des fichiers (pas de dossier)

    On ajoute ensuite des ! -name qui permettent de tout sélectionner hormis le(s) fichier(s) déduit(s) du paramètre. On spécifie donc qu\’on exclu le memtest mais aussi tous les fichiers contenant dans leur nom la version courante du noyau (d\’où le *$( uname -r )*).

    Pour conserver par exemple la version 2.6.32-23 du noyau, il suffit de rajouter après le memtest* quelque chose comme ! -name *2.6.32-23*.

  3. Mettez à jour la configuration de Grub
    $ sudo update-grub
    

Un redémarrage devrait vous permettre d\’admirer le résultat! Il ne reste plus qu\’à mettre tout ceci dans un script et l\’exécuter quand nécessaire.

Rappel: Rediriger les entrées/sorties sous UNIX

Un article comme celui-là a déjà été écrit maintes et maintes fois mais une piqûre de rappel n\’est jamais de trop! Et ça me permettra de bien (re)intégrer ces notions de redirection d\’entrées/sorties.

Premier point : vu que sous un système UNIX tout est fichier, les entrées et sorties ne dérogent pas à cette règle. De même, chaque fichier possède un \ »descripteur de fichier\ » qui est un numéro unique permettant d\’identifier un fichier. Les fichiers d\’entrée/sortie ont un numéro fixe particulier permettant d\’y accéder facilement :

  • 0 : entrée standard
  • 1 : sortie standard
  • 2 : sortie d\’erreur

Ces numéros peuvent s\’avérer très utiles couplés aux caractères de redirection basiques. Ainsi, on peut facilement écrire dans un fichier les erreurs que provoque une commande ou encore en supprimer l\’affichage lors de l’exécution. Bref, il est possible de faire énormément de choses et le tableau suivant se veut en être un résumé (non exhaustif) :

[table id=1 /]

Quelques modestes exemples d\’utilisation (que je complèterai plus tard…) :

$ find -name test > ~/find_result
# recherche les fichiers nommés \"test\" depuis le repertoire courant récursivement
# dans tous les sous-répertoires et met le résultat dans le fichier find_result à la
# racine de son répertoire utilisateur
$ rgrep -n biscotte * 2> /dev/null
# recherche le mot \"biscotte\" depuis le répertoire courant récursivement dans
# tous les fichiers et supprime l\'affichage des erreurs (notamment les fameuses
# \"permission denied\" sur certains fichiers)

Planifier une execution avec at

\"Clock\"Lorsque l\’on souhaite planifier de façon régulière l\’exécution d\’une commande ou d\’un script, le plus efficace reste l\’utilisation de cron. En revanche, lorsqu\’il s\’agit d\’une action unique, il existe une commande linux très pratique : at. L\’utilisation de base pour une planification dans la journée est assez simple. Il suffit de faire suivre at de l\’heure à laquelle on souhaite exécuter la commande ou le script en concaténant les heures et les minutes. Après avoir pressé la touche <entrée> un prompt s\’ouvre pour y tapper la ou les commandes souhaitées chacune suivie d\'<entrée>. Après la dernière commande, un Ctrl+D validera la planification. Par exemple, pour lancer le script synchro.sh aujourd\’hui à 23h30 :

$ at 2330
warning: commands will be executed using /bin/sh
at> sh ~/synchro.sh
at> 
job 7 at Tue Jun 29 23:30:00 2010
$

Plusieurs options sont proposées pour personnaliser un peu plus l\’exécution. On peut citer en particulier le paramètre -l permettant de lister les planifications en cours :

$ at -l
7	Tue Jun 29 23:30:00 2010 a username
$

ou encore la commande atrm suivie de l\’id de la tâche pour la supprimer.

$ at -l
7	Tue Jun 29 23:30:00 2010 a username
$ atrm 7
$ at -l
$

Pour le manuel de la commande, c\’est par là.

sl ou comment s\’auto-flageller

Tous les utilisateurs de linux familiers avec la ligne de commande se sont retrouvés un jour avec cette faute de frappe :

user@server:~# sl
-bash: sl: command not found
user@server:~#

De façon à se punir de cette coquille, il existe une commande dont la description est plutôt claire :

sl – display animations aimed to correct users who accidentally enter sl instead of ls.

Cette commande fait passer un train en ASCII dans le terminal. Pour couronner le tout, on ne peut d\’une part pas tuer le processus (à moins de spécifier le paramètre -e mais là c\’est clairement plus une faute de frappe !!!) et d\’autre part les principaux paramètres à la commande ls, à savoir le -l et le -a, sont également implémentés dans sl. Le premier affichera un train plus petit et le second fera appeler au secours les passagers avec des \ »help!\ ».

\"Commande

Bref, c\’est inutile, énervant et relève du masochisme : autant dire indispensable! Donc pour l\’installer c\’est comme d\’habitude :

sudo apt-get install sl

Et le manuel est là : manuel sl.