Compiler glut-3.7 sous Linux PPC.

Introduction.

En ces temps où les phénomènes astronomiques sont à la mode, il m'a pris l'envie de voir ce que donne ssystem-1.6, un logiciel d'astronomie. Comme d'habitude, je télécharge, je décompacte, je lis la doc en diagonale où je remarque qu'OpenGL ou Mesa-3.0 est nécessaire. Pas de problème, j'ai Mesa, donc je lance la compilation de ssytem-1.6 par make. Arg ! Erreur de compilation : le fichier GL/glut.h est introuvable. Je relis la doc, et je vois qu'il faut la bibliothèque ( http://reality.sgi.com/opengl/glut3/glut3.html) glut que je n'ai pas. Je me procure cette bibliothèque en version 3.7 et sous forme source. Je lis la documentation attentivement, j'effectue les manipulations décrites nécessaires pour Linux, et malgré ça, la compilation ne passe pas, mais alors, pas du tout.

Comme des lecteurs m'ont demandé de faire une sorte de cours de compilation, voilà un bon exemple pour répondre à cette demande. C'est l'objet de ce document qui s'adresse aux débutants, c'est à dire ceux qui ne savent pas ce qui se passe quand on tape make, ou qui ont des notions élémentaires qui ne leur permettent pas de se sortir de pareils cas.

Ce document se veut pédagogique. Il n'y a pas de script à télécharger, pas de patch à appliquer. Toutes les manipulations sont à faire soi-même à la main et sont détaillées et expliquées. On verra aussi que certaines étapes auraient pu être fusionnées mais ne l'ont pas été pour que tout le monde puisse suivre. Il est souhaitable de lire le document en entier avant de commencer quoique ce soit.

21/4/00 : depuis la version initiale de ce document (novembre 99), les choses ont évolué, et on trouve maintenant Glut en RPM, en particulier dans la distribution LinuxPPC 2000.

Conditions initiales.

Il est nécessaire que la bibliothèque Mesa soit installée.

Il faut aussi bien évidemment la bibliothèque (http://reality.sgi.com/opengl/glut3/glut3.html) glut-3.7.

On y va.

Et c'est parti. On décompacte gut-3.7.tar.gz, puis on LIT le fichier README.linux qui nous renvoie immédiatement à linux/README. Effectuez toutes les manipulations décrites, jusqu'au point 4 compris, sans vous poser de question. Vous noterez que le point 2 prend un certain temps.

Première étape.

Et surprise, la première erreur de compilation se produit. Vous devez avoir quelque chose comme ça :

etienne /users/trf/glut-3.7/lib/glut>make
rm -f glut_8x13.o
gcc -c -O2 -m486 -ansi -fPIC   -I../../include -I../.. -I/usr/X11R6/include -Dlinux -D__i386__ -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -DX_LOCALE -DFUNCPROTO=15 -DNARROWPROTO    glut_8x13.c
cc1: Invalid option `486'
make: *** [glut_8x13.o] Error 1
etienne /users/trf/glut-3.7/lib/glut>

Et voilà, comme d'hab, la personne qui a fait le fichier Makefile croit que Linux ne tourne que sur pécé ! Ce n'est pas bien grave, on a l'habitude. La première idée qui vient à l'esprit est de supprimer l'option -m486 qui indique au compilateur de produire du code pour compatible Intel 80486. En fait, supprimer cette option ne suffira pas. On remarque en effet un peu plus loin l'option -D__i386__. Cette option sert à définir la constante (ou macro, ou appelé aussi define) __i386__. Ça sent la compilation conditionnelle à plein nez ! De même pour les autres options -D_POSIX_SOURCE -D_BSD_SOURCE ...

Comme l'archive pèse 3 Mo compactée, on ne va pas aller regarder dans chacun des fichiers pour savoir ce qui se passe afin de déterminer quels sont les macros à définir. Alors, qu'a-t-on fait pour en arriver là ? On a recopié des fichiers, lancé le script mkmkfiles.imake, ... tilt ! Mais que fait donc ce script ? Comme d'habitude avec les logiciels du GNU, il existe un script à exécuter avant de démarrer la compilation. Ce script interroge votre configuration pour produire les Makefiles adaptés à votre cas.

Dans le répertoire lib/glut, nous allons éditer le fichier Makefile (celui qui était dans le répertoire linux) et le fichier Makefile produit par le script mkmkfiles.imake que vous n'aviez pas manqué de sauvegarder comme on vous a demandé de le faire. Je l'ai rebaptisé Makefile.orig.

Dans le fichier Makefile, recherchez la chaine de caractères __i386__. On la trouve utilisée à la ligne 111 :

   CXXSTD_DEFINES = -Dlinux -D__i386__ -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -DX_LOCALE

Dans le fichier Makefile.orig, recherchez la chaine CXXSTD_DEFINES. A la ligne 156, on trouve :

   CXXSTD_DEFINES = -Dlinux -D__powerpc__ -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -D_XOPEN_SOURCE=500L -D_BSD_SOURCE -D_SVID_SOURCE $(CXXPROJECT_DEFINES)

Sélectionnez la ligne 156, copiez la dans le presse papier, puis revenez au fichier Makefile. Mettez la ligne 111 en commentaire en la faisant précéder d'un signe '#'. Allez au début de la ligne 112, insérez une ligne, et collez le contenu du presse papier. (Un conseil, pour effectuer ces manipulations, il vaut mieux, amha, utiliser un autre éditeur que vi. J'utilise fte et Nedit.) Dans votre fichier Makefile, les lignes 111 et 112 sont alors les suivantes :

#   CXXSTD_DEFINES = -Dlinux -D__i386__ -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -DX_LOCALE
   CXXSTD_DEFINES = -Dlinux -D__powerpc__ -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -D_XOPEN_SOURCE=500L -D_BSD_SOURCE -D_SVID_SOURCE $(CXXPROJECT_DEFINES)

Continuez la recherche de la chaine __i386__ dans le fichier Makefile. On la trouve aux lignes 152, 153 et 477, avec en correspondance les lignes 202, 203 et 632 du fichier Makefile.orig. Effectuez à chaque fois le même type de manipulation. Attention, comme vous modifiez au fur et à mesure le fichier Makefile, les lignes à modifier seront en fait 152, 154 et 480. Effectuez les recherches sur les chaines. Je ne vous indique les numéros de ligne qu'à titre indicatif pour que vous puissiez vous y retrouver au cas où vous seriez un peu perdu.

Voilà une chose de faite, maintenant, il faut traiter le cas de l'option -m486, car rappelez vous, c'est cette option qui a causé l'erreur de compilation. Revenez donc au début du fichier Makefile, et recherchez la chaine -m486, et remplacez là par rien. Si vous connaissez le type de PowerPC qui équipe votre Macintosh, vous pouvez quand même remplacer -m486 par -mcpu=601, -mcpu=603, -mcpu=604 ou -mcpu=750 suivant votre modèle de micro-processeur.

Voilà, maintenant que toutes ces manips un peu pénibles sont faites, on peut reprendre la compilation en tapant make. Et ça marche ! L'informatique, c'est fantastique ;-)

C'est pas tout ça, mais où en était on ? Ah oui, on vient de réaliser le point 4 du fichier linux/README. Et bien on passe au point 5 puis au point 6.

Deuxième étape.

Mais tout se passe bien dirait-on ? Oui, mais ça ne va pas durer longtemps ...

En effet, deuxième erreur de compilation :

...
making all in test/glut... 
make[2]: Entering directory `/users/trf/glut-3.7/test/glut'
...
gcc -o test1 -O2 [couic] ../../../lib/libMesaGLU.so ../../../lib/libMesaGL.so -lXext -lX11 [couic]
gcc: ../../../lib/libMesaGLU.so: No such file or directory 
gcc: ../../../lib/libMesaGL.so: No such file or directory 
make[2]: *** [test1] Error 1 
make[2]: Leaving directory `/users/trf/glut-3.7/test/glut'
...

Mais qu'est-ce qui se passe encore ? Le compilateur, ou plus exactement l'éditeur de liens, ne trouve pas les bibliothèques libMesaGL.so et libMesaGLU.so. Et oui, c'est normal, car ces bibliothèques ne sont pas là, mais dans /usr/X11R6/lib (en tout cas chez moi, chez vous c'est peut être différent). D'ailleur, je vais en avoir le coeur net et je regarde ce qu'il y a dans ce répertoire en passant la commande ls -la test/glut/../../../lib. Erreur : ce répertoire n'existe pas. Mauvaise configuration, encore une fois. Il n'y a plus qu'à éditer le fichier test/glut/Makefile, et rechercher "libMesa" que l'on trouve aux lignes 636 et 637 :

OPENGL = $(TOP)/../lib/libMesaGL.so
GLU = $(TOP)/../lib/libMesaGLU.so

Mais qu'est-ce que c'est que ce binz ? Mesa est une bibliothèque, il devrait y avoir -lMesaGL et -lMesaGLU, tout simplement, et non pas ces choses infâmes qui sont définies ! (l'option -lMesaGL indique à l'éditeur de liens que l'on a besoin des fonctions de la bibliothèque libMesaGL) Ben yaka corriger. Oui, mais ce n'est certainement pas le seul endroit où il faudra intervenir de cette manière. Il y a quand même 3 Mo compactés à compiler !

On va donc rechercher dans tous les fichiers Makefile ceux qui utilisent ces bibliothèques :

find . -name Makefile -print -exec grep libMesaGL {} \; | more

Ouh la la, mais c'est qu'il y a bien une centaine de ligne qui vient de défiler ! Je ne vais pas me palucher tout ça à la main. Je suis programmeur, donc paresseux, ne l'oublions pas. Ah, si je connaissais sed, ça se ferait peut être en 2 coups de cuiller à pot. Mais je ne connais pas sed. Faut trouver autre chose. Bon réfléchissons peu, mais réfléchissons bien. Qu'a-t-on fait pour en arriver là. On a recopié des fichiers, on a lancé un script de configuration... Tiens au fait, dans les fichiers copiés, il y a Glut.cf. "cf", comme configuration ? Voyons voir ce que contient ce fichier.

Que lit-on ?

XCOMM Glut.cf - GLUT distribution Imakefile configuration info

On va peut être touver la solution ici. Continuons la lecture.

#ifdef SunArchitecture

Ce n'est pas pour moi, je suis sous Linux. Continuons ...

#else /* Everybody but Sun... */
#ifdef AlphaArchitecture

Toujours pas pour moi ...

#else /* Everybody but Sun or DEC Alpha... */

On s'approche ...

OPENGL = $(TOP)/../lib/libMesaGL.so /* modified per Mesa README PFM 6/31/96 */
GLU = $(TOP)/../lib/libMesaGLU.so /* modified per Mesa README PFM 6/31/96 */

... et on a trouvé quelque chose d'intéressant ! Ben voilà, yapuka faire la modification suivante :

OPENGL = -lMesaGL
GLU = -lMesaGLU

Et puis relancer le script mkmkfiles.imake. Euh non, pas tout de suite parce qu'on va retomber sur la première erreur de compilation ! En effet, ce script va regénérer les fichiers Makefile... Pas de problème, je vais feinter la bête, parce que franchement, je n'ai pas envie de refaire les manipulations de l'étape 1.

Donc, on retourne dans le répertoire lib/glut (cd lib/glut), on renomme le Makefile (mv Makefile Makefile.0), on revient dans le répertoire principal (cd ../..), on lance le script mkmkfiles.imake, on retourne dans le répertoire lib/glut (cd lib/glut), on supprime le fichier Makefile (rm Makefile), on restaure le fichier obtenu à l'étape 1 (mv Makefile.0 Makefile), on revient dans le répertoire principal (cd ../..), et on relance la compilation (make clean, puis make), on se lève de sa chaise ou de son fauteuil, on va dans la cuisine et on se sert un jus de houblon parce qu'on l'a bien mérité, parce qu'il faudra bien s'occuper pendant la compil, et puis il faut reprendre des forces car ce n'est pas terminé ...

NOTE : en fait, dans ce cas précis, on aurait pu relancer le script mkmkfiles.imake sans sauvegarder le Makefile de l'étape 1 et sans faire le make clean puisque les modifications que l'on vient de faire ne jouent que sur l'édition de liens qui n'est pas passée. Comme ce document a pour but d'expliquer sur un exemple comment se passe une compilation et comment s'en sortir en cas d'erreur de compilation, il vaut mieux donner des explications valables dans le cas général, d'autant plus que lorsque l'on touche de cette manière à un Makefile, il vaut mieux tout recompiler, à moins de savoir ce qu'on fait.

Troisième étape.

Bon, la compil est passée. Il n'y a plus qu'à installer la bibliothèque et les fichiers '*.h' associés. Habituellement, on passe la commande make install. Etant donnés les problèmes déjà rencontrés, je suis d'avis de ne pas faire ça en aveugle. Est-ce qu'au moins il y a une procédure de désinstallation (habituellement make uninstall) ? Pour s'en assurer, on édite le fichier Makefile, et on recherche uninstall. Y en n'a pas ! Et bien on va faire l'installation à la main. Les plus curieux verront que le Makefile principal appelle les Makefile dans les sous-répertoires. En particulier, le Makefile du sous répertoire lib/glut est appelé, et celui-ci ne fait rien rien d'autre que d'afficher un message. On est bel et bien obligé de faire l'installation à la main !

Glut est une bibliothèque. Cela signifie que des programmes, comme ssystem-1.6, vont utiliser toute ou partie de son code exécutable. Pour que cette utilisation soit possible, une bibliothèque fournit un ou des fichier(s) '*.h' pour la compilation, et un ou des fichier(s) 'lib*.a' et/ou 'lib*.so' pour l'édition de liens. On sait déjà qu'il y a le fichier glut.h, car c'est celui qui manquait pour compiler ssytem-1.6. On le recherche par la commande suivante :

find . -name glut.h -print

et on trouve

./include/GL/glut.h

Ça se présente bien puisqu'on a un répertoire GL comme pour la bibliothèque Mesa. On regarde donc ce qu'il a dans le répertoire GL (ls -la include/GL) :

-r--r--r--   1 etienne  root        60468 08/08/98 02:18 fgl.h
-r--r--r--   1 etienne  root         7273 08/08/98 02:18 fglu.h
-r--r--r--   1 etienne  root        10152 08/08/98 02:18 fglut.h
-r--r--r--   1 etienne  root         5150 08/08/98 02:18 glsmap.h
-r--r--r--   1 etienne  root        20844 08/08/98 02:18 glut.h
-r--r--r--   1 etienne  root         8874 08/08/98 02:18 tube.h

Par acquis de conscience, vérifions qu'il n'y a pas de doublons avec la bibliothèque Mesa (ls -la /usr/X11R6/include/GL (sur mon système, c'est à cet endroit que se trouvent les '*.h' de Mesa, sur le votre, c'est peut être ailleurs)). Il n'y a pas de doublons, on va pouvoir recopier les fichiers sans problème. Pour cela, devenez root en passant la commande su. Puis copiez les fichiers par la commande cp -vpad include/GL/*.h /usr/X11R6/include/GL/. . Quittez root en tapant exit.

Au tour de la bibliothèque. Comme je l'ai écrit plus haut, le nom d'une bibliothèque est de la forme 'lib*.a' ou/et 'lib*.so'. Cela ne vous rappelle pas le point 5 du fichier linux/README ? On l'a trouvée cette bibliothèque, elle se trouve dans le répertoire lib/glut. On se déplace donc dans ce répertoire (cd lib/glut). Et on va recopier les fichiers 'lib*.so*' au même endroit que la bibliothèque Mesa. Mais où donc ce trouve cette bibliothèque ? Certainement dans /usr/X11R6/lib. On vérifie par la commande ls -la /usr/X11R6/lib | grep -i mesa. C'est bien ça. On redevient root (commande su), puis on copie les fichiers de la bibliothèque (cp -vpad libglut.so* /usr/X11R6/lib/.). On avertit Linux que des nouvelles bibliothèques dynamiques ont été installées en passant la commande /sbin/ldconfig, puis on quitte root en tapant exit.

Et voilà c'est fini ... pour la bibliothèque glut, parce que ce que je voulais faire, c'était voir ce qu'est ssytem-1.6!

Bonus.

Donc, on peut revenir à nos moutons, à savoir compiler ssytem-1.6. Je retourne dans le répertoire, et je tape make. Résultat :

etienne /users/Logiciels/X/gadgets/ssystem-1.6>make
bison -d -v -p cfg cfgparse.y
gcc -c -Wall -O6 -I/root/Mesa-3.0/include -fomit-frame-pointer
 -funroll-loops -fexpensive-optimizations -march=pentium 
 -malign-loops=2 -malign-jumps=2 -malign-functions=2 
 -DLINUXJOY -DSDATADIR=\".\" cfgparse.tab.c
In file included from cfgparse.y:4:
ssystem.h:23: GL/glut.h: No such file or directory
make: *** [cfgparse.tab.o] Error 1

Ah oui, j'avais oublié. C'est l'option -I/root/Mesa-3.0/include qui n'est pas bonne. Cette option demande au compilateur d'ajouter le répertoire /root/Mesa-3.0/include à la liste des répertoires où il va chercher les fichiers '*.h'. Dans le fichier Makefile, remplacez la ligne :

MESADIR=/root/Mesa-3.0

par :

MESADIR=/usr/X11R6

Et relancez la compilation... et mauvaise surprise, ça ne marche toujours pas :

cc1: Invalid option `arch=pentium'
cc1: Invalid option `align-loops=2'
cc1: Invalid option `align-jumps=2'
cc1: Invalid option `align-functions=2'
make: *** [cfgparse.tab.o] Error 1

Ben oui, il y a un micro-processeur dans un Macintosh, pas un 4004 amélioré ! De plus, les options align-loops, align-jumps et align-functions ne sont pas valables avec le compilateur gcc pour LinuxPPC. Donc, dans le Makefile, remplacez les lignes :

CFLAGS = -Wall -O6 -I$(MESADIR)/include -fomit-frame-pointer -funroll-loops \
         -fexpensive-optimizations -march=pentium -malign-loops=2 \
         -malign-jumps=2 -malign-functions=2 -DLINUXJOY -DSDATADIR=\"${SDATADIR}\"

par :

CFLAGS = -Wall -O6 -I$(MESADIR)/include -fomit-frame-pointer -funroll-loops \
         -fexpensive-optimizations  \
         -DLINUXJOY -DSDATADIR=\"${SDATADIR}\"

Ceux qui n'ont pas de joystick peuvent aussi retirer -DLINUXJOY. On remarquera aussi l'option -O6 pour obtenir des optimisations avancées. Le compilateur gcc pour LinuxPPC s'arrête au niveau d'optimisation n° 2 (-O2), mais on peut laisser -O6, ça ne dérange pas.

On relance la compilation par make, et surprise, ça passe. Il n'y a plus qu'à faire exécuter ssytem et de regarder comme c'est beau ... (on appuiera sur la touche h pour voir ce que l'on peut faire).

Conclusion.

Ça a été un peu pénible, mais on s'en est sorti, ce qui n'est malheureusement pas toujours possible. On remarquera aussi que tout n'est pas rose, puisque certains programmes de test de la bibliothèque glut se terminent en erreur. Mais ssytem fonctionne et c'est ce qu'on voulait après tout.

Encore un petit détail. Effacez ou renommez le répertoire glut-3.7, décompressez à nouveau l'archive glut-3.7.tar.gz, placez vous dans le répertoire glut-3.7 et tapez mkmkfiles.imake, puis make ... Etonnant, non ? RTFM qu'ils disaient ... L'informatique, c'est fantastique. Voilà, et entre nous, il est certainement préférable d'installer la bibliothèque libglut.a (statique) qui vient d'être produite et d'effacer les bibliothèques dynamiques libglut.so* qu'on a obtenu au prix d'un bricolage plutôt infâme ...

Ceux qui ne savaient pas ce qui se passait quand on tape make en savent maintenant un peu plus, ce qui est le but du document. La bibliothèque glut et le programme ssystem n'étaient que des prétextes. Et pour vérifier qu'ils ont bien tout compris, ils peuvent s'amuser à modifier ce qu'il faut pour obtenir la bibliothèque glut sous forme dynamique et non plus statique.



Etienne Herlent.

 

Dernière mise à jour le 21/04/00.

les fichiers en téléchargement sont à ftp://ftp.linux-france.org/pub/macintosh/

 

Retour à GNU Linux sur Macintosh