Programmation
Wednesday, 21 September 2011
|
Écrit par
Grégory Soutadé

MAJ du script ici

J'aime bien suivre au jour le jour les statistiques du blog, ça fait passer 5 minutes et parfois cela permet de mieux répondre aux attentes des internautes (quand un mot clé revient régulièrement, mais que l'article proposé ne répond pas forcément à la question). À ce propos mes stats ont été divisés par 2 ou 3 depuis septembre ... Bref elles sont générées via AWStats. Il est un peu lent, mais quand on y est habitué on en tire plein d'informations intéressantes. Le problème principal d'AWStats est qu'il n'est composé que d'un seul fichier PERL de 20 000 lignes, ce qui le rend relativement indigeste et difficile à manipuler pour un néophyte.

L'objectif du jour est d'obtenir les nouvelles phrases clé par rapport à la dernière mise à jour. Pour cela j'ai réalisé un petit script PHP qui va brutalement analyser la sortie HTML d'AWStats et afficher dans un tableau : les nouvelles lignes en vert, les lignes mises à jour en jaune et les lignes supprimées en rouge. Le script est basique, il n'y a pas de gestion de date (si on rafraîchit deux fois dans la même journée), mais fonctionne plutôt bien.

Le script est disponible ici

 

Monday, 15 August 2011
|
Écrit par
Grégory Soutadé

En retard sur ma mise à jour (comme d'hab), me voici donc avec un noyau Linux 3.0 fraichement installé ! Comme d'habitude il faut recompiler le pilote graphique NVIDIA et le pilote Wifi Realtek (rtl8192e), sauf que le passage à la version 3.0 perturbe les scripts de compilation, même si les structures internes sont sensiblement identiques aux dernières 2.6.xx.

Les modifications à appliquer à HAL/rtl8192/Makefile sont :

  • Changer la vérification de version 2.6 en 3.0
-ifeq ($(shell uname -r|cut -d. -f1,2), 2.6) +ifeq ($(shell uname -r|cut -d. -f1,2), 3.0)
  • Le chemin de include/linux/autoconf.h a changé
-CONFIG_FILE := $(KSRC)/include/linux/autoconf.h +CONFIG_FILE := $(KSRC)/include/generated/autoconf.h
  • Le chemin de include/linux/modversions.h a changé
-CFLAGS += -DMODVERSIONS -DEXPORT_SYMTAB -include $(KSRC)/include/linux/modversions.h +CFLAGS += -DMODVERSIONS -DEXPORT_SYMTAB -include $(KSRC)/include/config/modversions.h
  • Changer la variable CFLAGS par EXTRA_CFLAGS


Le patch complet est disponible ici

Un petit make "clean && make && make install" et on peut de nouveau profiter du Wifi !

Le pilote rtl8192e est dans la branche stagging depuis 1 an et demi (noyau 2.6.32), ça serait bien qu'il intègre enfin la branche stable, on pourrait peut être enfin profiter d'un Wifi correct ...

Sunday, 17 April 2011
|
Écrit par
Grégory Soutadé

En retard (comme d'habitude), j'ai mis à jour hier ma Debian Wheezy (testing). Je vois dans la liste qu'il y a un nouveau noyau (le 2.6.38), donc c'est une mise à jour périlleuse pour les périphériques qui ne sont pas directement supportés par le noyau, à savoir : le pilote rtl8192e pour le Wifi et le pilote NVIDIA GeForce 330M pour la carte graphique.

Généralement tout se passe bien, enfin généralement... Pour le wifi c'était OK (il suffit de recompiler les pilotes), mais pour la carte graphique, le serveur X ne voulait plus se lancer. C'est un problème fréquent, on retourne via l'ancien noyau sur le site de NVIDIA, on télécharge le nouveau pilote et les headers du noyau puis on redémarre pour le compiler.

Comme d'hab il y a la vérification de gcc qui se règle en préfixant la commande par CC="gcc-4.4", mais cette fois-ci la compilation échoue ! On va voir ce qui se passe dans /var/log/nvidia-installer.log :

kernel/nv.c:426: error: unknown field ‘ioctl’ specified in initializer

C'est la première fois que ça arrive. Ni une, ni deux, j'extraie les sources de NVIDIA-Linux-x86_64-256.53.run avec

./NVIDIA-Linux-x86_64-256.53.run -x

j'ouvre le fichier nv.c, tout semble correct. Sauf qu'en fait le champs ioctl de la structure file_operations a été supprimé depuis 6 mois à cause du BKL (Big Kernel Lock). Arf les bougres ! La modification à réaliser n'est pas compliquée :

--- a/NVIDIA-Linux-x86_64-256.53/kernel/nv.c 2011-04-17 10:22:22.861937886 +0200 +++ b/NVIDIA-Linux-x86_64-256.53/kernel/nv.c 2011-04-17 09:08:21.000000000 +0200 @@ -423,9 +423,10 @@ static struct file_operations nv_fops = { .owner = THIS_MODULE, .poll = nv_kern_poll, - .ioctl = nv_kern_ioctl, #if defined(HAVE_UNLOCKED_IOCTL) .unlocked_ioctl = nv_kern_unlocked_ioctl, +#else + .ioctl = nv_kern_ioctl, #endif #if defined(NVCPU_X86_64) && defined(HAVE_COMPAT_IOCTL) .compat_ioctl = nv_kern_compat_ioctl,

On déplace le champs ioctl dans un #else. On recompile et ça tourne ! Même binaire, les pilotes NVIDIA sont de très bonne qualité, c'est bizarre d'avoir laissé une telle erreur. Je viens de leur envoyer un message (dur de trouver un point d'entrée), j'espère que ce sera corrigé dans la prochaine version.

Tuesday, 22 February 2011
|
Écrit par
Grégory Soutadé

Après m'être battu un moment avec iconv, voici un petit exemple de conversion ISO-8859-1 vers UTF-8 :

#include ‹iconv.h› int translate_text(char** text, char free_text) { char* tmp_in, *tmp_out, *original_out; size_t mult_size, size_in, size_out; if (!text || !*text) return 1; converter = iconv_open ("UTF-8", "ISO-8859-1"); if (converter <= 0) return 1; size_in = strlen(*text); mult_size = size_out = size_in*4; // Because UTF8 is bigger thant ISO-XXX tmp_in = *text; original_out = tmp_out = malloc(size_out); iconv(converter, &tmp_in, &size_in, &tmp_out, &size_out); // All variables are modified by iconv original_out[mult_size-size_out] = 0; if (free_text) free(*text); *text = original_out; iconv_close(converter); return 0; }
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