Programmation
Wednesday, 26 January 2011
|
Écrit par
Grégory Soutadé

Dans mon article précédent je faisais une petite comparaison entre le SheevaPlug et un DELL OptiPlex quasi dernière génération. Voilà un petit retour d'expérience sur la compilation croisée depuis le Sheeva.

Pour rappel : la compilation croisée c'est compiler depuis un plateforme matérielle/logicielle A pour créer des binaires qui s'exécuteront sur une plateforme matérielle/logicielle B. Exemple : on compile sur une plateforme ARM pour une plateforme x86, ou encore une plateforme x86 64 bits vers x86 32 bits.

1) Récupérer crosstool-ng

Jusque là pas de problème, il s'installe facilement et est multi-plateforme (ce n'est que du script bash).

2) Compilation de la toolchain

La ça coince un peu plus, comme indiqué précédement j'ai eu des problèmes avec la eglibc, mais ça s'est résolu en modifiant une config d'exemple. J'ai compilé deux toolchains : une en 32 bits (i686-nptl-linux-gnu) et une en 64 bits (x86_64-nptl-linux-gnu).

3) Compilation du logiciel

Pour un simple "Hello World !" il n'y a pas de soucis, mais dès qu'on commence à construire un logiciel un peu plus costaud on a rapidement quelques ennuis.


Tout d'abord il faut préparer le Makefile à la cross compilation pour supporter la définition externe des variables type CXXFLAGS ou LDFLAGS. Cela consiste à remplacer CXXFLAGS="Quelque chose" par CXXFLAGS+="Quelque chose", idem pour LDFLAGS. Il faut aussi changer CXX=g++ en CXX=$(HOST)g++.

Les modifications pour KissCount sont dans ce commit.


Second problème : les bibliothèques externes type GTK ou dans mon cas wxWidgets. Là il faut ruser un peu plus, on ne peut pas installer directement le runtime car le paquet est compilé pour une architecture ARM donc ld ne va pas s'y retrouver. A moins de passer une option pour ignorer les différences d'architecture, mais je n'ai pas testé, et surtout je ne voulais pas installer ce paquet avec toutes ses dépendances (GTK, Xorg, ...) sur le serveur. J'ai donc importé à la fois les entêtes (headers) et les bibliothèques (.so) dans les dossiers include_wxwidgets_32 et lib_wxwidgets_32 (idem pour la version 64 bits) depuis une machine où ces paquets sont installés.


Dans le Makefile on fait appel à wx-config pour récupérer les valeurs de LDFLAGS et CXXFLAGS, j'ai donc crée un faux wx-config qui va renvoyer le chemin de include_wxwidgets_32 et lib_wxwidgets_32. Ensuite on définit HOST avec "i686-nptl-linux-gnu-" ou "x86_64-nptl-linux-gnu-", puis on déroute PATH vers ~/x-tools/i686-nptl-linux-gnu/bin:.:$PATH (le "." est l'endroit où il y a le wx-config). Enfin on lance LDFLAGS="-Wl,--allow-shlib-undefined" make. L'option "allow-shlib-undefined" permet de ne pas faire une résolution récursive des symbols dans les bibliothèques partagées, ainsi on n'a pas besoin de copier tout GTK pour pouvoir lier notre programme avec wxWidgets (qui dépend GTK).


La compilation se passe bien ... en 32 bits ! On peut même exécuter le programme sans problème sur une autre machine. Mais en 64 bits ça coince lors de l'édition de lien finale avec les erreurs suivante :

undefined reference to `__libc_csu_init'
undefined reference to `__libc_csu_fini'

Cela vient du fait que la libc 32 bits (de la plateforme de compilation) ne définit pas ces symbols et le compilateur (même 64 bits) utilise la libc de l'hôte. Personnellement j'ai fait deux liens symboliques :

ln -s /lib64     ~/x-tools/x86_64-nptl-linux-gnu/x86_64-nptl-linux-gnu/sys-root/lib/
ln -s /usr/lib64 ~/x-tools/x86_64-nptl-linux-gnu/x86_64-nptl-linux-gnu/sys-root/usr/lib/

On met à jour LDFLAGS dans le Makefile avec -L/lib64 et -L/usr/lib64 et le tour est joué !

4) Compilation automatique (Nightly build)

Pour courronner le tout, j'ai fait un petit script qui va s'exécuter chaque nuit (via crontab), vérifier depuis le dépôt git s'il n'y a pas une nouvelle version pour chaque branche et si c'est le cas, la compiler pour chaque architecture ! Il suffit alors de feinter inDefero en utilisant un liens symbolique "Nightly_Build_${branche}_${ARCH}.tar.bz2" pour rendre la nouvelle version disponible. De plus le script envoie un mail en cas d'echec ou de réussite (que demander de plus ??).

Ma hierarchie de dossier est la suivante :

/KissCount
|-- lib_wxwidgets_32/
|-- include_wxwidgets_32/
|-- lib_wxwidgets_64/
|-- include_wxwidgets_64/
|-- wx-config
|-- mega_compile.sh
|-- lib_i686/                  # Spécifique KissCount
|-- lib_x86_64/            # Spécifique KissCount
|-- kisscount_master/
|-- kisscount_dev/


Attention : lors du clone du dépôt git, il faut cloner un dépôt public, sinon il demande le mot de passe pour faire un pull.

Mon script de compilation mega_compile.sh

Et dans /etc/crontab :

0  2    * * *  www-data cd /KissCount && ./mega_compile.sh > /dev/null
Monday, 24 January 2011
|
Écrit par
Grégory Soutadé

En ayant marre de construire manuellement les tarballs binaires de KissCount, j'ai décidé de confier cette tâche à mon petit serveur (c'est le premier pas vers le packaging). Petit problème : le SheevaPlug tourne sur un processeur ARM, processeur encore peu répandu sur le "desktop" (ordinateur personnel/de bureau). En effet la majorité totalité de ces ordinateurs ont un processeur x86 (Intel/AMD). Mais pas de panique, il suffit de créer une chaîne de compilation croisée (cross toolchain) pour produire nos binaires x86 à partir d'une plateforme ARM !

Trêve bavardage, on récupère la dernière version de crosstool-ng (j'aurais pu en choisir un autre, mais celui là a l'air bien et surtout je n'avais pas envie de la construire "à la main"). Je me bats un peu en essayant d'utiliser la eglibc (Embedded Glibc, notamment utilisée par le projet Debian) ... échec. Par dépit je prends une configuration d'exemple légèrement modifiée. Une petite chose qui manque : la possibilité, par défaut, de faire un restart (obligé d'activer l'option dans debug).

Ce petit exercice va donc permettre de faire une comparaison entre les deux architectures. Bien sûr la comparaison est un peu biaisée car ce ne sont pas des gammes équivalentes, mais essayons quand même. La compilation est un exercice qui met en jeu beaucoup de composants systèmes :

  • Lecture/Écriture de fichiers (système de fichier, noyau via les caches, disque, DMA)
  • Mémoire/Calculs (processeur, bus interne, cache processeur, compilateur)


Les chiffres bruts :
Temps de compilation sur le SheevaPlug : 8h
Temps de compilation sur le DELL : 1h

 

 

Vu comme cela on se dirait : ARM, c'est naze. Mais regardons de plus près :

DELL OptiPlex 360

  • Intel(R) Core(TM)2 Duo E7500 @ 2.93GHz 3Mo de cache, FSB 1066Mhz : un seul des deux cœurs a été utilisé
  • 4 Go de mémoire vive bicanale type DDR2 SDRAM non ECC (800 MHz)
  • Disque dur 320 Go en SATA II avec un système de fichier Ext4, le tout à 7500rpm
  • Ubuntu 10.4 64 bits
  • Noyau Linux 2.6.32

SheevaPlug

  • ARM (9, v5 te) Marvell Kirkwood (Feroceon 88FR131 rev 1 (v5l)) 1Ghz, 16KB de cache L1, 256KB de cache L2 @500Mhz
  • 512 Mo DDR2 SDRAM 16 bits
  • Clé USB Toshiba 16Go en Ext2
  • Debian stable (4 / Lenny) 32 bits
  • Noyau Linux 2.6.32

 

Il y a un facteur 8 entre les deux systèmes qui peut s'expliquer par : le cache de l'ARM est ridicule (ça coûte cher), la fréquence du bus est deux fois moins importante, la taille du bus est divisée par 4, le système de fichier de la clé USB est relativement lent en écriture (4.7 Go nécessaires pour la compilation et 141 Mo la toolchain finale). En partant de là je trouve que les performances sont tout à fait correctes, surtout que même avec 8h de compilation on est gagnant niveau consommation électrique ! J'espère réellement que cette architecture va débarquer sur PC une fois qu'elle sera un peu plus musclé ! C'est ce qu'on verra avec les nouveaux Cortex A5/A8/A9 qui font déjà des merveilles sur smartphone (même s'il y a beaucoup d'accélérateurs autour). Et puis Microsoft a décidé de faire une version ARM de Windows, ce n'est pas pour rien ;)

 

Configuration toolchain 32 bits
Configuration toolchain 64 bits

Tuesday, 21 December 2010
|
Écrit par
Grégory Soutadé



Un peu de pub pour un petit outil dont on ne peut plus se passer une fois qu'on y a goûté. Quand on est développeur et qu'on utilise régulièrement la ligne de commande (projets, compilation, gestion de version ...) on se retrouve souvent dans les même dossiers (projetX, build, etc ...) et il n'est pas rare que ces chemins soient lointains les uns des autres. Joel Schaerer a donc humblement développé autojump. "humblement" car c'est un petit outil, mais qui remplit pleinement sa fonction (et en plus l'auteur est Français).

La version vanilla d'autojump mémorise sa position dans le système de fichiers à chaque commande, permettant ainsi de faire des statistiques sur les endroits où l'on se trouve le plus souvent, mais surtout de pouvoir sauter d'un endroit à un autre grâce à la commande "j" qui analyse son paramètre et essais de le faire correspondre à un chemin connu (les plus utilisés seront les premiers). Autojump supporte bien évidement l'auto-complétion par tabulation !

Exemple : Si le chemin "/home/soutade/Projets_Perso/KissCount" est enregistré dans autojump, il suffit d'entrer "j kiss" pour sauter directement à cet endroit, ce qui est un gain de temps considérable.

Autojump supporte plusieurs paramètres : "j greg kiss" saute sur "/home/greg/Projets_Perso/KissCount"

En cas de conflit on peut utiliser tab et choisir le chemin le plus approprié :

cd v2__[tab]
v2__1__/home/soutade/Projets/v2-helium-greg
v2__2__/home/soutade/Projets/v2-helium

La commande "jumpstat" permet d'avoir un aperçu de la base

...
54.5:  /home/shared/musique
60.0:  /home/joel/workspace/coolstuff/glandu
83.0:  /home/joel/workspace/abs_user/autojump
96.9:  /home/joel/workspace/autojump
141.8: /home/joel/workspace/vv
161.7: /home/joel
Total key weight: 1077


D'autres alternatives existent comme apparix, wcd ou kcd mais je les trouve moins élégantes (nécessite de scanner le système de fichier, utilisation moins transparente ...).

Le code d'autojump est disponible ici : https://github.com/joelthelion/autojump/wiki

Une démonstration (en) est disponible sur youtube : http://www.youtube.com/watch?v=tnNyoMGnbKg

Une fois installé, c'est adopté. Néanmoins en réfléchissant deux secondes je trouvais dommage qu'autojump soit appelé à chaque commande. En effet quand je suis dans un répertoire et que je fait cd .. je n'ai pas forcément envie que ce soit répertorié. J'ai donc retroussé mes manches et modifié le comportement du logiciel (https://github.com/soutade/autojump/tree/v2).

Sur ma version "cd" devient un alias d'autojump. Elle permet donc à la fois de sauter à un endroit et d'enregistrer un chemin dans la base de façon transparente. Si un dossier n'est pas trouvé dans la base ou qu'il est dans le répertoire courant, c'est la complétion normale de bash qui s'applique.

Il y a donc deux modes : manuel (il faut faire cd -a "chemin" pour enregistrer un chemin) ou automatique (chemin enregistré à chaque commande cd). Tout ceci est paramétrable dans le autojump.bash.

Par effet de bord on peut indifféremment manipuler la base avec la commande autojump ou cd.

En plus de cette modification j'ai aussi rajouté la commande "autojump/cd --remove key" qui permet de supprimer une entrée dans la base (la complétion pour key est effective), ainsi que la commande "cd/autojump --purge num" qui permet de supprimer toutes les entrées dont le nombre est inférieur ou égal à num.

En résumé, quelle que soit la version utilisée, il faut absolument essayer cet outil !

La version 2 d'Autojump est disponible

Thursday, 11 November 2010
|
Écrit par
Grégory Soutadé

La version 0.2 est sortie !

Après 6 mois d'intense développement, voici la version 0.1 de KissCount. Tout a commencé par une simple feuille de calcul pour noter les dépenses d'un budget modeste (donc qui nécessite de l'attention), puis sont apparues les couleurs pour différencier les opérations, les lignes de démarcation entre les semaines, les graphiques ... Au fur et à mesure, des fonctionnalités de plus en plus complexes se sont ajoutées. Ne voulant pas me lancer dans de la programmation sous OOo, le projet KissCount est né !

L'objectif est simple : arriver à retrouver la simplicité d'une feuille calcul tout en automatisant le plus possible les manipulations et les calculs. Il faut pouvoir visualiser en un seul écran : les opérations courantes, l'état des comptes et la répartition des dépenses (statistiques). L'objectif initial était même de faire tenir toutes ces informations dans un écran d'une résolution de 1024x768.

Bien sûr il existe des dizaines d'autres logiciels de comptabilité personnelle : libres, gratuits ou payants. Mais après une recherche rapide je me suis rendu compte qu'ils avaient tous les mêmes fonctionnalités et la même ergonomie, ce qui ne répond absolument pas à MON besoin : ouvrir le logiciel, rentrer les opérations, voir l'état des comptes, fermer le logiciel. En effet la plupart des autres logiciels de comptabilité partent sur une base financière et essaient de modéliser le maximum de détails, hors pour une utilisation "normale" on n'a besoin que de 20% des fonctionnalités proposées. De plus ils se transforment souvent en cliquodromes insupportables pour réaliser de simples opérations.

Par exemple : les champs "date de valeur", "date d'opération", "numéro de chèque", "destinataire", "devise", "type de l'opération" (chèque, espèces, carte bleue) sont inutiles. Ils prennent de la place à l'écran et ralentissent la saisie.
Dans KissCount on considère que :

  • la "date de valeur" est équivalente à la "date de l'opération" : Si un chèque n'est encaissé que 6 mois plus tard on le considère pendant 6 mois comme déjà encaissé (ça évite de le dépenser) mais on a la possibilité de ne pas le prendre en compte lors du rapprochement mensuel
  • "Numéro de chèque" et "destinataire" : Ils peuvent être inclus dans la description de l'opération, le montant du chèque suffit souvent à l'identifier
  • "Devise" : Le logiciel considère que tout est dans la même devise, le change entre devises est exceptionnel dans la vie courante donc il n'est pas nécessaire de rajouter des mentions inutiles pour le supporter. Si l'utilisateur a à manipuler régulièrement différentes devises il peut se tourner vers d'autres logiciels
  • "Type de l'opération" : inutile car à part les espèces dont le montant est faible (il y a peu de personnes qui se promènent avec 1000€ en liquide sur eux) toutes les autres opérations se font à partir de ou vers un compte bancaire. Il suffit alors d'indiquer une opération de retrait (libre à la personne de gérer ce retrait comme elle l'entend).


Ce sont des exemples de la philosophie du logiciel qui se veut KISS avant tout.

KissCount v0.1

Petite mise au point pour ceux qui ne feraient que regarder les images : il y a deux types d'opérations dans KissCount, les opérations en jaune sont les opérations récurrentes (salaire, loyer ...) qui sont automatiquement reportées d'un mois sur l'autre et les opérations en vert sont les opérations du mois en cours (les couleurs et la police de caractère sont paramétrables pour chaque catégorie).

Actuellement les fonctionnalités suivantes sont implémentées :

  • Gestion des opérations, catégories, comptes bancaires
  • Grouper/Dégrouper des opérations
  • Lorsqu'une description est réutilisée pour une nouvelle opération, le logiciel remplit automatiquement la catégorie et le compte bancaire
  • Statistiques de répartition des dépenses (pratique pour analyser son budget)
  • Mode rapprochement (uniquement les opérations sélectionnées sont prises en compte)
  • Possibilité d'insérer des formules à la place de valeurs numériques
  • Fonction de recherche (avec édition des résultats)
  • Gestion des comptes partagés
  • Affichage des opérations de manière croissante ou décroissante
  • Traduction Français/Anglais
  • Support multi utilisateurs
  • Mini site web pour visualiser ses données en ligne (nécessite un serveur web)


Le logiciel n'a donc pas la prétention de détrôner les concurrents déjà en places mais simplement d'apporter une nouvelle vision innovante en partant du besoin réel de l'utilisateur.
A partir de maintenant le développement sera ralenti car toutes les fonctionnalités importantes ont été implémentées, ça ne veux pas dire que le projet est abandonné : s'il manque une fonctionnalité ou qu'il y a (encore) des bugs il y aura de l'activité.

Pour l'aspect technique : il est développé en C++ sur un modèle MVC avec wxWidgets comme boîte à outils graphique et un peu de PHP pour la partie web. Les données sont stockées dans une base SQLite3.

Pour le moment le principal défaut est que l'interface graphique est mal gérée au niveau des layouts, quelques graphiques plus sympa et des traductions seraient les bienvenues !
Le projet est hébergé sur une forge inDefero : http://indefero.soutade.fr/p/kisscount/
Des captures d'écran sont disponibles dans la documentation française et anglaise

Sunday, 26 September 2010
|
Écrit par
Grégory Soutadé

Aujourd'hui deux petites astuces pour notre système favoris

Presse papier du serveur X


Vous connaissez certainement le presse papier, c'est l'emplacement temporaire qui accueille les données du couper/copier/coller. Et bien le serveur X a lui aussi un presse papier. Il suffit de sélectionner du texte dans une fenêtre pour le copier, puis de cliquer sur la molette de la souris (bouton 3) pour le coller. Une fois qu'on y a goûté on ne peux plus s'en passer ! Et surtout on râle quand on est sur les systèmes qui ne proposent pas cette fonctionnalité. De plus le presse papier d'X est indépendant, en gros vous pouvez faire un copier/coller traditionnel et en parallèle un copier/coller via X.


Être averti des mises à jours par mail


Heureux possesseur d'un SheevaPlug, il m'arrive souvent d'oublier de faire les mises à jours. Bon sur ma Debian stable il n'y en a pas tous les jours non plus ... Mais ce petit script va vérifier chaque soir s'il y a des mises à jours à effectuer et me prévient par mail. Bien sûr je pourrais forcer les mises à jours mais c'est moins propre que si c'est fait interactivement (notamment quand il s'agit du noyau et qu'il faut redémarrer).

#!/bin/bash apt-get update > /dev/null res1=`apt-get upgrade -s` res2=`apt-get dist-upgrade -s` res3="$res1\n$res2" echo $res3 | grep 'Inst' >/dev/null || exit 0 # Délimiteur du for IFS=$'\n' packages="apt-get upgrade :" for line in $res1 ; do     echo $line | grep 'Inst' >/dev/null || continue     tmp=`echo $line | cut -d' ' -f 2`     packages="$packages $tmp" done packages="$packages\n\napt-get dist-upgrade :" for line in $res2 ; do     echo $line | grep 'Inst' >/dev/null || continue     tmp=`echo $line | cut -d' ' -f 2`     echo $res2 | grep $tmp >/dev/null && continue     packages="$packages $tmp" done echo -e $packages | mail -s "Packages needs to be updated on cybelle" gregory@soutade.fr

Et dans /etc/crontab :

0  2    * * *   root    /root/apt.sh