Cette situation arrive dans les cas suivants:
- Vous avez une architecture amd64 et c’est un programme i386
- Vous avez un logiciel propriétaire indispensable, cher et que vous vous devez utiliser mais qui date de 10 ans ou presque
Bien, évidemment ici on suppose que tout a été fait pour avoir la version correcte correspondant à votre architecture.
Bon 3 problèmes se posent
-
C’est un programme 32 bits sur une machine 64 bits ou encore un programme où il manque des librairies
-
Le programme utilise une vieille libc6.
-
la libc5
Tout d’abord le premier point
1) Rajout de librairies 32 bits ou de librairies manquantes.
Prenons par exemple l’exemple de maple7 (vieux et i386) à installer sur une Squeeze 64 bits.
On le lance, ça coince. Bon, on regarde où sont les bianires, on les trouve dans
/usr/local/maple7/bin.IBM_INTEL_LINUX
(À ce stade, se dire que maxima est nettement mieux et donne des réponses exactes lui mais bon…). L’outil essentiel est ldd qui permet de savoir les librairies utilisées.
Un
ldd /usr/local/maple7/bin.IBM_INTEL_LINUX/* | grep ound
donne des tas de résultats:
Certains se résolvent facilement (librairies essentielles existant en version 32 bits)
Un simple
francois@totoche:/usr/local/bin$ apt-file search libm.so.6
libc6: /lib/libm.so.6
libc6-i386: /lib32/libm.so.6
révèle que c’est le paquet libc6-i386 qu’il nous faut (ça il fallait le prévoir). C’est parfois moins grossier
francois@totoche:/usr/local/bin$ apt-file search libnspr4.so
ia32-libs-libnspr4: /emul/ia32-linux/usr/lib/libnspr4.so
ia32-libs-libnspr4: /emul/ia32-linux/usr/lib/libnspr4.so.0d
ia32-libs-xulrunner: /usr/lib32/xulrunner/libnspr4.so
iceape-browser: /usr/lib/iceape/libnspr4.so
libnspr4-0d: /usr/lib/libnspr4.so
libnspr4-0d: /usr/lib/libnspr4.so.0d
libnspr4-0d-dbg: /usr/lib/debug/usr/lib/libnspr4.so.0d
libxul-dev: /usr/lib/xulrunner/sdk/lib/libnspr4.so
libxul0d: /usr/lib/xulrunner/libnspr4.so
Ici on voit bien que c’est ia32-libs-libnspr4 qu’il faut prendre.
Et il peut arriver de grosses déceptions:
francois@totoche:/usr/local/bin$ apt-file search libxfce.so
gtk2-engines-xfce: /usr/lib/gtk-2.0/2.10.0/engines/libxfce.so
francois@totoche:/usr/local/bin$
Là il n’y a pas de paquets 32 bits d’existant
L’apothéose étant bien sûr:
francois@totoche:/usr/local/bin$ apt-file search libnag.so
francois@totoche:/usr/local/bin$
où il n’y a rien.
Dans les deux cas, il faut prévoir un répertoire à part où on mettra les librairies car cela se fera sans paquet debian.
Par exemple
Il faut rajouter ce répertoire dans ld.so.conf:
[edit: le .conf est obligatoire depuise squeeze]
Ensuite il faut se procurer la librairie manquante: dans le premier cas, c’est simple, c’est le paquet correspondant de la distribution i386, il suffit donc de charger le paquet i386 en allant le chercher sur http://www.fr.debian.org/distrib/packages, on trouve ici http://ftp.fr.debian.org/debian/pool/main/g/gtk2-engines-xfce/gtk2-engines-xfce_2.4.2-2_i386.deb
Pour récupérer la librairie, il faut utiliser par exemple dpkg-deb:
$ $ wget http://ftp.fr.debian.org/debian/pool/main/g/gtk2-engines-xfce/gtk2-engines-xfce_2.4.2-2_i386.deb
$ mkdir tempo
$ cd tempo
$ dpkg-deb -x ../gtk2-engines-xfce_2.4.2-2_i386.deb .
(il y a un «.» en fin de ligne)
On repère la librairie cherchée dans usr/lib/gtk-2.0/2.10.0/engines/libxfce.so. Un
[code]# mv /tmp/tempo/usr/lib/gtk-2.0/2.10.0/engines/libxfce.so /emul32/local/lib
ldconfig[/code]met en place la librairie (vérifiez que libxfce.so n’est pas un simple lien).
Dans le deuxième cas, il faut chercher la librairie manquante sur une machine où le logiciel tourne ou encore sur internet via un moteur de recherche quelconque et procéder de même.
Il est important d’être assez fin en ne mettant pas des librairies inutiles car déjà existantes, il peut y avoir des incompatibilités et une librairie rajoutée peut être systématiquement utilisée à la place d’une autre. Si on a des problèmes de ce type, le mieux est dans ce cas d’écarter le répertoire /emul32/local/lib de ld.so.conf.d et d’appeler le programme en faisant
Une fois tout cela terminé le programme doit marcher.
2) Erreurs à l’éxécution dues à une version trop récente de la libc6
il existe dans ce cas deux erreurs possibles particulièrement agaçantes
ou
Cela est du au fait que des fonctions (errno et __libc_wait) existantes dans les anciennbes versions des libc6 ont disparues, souvent remplacées par un define. Il suffit pour cela de créer une petite librairie les rédéfinissant:
Ainsi pour la première erreur, il suffit de définir errno par
extern int (* __errno_location);
int errno()
{
return(*__errno_location);
}
Cette librairie se compile par
gcc -O2 -c -o lib-errno.o lib-errno.c
gcc -shared -Wl,-soname,lib-errno -o lib-errno.so lib-errno.o
On la trouvera ici http://boisson.homeip.net/libc6/
Pour wait, c’est un peu plus compliqué car c’est une fonction en assembleur, il faut donc une librairie dédiée i386 et une autre dédiée amd64
i386:
[code]#include <syscall.h>
#include <sys/wait.h>
pid_t __libc_wait (int *status)
{
int res;
asm volatile (“pushl %%ebx\n\t”
“movl %2, %%ebx\n\t”
“movl %1, %%eax\n\t”
“int $0x80\n\t”
“popl %%ebx”
: “=a” (res)
: “i” (__NR_wait4), “0” (WAIT_ANY), “c” (status), “d” (0),
“S” (0));
return res;
}
[/code] en amd64, il faut remplacer ebx par rbx. Ça se compile par
Bref, quand vous avez ces librairies, il suffit en général de les mettre dans /usr/lib ou mieux dans /usr/local/lib, de créer un fichier /etc/ld.so.conf.d/perso contenant
/usr/local/lib
(il y en général un fichier contenant déjà cette ligne, c’est souvent surperflu) et de faire
Si cela ne suffit pas, il faut forcer le chargement de la librairie par un LD_PRELOAD
export LD_PRELOAD=/usr/local/lib/lib-errno.so
programmepenible
ou
Si à ce stade ça coince, ça devient délicat. Par exemple, il n’y a plus à ma connaissance de libc5 compatible libc6. Là le chroot s’impose où alors on peut essayer le bricolage suivant:
- Il faut deux choses pour la libc5: la libc5 elle même qu’on pourra trouver sur Internet (prendre une version la plus récente la 5.4.46) et mettre les fichiers /lib/libc* et /lib/libm* sous /emul32/local/lib/ par exemple (cf ci dessus) puis il faut avoir un fichier /lib/ld-linux.so.1 qui charge le programme et l’exécute. Le rapatriement de ld-linux.so.1.9.11.so fonctionne moyen voire pas du tout, j’ai obtenu de bons résultats en faisant bêtement
[code]# cd /lib