V. La première passe▲
V-A. Compiler binutils▲
Entrez dans le dossier build avec la commande
$ cd /work/build
et décompressez les sources de binutils dans un sous dossier de src avec la commande
$ tar -vxjf /c/downloads/binutils-2.17.tar.bz2 -C /work/src
Créez un dossier de compilation pour binutils et entrez dedans avec la commande
$ mkdir binutils && cd binutils
Invoquez la configuration de binutils avec la commande
$ ../../src/binutils-2.17/configure --prefix=/mingw --target=i686-pc-mingw32 \
--program-prefix="" \
--with-lib-path=/mingw/mingw32/lib:/mingw/lib:/usr/local/lib:/lib:/usr/lib \
--with-gcc --with-gnu-as --with-gnu-ld --disable-nls --disable-shared
Comprendre la commande
- --prefix=/mingw indique la racine du chemin d'installation
- --target=i686-pc-mingw32 spécifie la cible pour laquelle la compilation est effectuée
- --program-prefix="" indique qu'il ne faut rien rajouter au début des noms d'exécutables
- --with-lib-path fournit les dossiers dans lesquels ld devra s'attendre à trouver les différentes bibliothèques
- --disable-shared signale que les exécutables doivent être créés sans utiliser les bibliothèques partagées
- --with-gcc indique que l'on va utiliser GCC pour la compilation
- --with-gnu-as et --with-gnu-ld indiquent que l'on va utiliser les outils (assembleur et éditeur de liens) gnu
Comprendre l'option --target=
La syntaxe générale des options --target= (et --target= qui permet de configurer la compilation croisée) est <type processeur>-<type d'ordinateur>-<systeme>
La syntaxe est adaptée à mon cas car je dispose à ce jour d'un processeur Athlon-xp (équivalent Pentiun III), et il faudra donc penser à l'adapter à votre configuration personnelle.
Pour le type de processeurs sur PC, cela peut varier, selon votre configuration personnelle, parmis les valeurs suivantes:
- i386: pour les processeurs de type 3x86
- i486: pour les processeurs de type 4x68
- i586: pour les processeurs de type Pentium I (et équivalents)
- i686: pour les processeurs de type Pentium II (et équivalents)
- i786/i886/i986: pour les processeurs de type supérieurs
- IA-64: pour les processeurs 64 bits simples et multi-core de chez intel ("Itanium Processor Familly")
- x86_64 (ou amd64): pour les processeurs 64 bits simples et multi-core de chez AMD
Le type d'ordinateur étant ici un PC, c'est celui que l'on utilisera le plus souvent...
Cependant, il est possible de compiller les outils GNU sur une longue série d'autres ordinateurs, allant du solaris au powerpc, en passant de manière non exhaustive par le HP-HUX ou les systèmes SCO.
Enfin, le système sera, avec les PC's, principalement mingw32 (==windows) et linux
Vous trouverez la liste complètes des spécifications d'hôte et de cible
directement sur le site de GCC
Il ne semble pas à l'ordre du jour de l'équipe de MinGW d'envisager
d'évoluer vers une solution 64 bits.
Il ne reste plus qu'à invoquer la compilation:
$ make CFLAGS="-O2 -D__USE_CRTIMP -fno-exceptions" LDFLAGS=-s
et l'installation
$ make install
Enfin, il est temps de faire le ménage pour la deuxième passe avec la commande
$ make clean
V-B. Compiler les bibliothèques indispensables▲
Lorsque nous essayerons de compiler GCC, nous nous heurterons à un problème, certes mineur, mais qu'il vaut mieux anticiper juste après avoir compilé binutils.
En effet, GCC sera compilé, par défaut trois fois: une première fois pour obtenir une version compilée et utilisable de GCC, la deuxième fois pour s'assurer que GCC ait été compilé... en utilisant la même version de GCC. et une troisième fois pour vérifier que tout a bien fonctionné.
Toute l'astuce réside dans le fait que, pour la deuxième et la troisième compilation, il cherchera les fichiers d'en-têtes et les bibliothèques... dans le dossier dans lequel il devra s'installer.
Il faut donc veiller à ce que les en-têtes et les bibliothèques se trouvent au bon endroit quand GCC en aura besoin, et, tant qu'à faire, autant qu'il dispose d'une version qui aura été compilée en utilisant l'assembleur et l'éditeur de liens avec lequel nous lui demanderons de travailler dorénavant.
V-B-1. Compiler w32-api▲
retournez dans le dossier général de compilation et décompressez l'archive des sources dans le dossier source avec les commandes
$ cd /work/build
$ tar -vxjf /c/downloads/w32api-3.10.1-src-tar.bz2 -C /work/src
Comme la compilation de mingw-runtime cherchera un dossier avec les source de w32-api, sans information de version, renommons directement le dossier en vue de satisfaire la runtime de mingw avec la commande
$ mv /work/src/w32api-3.10-1 /work/src/w32api
il n'y a plus qu'à créer un dossier nommé w32api, y entrer et à effectuer la configuration, la compilation et l'installation avec les commandes
$ mkdir w32api && cd w32api
$ ../../src/w32api/configure --prefix=/mingw --target=i686-pc-mingw32 \
--with-as=/mingw/bin/as.exe --with-ld=/mingw/bin/ld.exe
$ make
$ make install
les options --with-ld=/mingw/bin/ld.exe et --with-as=/mingw/bin/as.exe permettent de spécifier l'éditeur de lien et l'assembleur à utiliser, et plus particulièrement, de dire qu'il faut utiliser la version que nous venons de compiler et d'installer.
Terminons en nettoyant le dossier en vue de la deuxième passe
$ make clean
L'avantage de la commande clean est qu'elle supprime les fichiers générés, mais laisse les Makefile et les éventuelles copies de fichiers source en place, ce qui nous permettra de ne pas devoir refaire la configuration lors de la deuxième passe
V-B-2. compiler mingw-runtime▲
La compilation de mingw-runtime ne devrait pas poser énormément de problèmes, il suffit en effet de retourner dans le dossier général de compilation, de décompresser l'archive dans le dossier source, de créer un dossier de compilation pour mingw-runtime, d'y entrer, d'invoquer la configuration, la compilation et l'installation avec les commandes
$ cd /work/build
$ tar -vxzf /c/downloads/mingw-runtime-3.13-20070825-1-src.tar.gz -C/work/src
$ mkdir mingw-runtime && cd mingw-runtime
$ ../../src/mingw-runtime-3.13-20070825-1/configure --prefix=/mingw \
--target=i686-pc-mingw32 --with-as=/mingw/bin/as.exe --with-ld=/mingw/bin/ld.exe
$ make
$ make install
sans qu'il n'y ait de nouveautés particulières;).
Sans oublier de faire le ménage pour la passe suivante avec un
$ make clean
V-B-3. Compiler libiconv (facultatif)▲
Libiconv n'est pas à proprement parler indispensable pour compiler GCC.
Son intérêt réside dans le fait qu'il permet de convertir le codage des textes afin de modifier la table de caractères utilisée.
La présence de cette bibliothèque est vérifiée de manière systématique lors de la compilation de GCC.
C'est la raison pour laquelle je me dis que, tant qu'à faire, autant la compiler dés le départ ;).
La suite de commande pour y arriver est:
$ cd /work/build
$ tar -vxzf /c/downloads/libiconv-1.11.tar.gz -C /work/src
$ mkdir libiconv && cd libiconv
$ ../../src/libiconv-1.11/configure --prefix=/mingw host=i686-pc-mingw32 \
--with-gnu-ld --with-gnu-as --with-ld=/mingw/bin/ld.exe \
--with-as=/mingw/bin/as.exe
$ make
$ make install
$ make clean
V-B-4. GMPlib et MPRF▲
Il y a deux bibliothèques qui seront nécessaires si vous souhaîtez activer le support de FORTRAN dans GCC et dont je n'ai pas encore parlé. Il s'agit de bibliothèques mathématiques particulières nommées respectivement gmplib et mpfr.
Gmplib est l'abréviation de GNU Multiple Precision Arithmetic Library, et est donc, pour ceux qui auraient des problèmes avec la langue de shakespeare, une bibliothèque GNU founissant la précision arithmétique multiple. Elle est disponible directement sur le site de l'équipe qui s'en occupe
MPFR est l'abréviation de Multiple-Precision Floating-point computations with correct Rounding, c'est à dire une bibliothèque qui fournit la possibilité d'effectuer des calculs à virgule flottante avec un arrondi correct. Vous pouvez également vous en procurer les sources directement sur le site qui s'en occupe
Vous pouvez, bien sûr, décider de ne pas les installer si vous ne prévoyez pas d'activer le support de FORTRAN, mais, d'un autre côté, les occasions dans lesquelles vous serez content d'en disposer, même en C ou en C++, risquent d'être nombreuses... Mais bon, à vous de choisir ;).
V-B-4-a. Compiler GMPLib▲
Le script de configuration de gmplib lui permet de déterminer de manière très correcte la meilleure manière de compiler la bibliothèque en fonction de votre système. De ce fait, il suffit de lui fournir le dossier dans lequel vous souhaîtez la voir installer, en précisant cependant que nous voulons utiliser notre toute nouvelle collection d'outils.
Une fois de retour dans le dossier build , il vous suffira donc de décompresser l'archive, de créer un dossier de compilation pour gmp et d'y entrer, avant de demander la configuration, la compilation et l'installation à l'aide des commandes
$ cd /work/build
$ tar -vxjf /c/downloads/gmp-4.2.1.tar.bz2 -C /work/src
$ mkdir gmp && cd gmp
$ ../../src/gmp-4.2.1/configure --prefix=/mingw --with-as=/mingw/bin/as.exe \
--with-gnu-ld=/mingw/bin/ld.exe
$ make
$ make install
Sans oublier de faire le ménage pour la passe suivante
$ make clean
V-B-4-b. Compiler MPRF▲
La compilation de MPRF ne devrait pas non plus poser problème. La suite désormais classique d'instructions
$ cd /work/build
$ tar -vxjf /c/downloads/mpfr-2.2.1.tar.bz2 -C /work/src
$ mkdir mpfr && cd mpfr
$ ../../src/mpfr-2.2.1/configure --prefix=/mingw --target=i686-pc-mingw32 --with-gnu-ld \
--with-gnu-as --with-ld=/mingw/bin/ld.exe --with-as=/mingw/bin/as.exe
$ make
$ make install
sera suffisante, mais il ne faudra pas oublier de faire le ménage avec
$ make clean
V-C. Compiler GCC▲
Nous arrivons, enfin, au but réel de cet article: la compilation de GCC.
Bien qu'ayant essayé à peu près toutes les solutions proposées, je n'ai trouvé aucun moyen de compiler correctement libjava (la bibliothèque de support du langage Java). Ce qui suit va donc permettre la compilation de tout, sauf de cette bibliothèque.
Sur les FTP de GNU.org, il est possible de trouver les sources de la collection sous deux formes: une archive regroupant les sources de l'ensemble de la collection ou plusieurs archives ne contenant chaque fois que les source d'une des parties de la collection (GCC-core (base), GCC-g++ (support de C++), GCC-ada (support d'Ada), GCC-g77 (support de FORTRAN) et GCC-objc (support de ObjectiveC).
Si vous décidez de ne pas prendre l'ensemble des sources, vous devrez au minimum prendre l'archive GCC-core et les archives qui correspondent aux langages pour lesquels vous souhaitez activer le support.
Par facilité, je considérerai que vous avez téléchargé l'archive "commune", si vous avez téléchargé les archives séparées, sera qu'il faudra décompressé chaque archive une à une.
La décompression des sources ne devrait pas poser de problème, avec l'éternelle suite de commande
$ cd /work/build
$ tar -vxjf /c/downloads/gcc-4.2.1.tar.bz2 -C /work/src
$ mkdir gcc && cd gcc
V-C-1. Avant la configuration▲
L'un des principaux problèmes que l'on rencontrera au cours de la compilation est que la création de liens symboliques échoue sous MSYS, lors de la compilation de libada.
Pour résoudre ce problème, il suffira de modifier une seule variable, que nous retrouverons dans plusieurs fichiers.
Ainsi, il faudra rechercher la variable LN_S, qui est définie avec une valeur de @LN_S@, dans le fichier c:\msys\1.0\work\src\gcc-4.2.1\gcc\libada\Makefile.in aux alentours de la ligne 30
et la modifier pour lui donner la valeur cp de manière à forcer la copie des fichiers plutôt que la création de liens symboliques.
Assez bizarement les autres bibliothèques ne souffrent pas de ce problème.
V-C-2. La commande de configuration▲
La commande de configuration prend la forme de
$ ../../src/gcc-4.2.1/configure --prefix=/mingw --target=i686-pc-mingw32 \
--program-prefix="" --with-as=/mingw/bin/as.exe \
--with-ld=/mingw/bin/ld.exe --with-gcc --with-gnu-ld --with-gnu-as \
--enable-threads --disable-nls \
--enable-languages=c,c++,ada,fortran,objc,obj-c++,treelang \
--disable-win32-registry --disable-shared --without-x \
--enable-interpreter
et est, en définitive, fort proche de ce que gcc -v nous a donné.
Seules les références à libjava et ses à côtés ont été supprimées pour les raisons exposées plus haut.
V-C-2-a. Comprendre la commande▲
La plupart des options fournies devraient permettre à quiconque connaissant un minimum l'anglais de les comprendre.
Cependant, pour ce qui concerne les langagess dont le support est activé, cette liste est exhaustive de l'ensemble des langages supportés. En effet, il est possible de remplacer cette liste par --enable-languages=all, mais cette manière de faire n'activera le support que pour C, C++, Java, FORTRAN, Ada et ObjC, en ne prenant pas en compte celui de Objective C++ et de treelang.
V-C-2-b. Au sujet de la compilation en elle-même▲
Lorsque l'on décide de lancer la compilation d'un compilateur, on ne sait jamais à la base quel compilateur, ou quelle version du compilateur sera utilisée pour effectuer la première compilation.
C'est la raison pour laquelle lorsque vous lancerez la compilation de GCC, il y aura en définitive trois compilations successives effectuées. Ce phénomène de compilations successives s'appelle le bootstrap
- La première pous s'assurer que les suivantes seront effectuées avec la bonne version de GCC
- La deuxième pour être tout à fait sur que ce soit bien la bonne version de GCC qui a compilé GCC
- la troisième pour s'assurer que GCC sait se compiler lui-même
Il paraîrait en outre que le compilateur est de plus en plus optimisé au fil des compilations successives (mais je ne suis pas en mesure de confirmer ni d'infirmer une telle chose)
Cependant, il faut bien se rendre compte que de telles compilations en cascade prennent du temps. Et il est tout à fait possible de modifier le nombre de ces compilations.
En effet, il est possible de n'effectuer qu'une seule compilation, par exemple si vous avez déjà la version de compilateur fonctionnelle, mais que vous voulez obtenir un compilateur croisé en rajoutant
all-target stage1-bubble
à la commande de compilation (attention, vous risquez aussi de devoir ajouter la commande enable-stage1-languages=all lors de la configuration).
Vous pouvez aussi demander à n'effectuer que deux compilations, de manière à gagner un peu de temps, quitte à ce que le compilateur ne soit pas aussi bien optimisé (ce sur quoi je ne me prononcerai pas) en rajoutant
bootstrap2
à la ligne de compilation.
Enfin, vous pouvez, au contraire, demander à effectuer une quatrième compilation, quitte à perdre encore plus de temps, mais dans l'idée qu'il sera mieux optimisé au final en rajoutant
bootstrap4
à la ligne de compilation.
De plus, il est tout à fait possible d'utiliser les drapeaux classiques pour GCC dans la ligne de compilation:
-J(nombre de processeur(s) ou de coeur(s))+1
aura de grandes chances de diminuer le temps de compilation, et ce d'autant plus que vous aurez une architecture avec de nombreux coeurs ou processeurs.
-m32 ou
-m64
sera utile au pocesseurs d'architecture pour déterminer si l'exécutable doit être codé sur 32 ou 64 bits.
march=<architecture>
permettra d'affiner l'architecture que vous utilisez
-Os
-O3
permettra d'optimier le compilateur pour la taille, ou pour la vitesse (attention, j'ai entendu, sans être en mesure d'affirmer quoi que ce soit, que -O3 était déconseillé pour le compilateur).
V-C-2-c. Lancer la compilation▲
Il n'y a plus qu'à lancer la compilation avec la commande
$ make CFLAGS="-O2 -fomit-frame-pointer" \
CXXFLAGS="-mthreads -fno-omit-frame-pointer -O2" LDFLAGS=-s
Si vous n'avez rien précisé comme information de bootstrap, et selon le matériel dont vous disposez, vous pouvez sans doute décider d'aller au cinema, car cela prendra du temps à se faire (4 à 5 heures dans mon cas).
Une fois que la compilation aura été menée à terme, il ne restera plus qu'à demander l'installation avec la commande
$ make install