Faire tourner du 32 bits sur 64 bits ou du vieux sur du neuf

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

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:

  1. 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[/code](brutal mais assez efficace).

Est-ce que d’autres utilisateurs ont testé?

En tout cas si ca marche chez toi, bravo

Oui. Il y a plusieurs posts ici. J’ai fait les librairies lib_wait et liberrno pour faire fonctionner les vieux maple © sur les distributions récentes. Vu le prix des licences, ça économise beaucoup d’argent aux lycées qui refusent la mise à jour d’office.

Est-ce que ce genre de procédure pourrait permettre d’installer des programmes sid sur une stable (sans mettre en l’air les dépendances de la stable)?

Non, il y a des soucis de versions de librairies dans un tel cas (libc6). Le meilleur moyen pour être sur de ne pas démolir une stable est de faire un chroot sid.

intéressant, il faut que je lise ton tuto sur le chroot transparent alors pour m’aider.

Question d’ordre plus général : j’imagine que tous les paquets Debian en 32 bits ont été portés en 64 bits, non ?
Car dans ce cas je pense que je n’aurai jamais à utiliser ce tutorial :slightly_smiling:

[quote=“Cluxter”]Question d’ordre plus général : j’imagine que tous les paquets Debian en 32 bits ont été portés en 64 bits, non ?
Car dans ce cas je pense que je n’aurai jamais à utiliser ce tutorial :slightly_smiling:[/quote]
non, ce n’est pas le cas pour tout.

Aïe, c’est bien dommage…
Bon j’imagine tout de même que la très grande majorité des paquets utilisés par le grand public ont été portés quand même. Ca doit être des trucs plus spécifiques, du genre des outils pour du matériel peu répandu, qui peuvent ne pas être dispo en 64 bits, j’imagine ?

Oui, c’est une minorité de paquets qui ne tournent pas en 64 et ça doit se raccourcir de jour en jour.

C’est surtout intéressant pour des programmes propriétaires souvent disponibles uniquement en 32 bits (skype, maple, etc).

modification spécifique à squeeze (.conf sur fichier /etc/ld.so.conf.d/perso.conf)

[code]francois@totoche:~/Téléchargement$ ldd hldsupdatetool.bin
linux-gate.so.1 => (0xf7fbd000)
libc.so.6 => /lib32/libc.so.6 (0xf7e51000)
/lib/ld-linux.so.2 (0xf7fbe000)
francois@totoche:~/Téléchargement$ uname -r
2.6.30-2-amd64
francois@totoche:~/Téléchargement$ arch
x86_64
francois@totoche:~/Téléchargement$

[/code]

As tu linux-gate.so.1 ?

À noter qu’on trouve la libc5 sur

archive.debian.net/fr/slink/libc5

ce truc et astuce fonctionne toujours sur une wheezy même si la libc5 est abandonnée depuis longtemps. Ça commence à être sportif mais ça marche.

Depuis que le dépôt des mainteneurs Mozilla est verrouillé à je ne sais plus quelle version pour squeeze, j’utilise le firefox officiel qui est en 32 bits.

Ce que j’ai fais c’est simplement installé quelques lib comme ia32-libs et ia32-libs-gtk, puis j’utilise un wrapper tout simple :

[code]#!/bin/sh

export LD_PRELOAD=’/usr/lib32/gtk-2.0/2.10.0/engines/libclearlooks.so’
export GTK_PATH=’/usr/lib32/gtk-2.0’

exec /opt/firefox/firefox “$@”[/code]
Je présume que ça marche bien uniquement parce que GTK est packagé comme il faut, mais ça permet d’éviter le chroot pour les cas simples.

En fait je ne fais plus de chroot pour ce genre de choses, le cas le plus délicat a été de faire touner un maple release 4 (datant de 12 ou 13 ans) sur une wheezy 64 bits, donc une libc5 32bits sur du 64bits, ça marche bien!

@fran.b : autant installer Xcas, ça marchera encore mieux :slightly_smiling:

Flo

Hum, Xcas n’étant pas pour le moment au programme des concours, j’imagine la tête des 300 élèves si je leur dis que «Tant pis pour les concours, c’est Xcas!»

Mais là c’est HS, on peut continuer la discussion dans Pause Café si tu veux (je transférerai dans ce cas le morceau du fil)

Au temps pour moi, j’ai pas relu le fil et j’étais resté dans l’idée que tu faisais du chroot+debootstrap.