Compiler Qt 4 avec Visual C++ 2005Date de publication : 01/03/2006
Par
Aurélien Regat-Barrel (Espace personnel) Cet article a pour but de faciliter la compilation Qt/Windows Open Source Edition avec Microsoft Visual C++ 2005. Il présente aussi de manière détaillée le processus de compilation et le principe de configuration de cette bibliothèque.
Introduction Première compilation de Qt Configurer la compilation Principe Support des base de données : exemple avec ODBC et PostgreSQL Détails sur le processus de compilation et le fonctionnement du patch Personnaliser la compilation Personnalisation avancée de la compilation Compilation d'une version release sur mesure Modification des options de compilation de Visual C++ Modification de qmake Recompilation des bibliothèques tierces Réalisation d'un paquetage prêt à l'emploi Liens utiles Introduction
L'année 2005 est marquée de deux bonnes nouvelles en matière de développement sous Windows :
Qt est disponible en version GPL sous Windows depuis la version 4 (Qt/Windows Open Source Edition)
et Microsoft distribue gratuitement
Visual C++ 2005 en version limitée mais qui reste à mon avis largement
au dessus des autres IDE C++ gratuits.
Microsoft et Trolltech ont donc fait preuve de générosité, mais cela ne nous dispense pas pour
autant d'un minimum d'efforts avant de pouvoir utiliser conjointement les deux produits.
Car Trolltech a volontairement limité le support de Qt/Windows Open Source Edition
au compilateur MingW (port de GCC sous Windows), ce qui complique son utilisation
avec Visual C++. Mais avec quelques connaissances et un peu de malice,
cela reste possible. Cet article tente d'expliquer en détails comment procéder.
Les lecteurs pressés peuvent se rendre directement en fin d'article où ils trouveront
une archive contenant Qt 4.1.1 prête à être utilisée avec Visual C++ 2005.
Première compilation de Qt
Avant toute chose, il faut bien sûr commencer par installer Visual C++ et Qt.
Pour VC++, je vous renvoie vers l'article
Prise en main de Visual C++ Express Edition.
Veillez à bien avoir installé le Platform SDK (PSDK). Pour Qt, récupérez la dernière version disponible de Qt/Windows Open Source Edition (au moment où j'écris ces lignes, il s'agit de la version 4.1.1 : ftp://ftp.trolltech.com/qt/source/qt-win-opensource-src-4.1.1.zip), et décompressez l'archive dans un répertoire donné. Pour cet article, j'utilise C:\qt4 comme emplacement racine.
Normalement, la compilation est effectuée en deux temps :
Mais comme évoqué lors de l'introduction, la version GPL n'est prévue pour être compilée qu'avec MingW.
Si on lance configure, celui-ci nous le rappelle:
Cette limitation porte essentiellement sur le processus de compilation et non sur les sources de la bibliothèque en elle-même.
Il manque ainsi les fichiers de configuration pour les différentes versions de Visual C++.
Heureusement, il existe un patch ajoutant le support de ce compilateur (et d'autres...), qui
se trouve ici:
Qt/Win Free - Unofficial patches for Qt4. Il devrait normalement y avoir une version correspondant à
la version de Qt que vous utilisez.
En ce qui me concerne (Qt 4.1), j'ai téléchargé le fichier
acs4qt41p3.zip.
Une fois récupéré, il faut le décompresser dans le même répertoire que Qt, soit (C:\qt4) dans mon cas.
Le répertoire C:\qt4 contient donc à sa racine l'ensemble du code source de Qt ainsi que les fichiers
du patch. Il n'y a plus qu'à installer ce dernier. En lisant le fichier d'aide, on apprend qu'il suffit simplement
d'exécuter installpatch41.bat.
Avant de démarrer la compilation, il reste une dernière chose à effectuer : préparer l'environnement,
c'est à dire faire en sorte que l'ensemble des outils (nmake...) et bibliothèques (VC++, PSDK, ...)
de compilation soient accessibles.
En ce qui concerne les outils et bibliothèques fournies avec VC++ 2005, tout est automatiquement configuré
par un fichier de commande spécial vsvars32.bat créé lors de l'installation.
Il se trouve normalement dans C:\Program Files\Microsoft Visual Studio 8\Common7\Tools.
La variable d'environnement %VS80COMNTOOLS% devrait désigner cet emplacement.
Il suffit donc de taper dans la console (les guillemets sont importants):
pour rendre les outils de VC++ accessibles.
De même, le Platform SDK dispose d'un fichier de commande créé à l'installation qui se charge de configurer l'environnement de compilation pour le rendre accessible:
Il ne reste plus qu'à démarrer la compilation.
Le fichier d'aide du patch indique qu'il ne faut pas passer par configure
mais par qconfigure.bat fourni avec le patch,
en lui passant en premier argument le nom du compilateur à utiliser,
soit msvc2005 dans notre cas:
Le processus démarre alors (vous pouvez aller boire un café...).
Une fois terminé, vous devriez obtenir dans les répertoires C:\qt4\bin et C:\qt4\lib
les divers outils et modules Qt compilés.
Vous pouvez en particulier lancer C:\qt4\bin\qtdemo.exe pour avoir droit à une présentation
interactive à la PowerPoint du framework.
Configurer la compilationPrincipe
La compilation est paramétrable via configure au moyen de diverses options.
Exécutez
pour en avoir le détail.
Dans notre cas, nous devons passer par le fichier qconfigure.bat, en lui donnant
msvc2005 comme premier paramètre.
Il est possible de lui en donner d'autres en suivant afin qu'il les transmette à configure.
Ceci est embêtant car on peut facilement arriver à dépasser ce chiffre.
Théoriquement, configure supporte le paramètre -loadconfig qui permet de spécifier un fichier contenant une liste
de paramètres, mais la version livrée avec Qt 4.1 ne semble pas le supporter.
Il en est de même pour d'autres paramètres (saveconfig, redo, prefix...).
La version Windows de configure n'est en effet pas totalement finalisée
(cela devrait évoluer à partir de Qt 4.2).
Une solution est d'éditer le fichier qconfigure.bat pour ajouter lors de l'appel
à configure des paramètres supplémentaires.
Mais ce fichier qconfigure.bat possède un autre inconvénient :
il relance systématiquement la compilation de toute la bibliothèque, y compris
celle des outils, des exemples, des tutoriels, etc...
Ce qui est très long, et inutile si on l'a déjà fait.
C'est pourquoi je me suis lancé dans la réalisation de mon propre fichier .bat, que je présente
un peu plus loin.
Support des base de données : exemple avec ODBC et PostgreSQL
Il peut aussi être nécessaire d'installer d'autres bibliothèques nécessaires à la compilation de Qt,
en particulier si vous comptez utiliser des bases de données.
Par exemple, si vous souhaitez pouvoir utiliser PostgreSQL depuis Qt, deux options s'offrent à vous:
En plus de PostgreSQL, Qt 4.1 sait aussi directement s'interfacer avec MySQL,
IBM DB2, Borland InterBase, Oracle, SQLite et Sybase. Pour plus d'informations à ce sujet, consultez la
documentation de QSqlDatabase
ainsi que celle du module QtSql.
Dans le cas de PostgreSQL, l'installation du driver ODBC (cercle du haut dans l'image ci-dessous)
et/ou de la bibliothèque libpq (cercle du bas) se fait/font depuis l'installeur:
![]() Installation du driver ODBC pour PostgreSQL et de sa bibliothèque libpq
Détails sur le processus de compilation et le fonctionnement du patch
Le rôle de configure est, ô surprise, de configurer la compilation de Qt.
Concrètement, cela consiste en répercuter à plusieurs niveaux la signification des paramètres
reçus en ligne de commande:
configure génère aussi le fichier qtconfig.cpp et se charge de recompiler qmake
avant de l'appeler, sauf si on lui a demandé de ne pas le faire (option -no-qmake).
Dans la version Open Source de Qt, configure n'accepte de fonctionner que si
QMAKESPEC est défini à win32-g++,
c'est à dire que Qt est configuré pour être compilé avec MingW.
Pour le faire fonctionner, il faut donc définir QMAKESPEC à win32-g++
au moyen du paramètre -platform win32-g++ (ou encore en créant une variable d'environnement
nommée QMAKESPEC initialisée à win32-g++).
Mais cela a pour conséquence que la compilation va être paramétrée pour MingW
au moyen du contenu de C:\qt4\mkspecs\win32-g++\.
Autant dire qu'elle échouera rapidement dans notre cas.
Pour permettre la compilation avec Visual C++ 2005, le patch crée (entre autre) le répertoire
C:\qt4\mkspecs\win32-msvc2005\
qui contient ce qu'il faut pour que qmake parvienne à utiliser VC++ 2005 comme compilateur.
On pourrait remplacer le contenu d win32-g++ par celui de win32-msvc2005
afin de gruger configure, mais il y a plus fin.
Analysons le fonctionnement du patch et de son fichier qconfigure.bat. Dans notre cas, il se résume ainsi:
En plus de -platform win32-g++, qconfigure.bat transmet systématiquement à votre insu les paramètres
-no-qmake et -dont-process dont l'utilité est expliquée en suivant, ainsi que les paramètres
-qt-zlib -qt-libmng -qt-libpng -qt-libjpeg dont je n'ai pas pris le temps d'étudier le but
étant donné qu'ils me conviennent.
configure est ainsi exécuté de façon minimale afin qu'il se limite effectivement à la stricte configuration
de Qt, c'est à dire sans compiler qmake (via l'option -no-qmake) car elle échouerait
et sans générer les makefiles (-dont-process) puisque qmake n'est pas disponible.
configure se limite donc essentiellement à créer les fichiers qtconfig.h et qtconfig.cpp
qui conviennent, ainsi qu'à configurer qmake via .qmake.cache.
Une fois ceci effectué, on en a terminé avec la configuration.
Reste à créer les makefiles pour nmake via qmake, mais ce dernier n'existe toujours pas.
Il faut donc d'abord le compiler, avec VC++ et non MingW.
Le patch installe pour cela le makefile qu'il faut, dans C:\qt4\qmake\Makefile.win32-msvc2005.
Il suffit de le transmettre à nmake:
pour obtenir au bout de quelques minutes le précieux qmake.
Il ne reste plus alors qu'à définir correctement QMAKESPEC
et à lancer qmake pour obtenir les makefiles tant attendus.
qmake va alors aller lire le fichier cache .qmake.cache dans son répertoire parent
(qui est aussi le répertoire courant).
Puis comme aucun fichier projet ne lui est donné en argument, il va regarder dans le répertoire courant (C:\qt4)
s'il en trouve un.
Et justement il y a un : projects.pro, qui constitue donc le point de départ de la compilation de Qt.
Si l'on ouvre ce fichier, on trouve un passage intéressant à son début:
Ainsi, si QT_PROJECTS n'est pas défini, les sous répertoires traités par qmake
sont src, tools, demos et examples.
Donc, en définissant QT_PROJECTS à src avant l'appel de qmake,
on peut restreindre la compilation uniquement au code source de la bibliothèque, ce qui est bien moins long.
Personnaliser la compilation
En ce qui me concerne, j'ai l'habitude de travailler ainsi avec les bibliothèques:
Dans le cas de Qt, en debug comme en release, je souhaite bénéficier:
Ceux susceptibles de varier d'une compilation de Qt à l'autre sont:
Idéalement, ces derniers paramètres devraient être passés selon les besoins en ligne de commande,
et les autres devraient être automatiquement actifs. C'est pourquoi je les ai
inclus directement dans mon propre fichier .bat (voir les explications relatives à qconfigure.bat
un peu plus haut). Ce fameux fichier .bat sur mesure, le voici:
Ce fichier ne compile pas qmake s'il l'a déjà été, et limite par défaut la compilation aux
sources de Qt. Il est aussi configuré pour aller chercher vsvars32.bat et le PSDK
dans leurs emplacements par défaut définis respectivement par la variable d'environnement
VS80COMNTOOLS (qui devrait déjà exister) et la variable PSDK_SETENV_PATH créée au
tout début du fichier. Vérifiez que l'emplacement désigné par ces deux variables est
correct (un message d'erreur devrait s'afficher si ce n'est pas le cas). Si la variable d'environnement QT_PROJECTS n'est pas définie, elle est initialisée à src afin de restreindre par défaut la compilation au code source de la bibliothèque uniquement. Les autres valeurs possibles sont tools, demos et examples. Les valeurs choisies sont transmises en argument à qmake lors de son appel.
Pour compiler la version dll debug, il faut l'appeler ainsi:
Et pour compiler toute la bibliothèque en version release statique:
Personnellement, pour la compilation en release,
je désactive certaines fonctionnalités afin d'accélérer la compilation et de réduire
la taille des exécutables produits:
Personnalisation avancée de la compilationCompilation d'une version release sur mesure
Normalement, vous devriez être parvenu à compiler une version release statique de Qt, idéale
pour compiler un exécutable final autonome. Enfin presque.
Car à y regarder de plus près, si on obtient bien un exécutable qui ne dépend d'aucune dll Qt en release,
ce même exécutable reste lié dynamiquement à la bibliothèque C/C++ standard, la CRT.
Visual C++ permet en effet de se lier soit statiquement à la CRT, soit dynamiquement.
Dans le dernier cas, l'exécutable obtenu est dépendant des dlls msvcr80.dll et msvcp80.dll en release,
et msvcr80d.dll et msvcp80d.dll en debug.
Vous l'aurez compris, en debug comme en release, Qt est compilé pour utiliser la version dynamique de la CRT,
c'est à dire au moyen de l'option
-MD
au lieu de
-MT
en release.
Les programmes obtenus doivent ainsi être distribués accompagnés des dll nécessaires.
Mais c'est encore pire dans notre cas car ces dlls ne peuvent pas être simplement copiées dans le même
répertoire que votre programme, mais doivent être installées de manière particulière
(en tant que shared ou private side-by-side assemblies
ce qui nécessite de créer un installeur de type Windows Installer).
Consultez
Visual C++ Libraries as Shared Side-by-Side Assemblies et
Redistributing Visual C++ Files)
pour plus de détails.
Pour ne pas s'encombrer d'une telle procédure, pouvoir compiler Qt avec l'option -MT se révèle
indispensable.
Modification des options de compilation de Visual C++
Cette option est renseignée au niveau du fichier de configuration qmake.conf qui existe en autant
de version qu'il y a de compilateurs supportés. Dans notre cas, il a été créé par le patch, dans
le répertoire dédié mkspecs (voir la documentation sur
QMAKESPEC)
, c'est à dire précisément C:\qt4\mkspecs\win32-msvc2005\ en ce qui nous concerne.
Ce fichier de configuration définit la variable QMAKE_CFLAGS_RELEASE, qui est utilisée par qmake pour préciser les options de compilation en release au compilateur utilisé, soit Visual C++ 2005 ici. QMAKE_CFLAGS_RELEASE est définie ainsi:
Il suffit donc de modifier -MD en -MT pour pouvoir en théorie compiler avec une utilisation
statique de la CRT.
Tant qu'on y est, on peut aussi spécifier des options supplémentaires, en particulier
-GL
qui active l'optimisation de l'ensemble du programme.
Cette option a un impact sur l'édition de liens (qui est plus longue) et sur le format des fichiers .lib
générés (lire la documentation ainsi que l'article
Les bienfaits de l'option Whole Program Optimisation de Visual C++ .Net
qui traite du sujet).
La nouvelle ligne devient donc:
Normalement, il ne reste plus qu'à tout recompiler pour avoir le résultat attendu.
Modification de qmake
Sauf que la compilation échoue rapidement au niveau de C:\qt4\src\tools\moc\
avec un obscure message d'erreur:
Pour comprendre, il faut savoir qu'une des nouveautés de Visual C++ 2005 concerne
la gestion des manifest, des petits fichiers xml destinés entre autre à gérer
les multiples versions d'une même dll (voir
Understanding Manifest Generation for C/C++ Programs).
Créer le bon manifest est une tâche fastidieuse, mais heureusement rendue transparente par Visual C++
qui se charge de générer le manifest qui convient (voir
Manifest Generation at the Command Line).
Ce manifest est généré par le linker sous forme de fichier séparé en même temps qu'il crée l'exécutable
(ou la dll).
Conformément au principe des manifest, il lui donne le même nom que l'exécutable (ou que la dll) avec l'extension
.manifest en plus (par exemple, VC++ génère pour moc.exe le fichier moc.exe.manifest).
Et il faut bien évidemment redistribuer ce fichier séparé en même temps que son exécutable (ou sa dll).
Avoir ce fichier supplémentaire à livrer avec son programme est contraignant.
C'est pourquoi il est aussi possible d'embarquer le manifest au sein même de l'exécutable
(ou de la dll), dans ses ressources.
C'est précisément le rôle d'un nouvel outil apparu avec Visual C++ 2005 : mt.exe.
Ce petit programme se charge en quelque sorte de fusionner un fichier manifest donné avec
son fichier exécutable (ou autre) associé (voir
How to: Embed a Manifest Inside a C/C++ Application).
Et c'est précisément ce petit programme qui échoue dans notre cas, lors de la
compilation de moc.exe. Pourquoi ? Tout simplement parce que le fichier
manifest qu'on lui demande d'insérer dans moc.exe (qui vient d'être construit
avec succès) n'existe pas.
Et pour cause : comme nous avons compilé moc.exe avec l'option -MT
il n'y en a pas besoin, et Visual C++ ne l'a donc pas créé.
La faute est donc au makefile fourni à nmake.
Ce dernier contient en effet les instructions suivantes en ce qui concerne la
construction de moc.exe:
nmake va ainsi d'abord effectuer l'édition de liens pour créer $(DESTDIR_TARGET)
qui correspond dans notre cas à C:\qt4\bin\moc.exe, puis va appeler mt.exe en lui
demandant d'embarquer le fichier C:\qt4\bin\moc.exe.manifest dans la cible qui vient
d'être construite.
Or, dans notre cas, comme ce fichier n'existe pas, mt.exe ne doit pas être invoqué.
Plutôt que de se référer à la présence ou non de l'option -MT, il est plus simple de réutiliser
le principe présenté dans
How to: Embed a Manifest Inside a C/C++ Application, à savoir d'appeler
mt.exe seulement si le fichier manifest existe.
Si l'on remplace le passage précédent par:
et que l'on relance la compilation (en tapant simplement nmake), la compilation
de moc.exe réussit sans erreur.
Nous avons donc la solution, le problème concerne sa mise en oeuvre, car il faut effectuer
cette modification au niveau de tous les makefiles générés par qmake.
Il est donc préférable de corriger cela directement au niveau de qmake,
ce qui implique de modifier son code source.
Ceci est permis par sa licence GPL, à condition de documenter les changements apportés.
Une rapide investigation dans le répertoire C:\qt4\qmake\ fait apparaître que la ligne
fautive se trouve dans le fichier dédié à la génération des makefiles pour nmake,
soit le fichier C:\qt4\qmake\generators\win32\msvc_nmake.cpp.
En modifiant la ligne 112:
ainsi:
qmake génèrera désormais des makefiles compatibles avec l'option -MT.
Il ne reste plus qu'à tout recompiler, à commencer par qmake. Et pour cela le patch
nous a fourni un makefile spécial, qu'il convient aussi de modifier tant qu'à faire
afin que qmake utilise les mêmes options -MT et -GL.
Il faut donc éditer le fichier C:\qt4\qmake\Makefile.win32-msvc2005 afin de remplacer:
par
et de rajouter devant la ligne
le test
Une fois tout ceci effectué, la compilation en -release -static peut être effectuée
selon les procédures décrites précédemment.
Vous pouvez télécharger les versions complètes modifiées de
msvc_nmake.cpp,
qmake.conf,
et
Makefile.win32-msvc2005,
ou bien utiliser le patch que je vous propose en fin d'article.
Recompilation des bibliothèques tierces
Après tous ces laborieux efforts, on obtient bien de jolis exécutables autonomes. Sauf
si l'on utilise le module QtSql.
Si l'on a compilé le support d'ODBC, on est lié à la dll odbc32.dll, ce qui n'est
pas grave car il s'agit d'une dll système présente sous tous les Windows (au même titre que
kernel32.dll etc...). Par contre, mauvaise nouvelle, si on a compilé avec le support d'une bibliothèque tierce telle que libpq dans mon cas, on peut être dépendant d'une dll (libpq.dll). Cette dll a été installée avec PostgreSQL, et sa version statique n'est pas fournie. Autrement dit, elle doit être distribuée avec votre application.
Pour s'en passer, il faut veiller à linker avec la version statique si vous la posséder,
ou bien dans le cas de PostgreSQL recompiler la bibliothèque libpq afin de l'obtenir.
Je ne peux que vous encourager à le faire, surtout que dans mon cas la dll
installée par défaut (vraisemblablement compilée avec Visual C++ 6) provoquait des
plantages incompréhensibles dans le module QtSql, plantages qui ont disparu après
avoir recompilé la bibliothèque avec Visual C++ 2005.
Je ne détaillerai pas la recompilation de la libpq avec Visual C++ dans cet article.
Reportez vous aux liens donnés sur la documentation de PostgreSQL en fin d'article.
Réalisation d'un paquetage prêt à l'emploi
Pour bien terminer cet article, il serait appréciable de pouvoir faire cohabiter à moindre frais
les versions compilées en debug et release de la bibliothèque.
Souvenez-vous des explications du début sur le rôle de configure au niveau
du code source de la bibliothèque : générer le fichier qconfig.h qui convient.
Mélanger deux compilations différentes de la bibliothèque (une en debug et l'autre en release) revient
donc à fusionner les deux fichiers qconfig.h produits
(dans C:\qt4\src\corelib\global\).
Il suffit pour cela d'isoler le contenu spécifique aux versions debug et release au moyen d'un test sur la macro _DEBUG, comme dans l'exemple suivant:
De cette manière, il est possible de mixer deux compilations différentes de Qt.
C'est ce que j'ai fait dans le but de créer une archive prête à l'emploi. Celle-ci contient:
La version debug inclut aussi les fichiers de débogage .pdb qui permettent de naviguer dans le code
source de la bibliothèque lors d'une session de débogage.
L'ensemble est compressé dans une archive zip de 250 Mo qu'il convient de décompresser
dans le répertoire C:\qt4\ afin que Qt Assistant et Qt Demo localisent
les fichiers dont ils ont besoin (car cet emplacement est codé en dur lors de leur compilation).
A noter que certains exemples de Qt Demo ne fonctionnent pas car ils nécessitent une compilation de Qt sous
forme de dll (pour les plugins notamment)
ou avec le support d'une base de données particulière (SQLite...).
Liens utiles
L'url de la documentation de PostgreSQL évolue constamment à cause du numéro de version
qui est incrémenté fréquemment, ce qui fait que les liens qui vont suivre seront
certainement invalides. Notez donc bien le numéro des chapitres qui sont le
Chapitre 28. libpq - Bibliothèque C en ce qui concerne la libpq et le
Chapitre 15. Installation sur Windows du seul client en ce qui concerne sa compilation
avec Visual C++. Vous pouvez aussi vous tourner vers la documentation originale en anglais dont l'url semble plus stable :
Chapter 28. libpq - C Library et
Chapter 15. Client-Only Installation on Windows.
Si vous n'avez jamais utilisé Visual C++, l'article
Démarrer avec Visual C++ 2005 Express
peut vous aider à débuter. Concernant le fonctionnement de l'option -GL, vous pouvez lire l'article de Gilles Vollant consacré à ce sujet : Les bienfaits de l'option Whole Program Optimisation de Visual C++ .Net.
Si vous souhaitez aussi utiliser Qt 4 avec Dev-C++,
je vous renvoie vers l'article de
Nicolas Joseph :
Installer Qt4 sous Windows.
|
Les sources présentées sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2006-2008 Aurélien Regat-Barrel. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.