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
1) C'est un programme 32 bits sur une machine 64 bits ou encore un programme où il manque des librairies
2) Le programme utilise une vieille libc6.
3) 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
Code:
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)
Citer:
libm.so.6: not found
Un simple
Code:
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
Code:
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:
Code:
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:
Code:
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
Code:
# mkdir /emul32/local/lib
Il faut rajouter ce répertoire dans ld.so.conf:
Code:
# echo /emul32/local/lib/ >> /etc/ld.so.conf.d/perso.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.debPour récupérer la librairie, il faut utiliser par exemple dpkg-deb:
Code:
$ $ 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
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
Code:
LD_LIBRARY_PATH=/emul32/local/lib/:$LD_LIBRARY_PATH nomduprogramme
Une fois tout cela terminé le programme doit marcher.
2) Erreurs à l'éxécution dues à une version trop récente de la libc6il existe dans ce cas deux erreurs possibles particulièrement agaçantes
Citer:
symbol errno, version GLIBC_2.0 not defined in file libc.so.6 with link time reference
ou
Citer:
symbol __libc_wait, version GLIBC_2.0 not defined in file libc.so.6
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
Code:
extern int (* __errno_location);
int errno()
{
return(*__errno_location);
}
Cette librairie se compile par
Code:
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;
}
en amd64, il faut remplacer ebx par rbx. Ça se compile par
Code:
gcc -fpic -O2 -shared libcwait.c -o libcwait.so
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
Code:
/usr/local/lib
(il y en général un fichier contenant déjà cette ligne, c'est souvent surperflu) et de faire
Code:
# ldconfig
Si cela ne suffit pas, il faut forcer le chargement de la librairie par un LD_PRELOAD
Code:
export LD_PRELOAD=/usr/local/lib/lib-errno.so
programmepenible
ou
Code:
LD_PRELOAD=/usr/local/lib/lib-errno.so programmepenible
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:
3) 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
# ln -s ld-linux.so.2 ld-linux.so.1
(brutal mais assez efficace).