Make architecture detection more robust.
[profile/ivi/qtbase.git] / tools / configure / configureapp.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "configureapp.h"
43 #include "environment.h"
44 #ifdef COMMERCIAL_VERSION
45 #  include "tools.h"
46 #endif
47
48 #include <QDate>
49 #include <qdir.h>
50 #include <qtemporaryfile.h>
51 #include <qstack.h>
52 #include <qdebug.h>
53 #include <qfileinfo.h>
54 #include <qtextstream.h>
55 #include <qregexp.h>
56 #include <qhash.h>
57
58 #include <iostream>
59 #include <windows.h>
60 #include <conio.h>
61
62 QT_BEGIN_NAMESPACE
63
64 std::ostream &operator<<(std::ostream &s, const QString &val) {
65     s << val.toLocal8Bit().data();
66     return s;
67 }
68
69
70 using namespace std;
71
72 // Macros to simplify options marking
73 #define MARK_OPTION(x,y) ( dictionary[ #x ] == #y ? "*" : " " )
74
75
76 bool writeToFile(const char* text, const QString &filename)
77 {
78     QByteArray symFile(text);
79     QFile file(filename);
80     QDir dir(QFileInfo(file).absoluteDir());
81     if (!dir.exists())
82         dir.mkpath(dir.absolutePath());
83     if (!file.open(QFile::WriteOnly)) {
84         cout << "Couldn't write to " << qPrintable(filename) << ": " << qPrintable(file.errorString())
85              << endl;
86         return false;
87     }
88     file.write(symFile);
89     return true;
90 }
91
92 Configure::Configure(int& argc, char** argv)
93 {
94     useUnixSeparators = false;
95     // Default values for indentation
96     optionIndent = 4;
97     descIndent   = 25;
98     outputWidth  = 0;
99     // Get console buffer output width
100     CONSOLE_SCREEN_BUFFER_INFO info;
101     HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
102     if (GetConsoleScreenBufferInfo(hStdout, &info))
103         outputWidth = info.dwSize.X - 1;
104     outputWidth = qMin(outputWidth, 79); // Anything wider gets unreadable
105     if (outputWidth < 35) // Insanely small, just use 79
106         outputWidth = 79;
107     int i;
108
109     /*
110     ** Set up the initial state, the default
111     */
112     dictionary[ "CONFIGCMD" ] = argv[ 0 ];
113
114     for (i = 1; i < argc; i++)
115         configCmdLine += argv[ i ];
116
117     if (configCmdLine.size() >= 2 && configCmdLine.at(0) == "-srcdir") {
118         sourcePath = QDir::cleanPath(configCmdLine.at(1));
119         sourceDir = QDir(sourcePath);
120         configCmdLine.erase(configCmdLine.begin(), configCmdLine.begin() + 2);
121     } else {
122         // Get the path to the executable
123         wchar_t module_name[MAX_PATH];
124         GetModuleFileName(0, module_name, sizeof(module_name) / sizeof(wchar_t));
125         QFileInfo sourcePathInfo = QString::fromWCharArray(module_name);
126         sourcePath = sourcePathInfo.absolutePath();
127         sourceDir = sourcePathInfo.dir();
128     }
129     buildPath = QDir::currentPath();
130 #if 0
131     const QString installPath = QString("C:\\Qt\\%1").arg(QT_VERSION_STR);
132 #else
133     const QString installPath = buildPath;
134 #endif
135     if (sourceDir != buildDir) { //shadow builds!
136         if (!findFile("perl") && !findFile("perl.exe")) {
137             cout << "Error: Creating a shadow build of Qt requires" << endl
138                  << "perl to be in the PATH environment";
139             exit(0); // Exit cleanly for Ctrl+C
140         }
141
142         cout << "Preparing build tree..." << endl;
143         QDir(buildPath).mkpath("bin");
144
145         { //make a syncqt script(s) that can be used in the shadow
146             QFile syncqt(buildPath + "/bin/syncqt");
147             if (syncqt.open(QFile::WriteOnly)) {
148                 QTextStream stream(&syncqt);
149                 stream << "#!/usr/bin/perl -w" << endl
150                        << "require \"" << sourcePath + "/bin/syncqt\";" << endl;
151             }
152             QFile syncqt_bat(buildPath + "/bin/syncqt.bat");
153             if (syncqt_bat.open(QFile::WriteOnly)) {
154                 QTextStream stream(&syncqt_bat);
155                 stream << "@echo off" << endl
156                        << "call " << fixSeparators(sourcePath) << fixSeparators("/bin/syncqt.bat -qtdir \"") << fixSeparators(buildPath) << "\" %*" << endl;
157                 syncqt_bat.close();
158             }
159         }
160
161         QFile configtests(buildPath + "/bin/qtmodule-configtests");
162         if (configtests.open(QFile::WriteOnly)) {
163             QTextStream stream(&configtests);
164             stream << "#!/usr/bin/perl -w" << endl
165                    << "require \"" << sourcePath + "/bin/qtmodule-configtests\";" << endl;
166         }
167         // For Windows CE and shadow builds we need to copy these to the
168         // build directory.
169         QFile::copy(sourcePath + "/bin/setcepaths.bat" , buildPath + "/bin/setcepaths.bat");
170         //copy the mkspecs
171         buildDir.mkpath("mkspecs");
172         if (!Environment::cpdir(sourcePath + "/mkspecs", buildPath + "/mkspecs")){
173             cout << "Couldn't copy mkspecs!" << sourcePath << " " << buildPath << endl;
174             dictionary["DONE"] = "error";
175             return;
176         }
177     }
178
179     dictionary[ "QT_SOURCE_TREE" ]    = fixSeparators(sourcePath);
180     dictionary[ "QT_BUILD_TREE" ]     = fixSeparators(buildPath);
181     dictionary[ "QT_INSTALL_PREFIX" ] = fixSeparators(installPath);
182
183     dictionary[ "QMAKESPEC" ] = getenv("QMAKESPEC");
184     if (dictionary[ "QMAKESPEC" ].size() == 0) {
185         dictionary[ "QMAKESPEC" ] = Environment::detectQMakeSpec();
186         dictionary[ "QMAKESPEC_FROM" ] = "detected";
187     } else {
188         dictionary[ "QMAKESPEC_FROM" ] = "env";
189     }
190
191     dictionary[ "QCONFIG" ]         = "full";
192     dictionary[ "EMBEDDED" ]        = "no";
193     dictionary[ "BUILD_QMAKE" ]     = "yes";
194     dictionary[ "DSPFILES" ]        = "yes";
195     dictionary[ "VCPROJFILES" ]     = "yes";
196     dictionary[ "QMAKE_INTERNAL" ]  = "no";
197     dictionary[ "FAST" ]            = "no";
198     dictionary[ "NOPROCESS" ]       = "no";
199     dictionary[ "STL" ]             = "yes";
200     dictionary[ "EXCEPTIONS" ]      = "yes";
201     dictionary[ "WIDGETS" ]         = "yes";
202     dictionary[ "RTTI" ]            = "yes";
203     dictionary[ "MMX" ]             = "auto";
204     dictionary[ "3DNOW" ]           = "auto";
205     dictionary[ "SSE" ]             = "auto";
206     dictionary[ "SSE2" ]            = "auto";
207     dictionary[ "IWMMXT" ]          = "auto";
208     dictionary[ "SYNCQT" ]          = "auto";
209     dictionary[ "CE_CRT" ]          = "no";
210     dictionary[ "CETEST" ]          = "auto";
211     dictionary[ "CE_SIGNATURE" ]    = "no";
212     dictionary[ "PHONON_BACKEND" ]  = "yes";
213     dictionary[ "AUDIO_BACKEND" ]   = "auto";
214     dictionary[ "WMSDK" ]           = "auto";
215     dictionary[ "DIRECTSHOW" ]      = "no";
216     dictionary[ "V8SNAPSHOT" ]      = "auto";
217     dictionary[ "DECLARATIVE_DEBUG" ]= "yes";
218     dictionary[ "PLUGIN_MANIFESTS" ] = "yes";
219     dictionary[ "DIRECTWRITE" ]     = "no";
220
221     QString version;
222     QFile qglobal_h(sourcePath + "/src/corelib/global/qglobal.h");
223     if (qglobal_h.open(QFile::ReadOnly)) {
224         QTextStream read(&qglobal_h);
225         QRegExp version_regexp("^# *define *QT_VERSION_STR *\"([^\"]*)\"");
226         QString line;
227         while (!read.atEnd()) {
228             line = read.readLine();
229             if (version_regexp.exactMatch(line)) {
230                 version = version_regexp.cap(1).trimmed();
231                 if (!version.isEmpty())
232                     break;
233             }
234         }
235         qglobal_h.close();
236     }
237
238     if (version.isEmpty())
239         version = QString("%1.%2.%3").arg(QT_VERSION>>16).arg(((QT_VERSION>>8)&0xff)).arg(QT_VERSION&0xff);
240
241     dictionary[ "VERSION" ]         = version;
242     {
243         QRegExp version_re("([0-9]*)\\.([0-9]*)\\.([0-9]*)(|-.*)");
244         if (version_re.exactMatch(version)) {
245             dictionary[ "VERSION_MAJOR" ] = version_re.cap(1);
246             dictionary[ "VERSION_MINOR" ] = version_re.cap(2);
247             dictionary[ "VERSION_PATCH" ] = version_re.cap(3);
248         }
249     }
250
251     dictionary[ "REDO" ]            = "no";
252     dictionary[ "DEPENDENCIES" ]    = "no";
253
254     dictionary[ "BUILD" ]           = "debug";
255     dictionary[ "BUILDALL" ]        = "auto"; // Means yes, but not explicitly
256
257     dictionary[ "BUILDTYPE" ]      = "none";
258
259     dictionary[ "BUILDDEV" ]        = "no";
260
261     dictionary[ "SHARED" ]          = "yes";
262
263     dictionary[ "ZLIB" ]            = "auto";
264
265     dictionary[ "PCRE" ]            = "auto";
266
267     dictionary[ "ICU" ]             = "auto";
268
269     dictionary[ "GIF" ]             = "auto";
270     dictionary[ "JPEG" ]            = "auto";
271     dictionary[ "PNG" ]             = "auto";
272     dictionary[ "LIBJPEG" ]         = "auto";
273     dictionary[ "LIBPNG" ]          = "auto";
274     dictionary[ "FREETYPE" ]        = "yes";
275
276     dictionary[ "ACCESSIBILITY" ]   = "yes";
277     dictionary[ "OPENGL" ]          = "yes";
278     dictionary[ "OPENVG" ]          = "no";
279     dictionary[ "OPENSSL" ]         = "auto";
280     dictionary[ "DBUS" ]            = "auto";
281
282     dictionary[ "STYLE_WINDOWS" ]   = "yes";
283     dictionary[ "STYLE_WINDOWSXP" ] = "auto";
284     dictionary[ "STYLE_WINDOWSVISTA" ] = "auto";
285     dictionary[ "STYLE_PLASTIQUE" ] = "yes";
286     dictionary[ "STYLE_CLEANLOOKS" ]= "yes";
287     dictionary[ "STYLE_WINDOWSCE" ] = "no";
288     dictionary[ "STYLE_WINDOWSMOBILE" ] = "no";
289     dictionary[ "STYLE_MOTIF" ]     = "yes";
290     dictionary[ "STYLE_CDE" ]       = "yes";
291     dictionary[ "STYLE_GTK" ]       = "no";
292
293     dictionary[ "SQL_MYSQL" ]       = "no";
294     dictionary[ "SQL_ODBC" ]        = "no";
295     dictionary[ "SQL_OCI" ]         = "no";
296     dictionary[ "SQL_PSQL" ]        = "no";
297     dictionary[ "SQL_TDS" ]         = "no";
298     dictionary[ "SQL_DB2" ]         = "no";
299     dictionary[ "SQL_SQLITE" ]      = "auto";
300     dictionary[ "SQL_SQLITE_LIB" ]  = "qt";
301     dictionary[ "SQL_SQLITE2" ]     = "no";
302     dictionary[ "SQL_IBASE" ]       = "no";
303
304     QString tmp = dictionary[ "QMAKESPEC" ];
305     if (tmp.contains("\\")) {
306         tmp = tmp.mid(tmp.lastIndexOf("\\") + 1);
307     } else {
308         tmp = tmp.mid(tmp.lastIndexOf("/") + 1);
309     }
310     dictionary[ "QMAKESPEC" ] = tmp;
311
312     dictionary[ "INCREDIBUILD_XGE" ] = "auto";
313     dictionary[ "LTCG" ]            = "no";
314     dictionary[ "NATIVE_GESTURES" ] = "yes";
315     dictionary[ "MSVC_MP" ] = "no";
316 }
317
318 Configure::~Configure()
319 {
320     for (int i=0; i<3; ++i) {
321         QList<MakeItem*> items = makeList[i];
322         for (int j=0; j<items.size(); ++j)
323             delete items[j];
324     }
325 }
326
327 QString Configure::fixSeparators(const QString &somePath, bool escape)
328 {
329     if (useUnixSeparators)
330         return QDir::fromNativeSeparators(somePath);
331     QString ret = QDir::toNativeSeparators(somePath);
332     return escape ? escapeSeparators(ret) : ret;
333 }
334
335 QString Configure::escapeSeparators(const QString &somePath)
336 {
337     QString out = somePath;
338     out.replace(QLatin1Char('\\'), QLatin1String("\\\\"));
339     return out;
340 }
341
342 // We could use QDir::homePath() + "/.qt-license", but
343 // that will only look in the first of $HOME,$USERPROFILE
344 // or $HOMEDRIVE$HOMEPATH. So, here we try'em all to be
345 // more forgiving for the end user..
346 QString Configure::firstLicensePath()
347 {
348     QStringList allPaths;
349     allPaths << "./.qt-license"
350              << QString::fromLocal8Bit(getenv("HOME")) + "/.qt-license"
351              << QString::fromLocal8Bit(getenv("USERPROFILE")) + "/.qt-license"
352              << QString::fromLocal8Bit(getenv("HOMEDRIVE")) + QString::fromLocal8Bit(getenv("HOMEPATH")) + "/.qt-license";
353     for (int i = 0; i< allPaths.count(); ++i)
354         if (QFile::exists(allPaths.at(i)))
355             return allPaths.at(i);
356     return QString();
357 }
358
359
360 // #### somehow I get a compiler error about vc++ reaching the nesting limit without
361 // undefining the ansi for scoping.
362 #ifdef for
363 #undef for
364 #endif
365
366 void Configure::parseCmdLine()
367 {
368     int argCount = configCmdLine.size();
369     int i = 0;
370     const QStringList imageFormats = QStringList() << "gif" << "png" << "jpeg";
371
372 #if !defined(EVAL)
373     if (argCount < 1) // skip rest if no arguments
374         ;
375     else if (configCmdLine.at(i) == "-redo") {
376         dictionary[ "REDO" ] = "yes";
377         configCmdLine.clear();
378         reloadCmdLine();
379     }
380     else if (configCmdLine.at(i) == "-loadconfig") {
381         ++i;
382         if (i != argCount) {
383             dictionary[ "REDO" ] = "yes";
384             dictionary[ "CUSTOMCONFIG" ] = "_" + configCmdLine.at(i);
385             configCmdLine.clear();
386             reloadCmdLine();
387         } else {
388             dictionary[ "HELP" ] = "yes";
389         }
390         i = 0;
391     }
392     argCount = configCmdLine.size();
393 #endif
394
395     // Look first for XQMAKESPEC
396     for (int j = 0 ; j < argCount; ++j)
397     {
398         if (configCmdLine.at(j) == "-xplatform") {
399             ++j;
400             if (j == argCount)
401                 break;
402             dictionary["XQMAKESPEC"] = configCmdLine.at(j);
403             if (!dictionary[ "XQMAKESPEC" ].isEmpty())
404                 applySpecSpecifics();
405         }
406     }
407
408     for (; i<configCmdLine.size(); ++i) {
409         bool continueElse[] = {false, false};
410         if (configCmdLine.at(i) == "-help"
411             || configCmdLine.at(i) == "-h"
412             || configCmdLine.at(i) == "-?")
413             dictionary[ "HELP" ] = "yes";
414
415 #if !defined(EVAL)
416         else if (configCmdLine.at(i) == "-qconfig") {
417             ++i;
418             if (i == argCount)
419                 break;
420             dictionary[ "QCONFIG" ] = configCmdLine.at(i);
421         }
422
423         else if (configCmdLine.at(i) == "-release") {
424             dictionary[ "BUILD" ] = "release";
425             if (dictionary[ "BUILDALL" ] == "auto")
426                 dictionary[ "BUILDALL" ] = "no";
427         } else if (configCmdLine.at(i) == "-debug") {
428             dictionary[ "BUILD" ] = "debug";
429             if (dictionary[ "BUILDALL" ] == "auto")
430                 dictionary[ "BUILDALL" ] = "no";
431         } else if (configCmdLine.at(i) == "-debug-and-release")
432             dictionary[ "BUILDALL" ] = "yes";
433
434         else if (configCmdLine.at(i) == "-shared")
435             dictionary[ "SHARED" ] = "yes";
436         else if (configCmdLine.at(i) == "-static")
437             dictionary[ "SHARED" ] = "no";
438         else if (configCmdLine.at(i) == "-developer-build")
439             dictionary[ "BUILDDEV" ] = "yes";
440         else if (configCmdLine.at(i) == "-opensource") {
441             dictionary[ "BUILDTYPE" ] = "opensource";
442         }
443         else if (configCmdLine.at(i) == "-commercial") {
444             dictionary[ "BUILDTYPE" ] = "commercial";
445         }
446         else if (configCmdLine.at(i) == "-ltcg") {
447             dictionary[ "LTCG" ] = "yes";
448         }
449         else if (configCmdLine.at(i) == "-no-ltcg") {
450             dictionary[ "LTCG" ] = "no";
451         }
452         else if (configCmdLine.at(i) == "-mp") {
453             dictionary[ "MSVC_MP" ] = "yes";
454         }
455         else if (configCmdLine.at(i) == "-no-mp") {
456             dictionary[ "MSVC_MP" ] = "no";
457         }
458         else if (configCmdLine.at(i) == "-force-asserts") {
459             dictionary[ "FORCE_ASSERTS" ] = "yes";
460         }
461
462
463 #endif
464
465         else if (configCmdLine.at(i) == "-platform") {
466             ++i;
467             if (i == argCount)
468                 break;
469             dictionary[ "QMAKESPEC" ] = configCmdLine.at(i);
470         dictionary[ "QMAKESPEC_FROM" ] = "commandline";
471         } else if (configCmdLine.at(i) == "-arch") {
472             ++i;
473             if (i == argCount)
474                 break;
475             dictionary["OBSOLETE_ARCH_ARG"] = "yes";
476         } else if (configCmdLine.at(i) == "-embedded") {
477             dictionary[ "EMBEDDED" ] = "yes";
478         } else if (configCmdLine.at(i) == "-xplatform") {
479             ++i;
480             // do nothing
481         }
482
483
484 #if !defined(EVAL)
485         else if (configCmdLine.at(i) == "-no-zlib") {
486             // No longer supported since Qt 4.4.0
487             // But save the information for later so that we can print a warning
488             //
489             // If you REALLY really need no zlib support, you can still disable
490             // it by doing the following:
491             //   add "no-zlib" to mkspecs/qconfig.pri
492             //   #define QT_NO_COMPRESS (probably by adding to src/corelib/global/qconfig.h)
493             //
494             // There's no guarantee that Qt will build under those conditions
495
496             dictionary[ "ZLIB_FORCED" ] = "yes";
497         } else if (configCmdLine.at(i) == "-qt-zlib") {
498             dictionary[ "ZLIB" ] = "qt";
499         } else if (configCmdLine.at(i) == "-system-zlib") {
500             dictionary[ "ZLIB" ] = "system";
501         }
502
503         else if (configCmdLine.at(i) == "-qt-pcre") {
504             dictionary[ "PCRE" ] = "qt";
505         } else if (configCmdLine.at(i) == "-system-pcre") {
506             dictionary[ "PCRE" ] = "system";
507         }
508
509         else if (configCmdLine.at(i) == "-icu") {
510             dictionary[ "ICU" ] = "yes";
511         } else if (configCmdLine.at(i) == "-no-icu") {
512             dictionary[ "ICU" ] = "no";
513         }
514
515         // Image formats --------------------------------------------
516         else if (configCmdLine.at(i) == "-no-gif")
517             dictionary[ "GIF" ] = "no";
518
519         else if (configCmdLine.at(i) == "-no-libjpeg") {
520             dictionary[ "JPEG" ] = "no";
521             dictionary[ "LIBJPEG" ] = "no";
522         } else if (configCmdLine.at(i) == "-qt-libjpeg") {
523             dictionary[ "LIBJPEG" ] = "qt";
524         } else if (configCmdLine.at(i) == "-system-libjpeg") {
525             dictionary[ "LIBJPEG" ] = "system";
526         }
527
528         else if (configCmdLine.at(i) == "-no-libpng") {
529             dictionary[ "PNG" ] = "no";
530             dictionary[ "LIBPNG" ] = "no";
531         } else if (configCmdLine.at(i) == "-qt-libpng") {
532             dictionary[ "LIBPNG" ] = "qt";
533         } else if (configCmdLine.at(i) == "-system-libpng") {
534             dictionary[ "LIBPNG" ] = "system";
535         }
536
537         // Text Rendering --------------------------------------------
538         else if (configCmdLine.at(i) == "-no-freetype")
539             dictionary[ "FREETYPE" ] = "no";
540         else if (configCmdLine.at(i) == "-qt-freetype")
541             dictionary[ "FREETYPE" ] = "yes";
542
543         // CE- C runtime --------------------------------------------
544         else if (configCmdLine.at(i) == "-crt") {
545             ++i;
546             if (i == argCount)
547                 break;
548             QDir cDir(configCmdLine.at(i));
549             if (!cDir.exists())
550                 cout << "WARNING: Could not find directory (" << qPrintable(configCmdLine.at(i)) << ")for C runtime deployment" << endl;
551             else
552                 dictionary[ "CE_CRT" ] = QDir::toNativeSeparators(cDir.absolutePath());
553         } else if (configCmdLine.at(i) == "-qt-crt") {
554             dictionary[ "CE_CRT" ] = "yes";
555         } else if (configCmdLine.at(i) == "-no-crt") {
556             dictionary[ "CE_CRT" ] = "no";
557         }
558         // cetest ---------------------------------------------------
559         else if (configCmdLine.at(i) == "-no-cetest") {
560             dictionary[ "CETEST" ] = "no";
561             dictionary[ "CETEST_REQUESTED" ] = "no";
562         } else if (configCmdLine.at(i) == "-cetest") {
563             // although specified to use it, we stay at "auto" state
564             // this is because checkAvailability() adds variables
565             // we need for crosscompilation; but remember if we asked
566             // for it.
567             dictionary[ "CETEST_REQUESTED" ] = "yes";
568         }
569         // Qt/CE - signing tool -------------------------------------
570         else if (configCmdLine.at(i) == "-signature") {
571             ++i;
572             if (i == argCount)
573                 break;
574             QFileInfo info(configCmdLine.at(i));
575             if (!info.exists())
576                 cout << "WARNING: Could not find signature file (" << qPrintable(configCmdLine.at(i)) << ")" << endl;
577             else
578                 dictionary[ "CE_SIGNATURE" ] = QDir::toNativeSeparators(info.absoluteFilePath());
579         }
580         // Styles ---------------------------------------------------
581         else if (configCmdLine.at(i) == "-qt-style-windows")
582             dictionary[ "STYLE_WINDOWS" ] = "yes";
583         else if (configCmdLine.at(i) == "-no-style-windows")
584             dictionary[ "STYLE_WINDOWS" ] = "no";
585
586         else if (configCmdLine.at(i) == "-qt-style-windowsce")
587             dictionary[ "STYLE_WINDOWSCE" ] = "yes";
588         else if (configCmdLine.at(i) == "-no-style-windowsce")
589             dictionary[ "STYLE_WINDOWSCE" ] = "no";
590         else if (configCmdLine.at(i) == "-qt-style-windowsmobile")
591             dictionary[ "STYLE_WINDOWSMOBILE" ] = "yes";
592         else if (configCmdLine.at(i) == "-no-style-windowsmobile")
593             dictionary[ "STYLE_WINDOWSMOBILE" ] = "no";
594
595         else if (configCmdLine.at(i) == "-qt-style-windowsxp")
596             dictionary[ "STYLE_WINDOWSXP" ] = "yes";
597         else if (configCmdLine.at(i) == "-no-style-windowsxp")
598             dictionary[ "STYLE_WINDOWSXP" ] = "no";
599
600         else if (configCmdLine.at(i) == "-qt-style-windowsvista")
601             dictionary[ "STYLE_WINDOWSVISTA" ] = "yes";
602         else if (configCmdLine.at(i) == "-no-style-windowsvista")
603             dictionary[ "STYLE_WINDOWSVISTA" ] = "no";
604
605         else if (configCmdLine.at(i) == "-qt-style-plastique")
606             dictionary[ "STYLE_PLASTIQUE" ] = "yes";
607         else if (configCmdLine.at(i) == "-no-style-plastique")
608             dictionary[ "STYLE_PLASTIQUE" ] = "no";
609
610         else if (configCmdLine.at(i) == "-qt-style-cleanlooks")
611             dictionary[ "STYLE_CLEANLOOKS" ] = "yes";
612         else if (configCmdLine.at(i) == "-no-style-cleanlooks")
613             dictionary[ "STYLE_CLEANLOOKS" ] = "no";
614
615         else if (configCmdLine.at(i) == "-qt-style-motif")
616             dictionary[ "STYLE_MOTIF" ] = "yes";
617         else if (configCmdLine.at(i) == "-no-style-motif")
618             dictionary[ "STYLE_MOTIF" ] = "no";
619
620         else if (configCmdLine.at(i) == "-qt-style-cde")
621             dictionary[ "STYLE_CDE" ] = "yes";
622         else if (configCmdLine.at(i) == "-no-style-cde")
623             dictionary[ "STYLE_CDE" ] = "no";
624
625         // Work around compiler nesting limitation
626         else
627             continueElse[1] = true;
628         if (!continueElse[1]) {
629         }
630
631         // OpenGL Support -------------------------------------------
632         else if (configCmdLine.at(i) == "-no-opengl") {
633             dictionary[ "OPENGL" ]    = "no";
634         } else if (configCmdLine.at(i) == "-opengl-es-cm") {
635             dictionary[ "OPENGL" ]          = "yes";
636             dictionary[ "OPENGL_ES_CM" ]    = "yes";
637         } else if (configCmdLine.at(i) == "-opengl-es-2") {
638             dictionary[ "OPENGL" ]          = "yes";
639             dictionary[ "OPENGL_ES_2" ]     = "yes";
640         } else if (configCmdLine.at(i) == "-opengl") {
641             dictionary[ "OPENGL" ]          = "yes";
642             i++;
643             if (i == argCount)
644                 break;
645
646             if (configCmdLine.at(i) == "es1") {
647                 dictionary[ "OPENGL_ES_CM" ]    = "yes";
648             } else if ( configCmdLine.at(i) == "es2" ) {
649                 dictionary[ "OPENGL_ES_2" ]     = "yes";
650             } else if ( configCmdLine.at(i) == "desktop" ) {
651                 // OPENGL=yes suffices
652             } else {
653                 cout << "Argument passed to -opengl option is not valid." << endl;
654                 dictionary[ "DONE" ] = "error";
655                 break;
656             }
657         }
658
659         // OpenVG Support -------------------------------------------
660         else if (configCmdLine.at(i) == "-openvg") {
661             dictionary[ "OPENVG" ]    = "yes";
662         } else if (configCmdLine.at(i) == "-no-openvg") {
663             dictionary[ "OPENVG" ]    = "no";
664         }
665
666         // Databases ------------------------------------------------
667         else if (configCmdLine.at(i) == "-qt-sql-mysql")
668             dictionary[ "SQL_MYSQL" ] = "yes";
669         else if (configCmdLine.at(i) == "-plugin-sql-mysql")
670             dictionary[ "SQL_MYSQL" ] = "plugin";
671         else if (configCmdLine.at(i) == "-no-sql-mysql")
672             dictionary[ "SQL_MYSQL" ] = "no";
673
674         else if (configCmdLine.at(i) == "-qt-sql-odbc")
675             dictionary[ "SQL_ODBC" ] = "yes";
676         else if (configCmdLine.at(i) == "-plugin-sql-odbc")
677             dictionary[ "SQL_ODBC" ] = "plugin";
678         else if (configCmdLine.at(i) == "-no-sql-odbc")
679             dictionary[ "SQL_ODBC" ] = "no";
680
681         else if (configCmdLine.at(i) == "-qt-sql-oci")
682             dictionary[ "SQL_OCI" ] = "yes";
683         else if (configCmdLine.at(i) == "-plugin-sql-oci")
684             dictionary[ "SQL_OCI" ] = "plugin";
685         else if (configCmdLine.at(i) == "-no-sql-oci")
686             dictionary[ "SQL_OCI" ] = "no";
687
688         else if (configCmdLine.at(i) == "-qt-sql-psql")
689             dictionary[ "SQL_PSQL" ] = "yes";
690         else if (configCmdLine.at(i) == "-plugin-sql-psql")
691             dictionary[ "SQL_PSQL" ] = "plugin";
692         else if (configCmdLine.at(i) == "-no-sql-psql")
693             dictionary[ "SQL_PSQL" ] = "no";
694
695         else if (configCmdLine.at(i) == "-qt-sql-tds")
696             dictionary[ "SQL_TDS" ] = "yes";
697         else if (configCmdLine.at(i) == "-plugin-sql-tds")
698             dictionary[ "SQL_TDS" ] = "plugin";
699         else if (configCmdLine.at(i) == "-no-sql-tds")
700             dictionary[ "SQL_TDS" ] = "no";
701
702         else if (configCmdLine.at(i) == "-qt-sql-db2")
703             dictionary[ "SQL_DB2" ] = "yes";
704         else if (configCmdLine.at(i) == "-plugin-sql-db2")
705             dictionary[ "SQL_DB2" ] = "plugin";
706         else if (configCmdLine.at(i) == "-no-sql-db2")
707             dictionary[ "SQL_DB2" ] = "no";
708
709         else if (configCmdLine.at(i) == "-qt-sql-sqlite")
710             dictionary[ "SQL_SQLITE" ] = "yes";
711         else if (configCmdLine.at(i) == "-plugin-sql-sqlite")
712             dictionary[ "SQL_SQLITE" ] = "plugin";
713         else if (configCmdLine.at(i) == "-no-sql-sqlite")
714             dictionary[ "SQL_SQLITE" ] = "no";
715         else if (configCmdLine.at(i) == "-system-sqlite")
716             dictionary[ "SQL_SQLITE_LIB" ] = "system";
717         else if (configCmdLine.at(i) == "-qt-sql-sqlite2")
718             dictionary[ "SQL_SQLITE2" ] = "yes";
719         else if (configCmdLine.at(i) == "-plugin-sql-sqlite2")
720             dictionary[ "SQL_SQLITE2" ] = "plugin";
721         else if (configCmdLine.at(i) == "-no-sql-sqlite2")
722             dictionary[ "SQL_SQLITE2" ] = "no";
723
724         else if (configCmdLine.at(i) == "-qt-sql-ibase")
725             dictionary[ "SQL_IBASE" ] = "yes";
726         else if (configCmdLine.at(i) == "-plugin-sql-ibase")
727             dictionary[ "SQL_IBASE" ] = "plugin";
728         else if (configCmdLine.at(i) == "-no-sql-ibase")
729             dictionary[ "SQL_IBASE" ] = "no";
730
731         // Image formats --------------------------------------------
732         else if (configCmdLine.at(i).startsWith("-qt-imageformat-") &&
733                  imageFormats.contains(configCmdLine.at(i).section('-', 3)))
734             dictionary[ configCmdLine.at(i).section('-', 3).toUpper() ] = "yes";
735         else if (configCmdLine.at(i).startsWith("-plugin-imageformat-") &&
736                  imageFormats.contains(configCmdLine.at(i).section('-', 3)))
737             dictionary[ configCmdLine.at(i).section('-', 3).toUpper() ] = "plugin";
738         else if (configCmdLine.at(i).startsWith("-no-imageformat-") &&
739                  imageFormats.contains(configCmdLine.at(i).section('-', 3)))
740             dictionary[ configCmdLine.at(i).section('-', 3).toUpper() ] = "no";
741 #endif
742         // IDE project generation -----------------------------------
743         else if (configCmdLine.at(i) == "-no-dsp")
744             dictionary[ "DSPFILES" ] = "no";
745         else if (configCmdLine.at(i) == "-dsp")
746             dictionary[ "DSPFILES" ] = "yes";
747
748         else if (configCmdLine.at(i) == "-no-vcp")
749             dictionary[ "VCPFILES" ] = "no";
750         else if (configCmdLine.at(i) == "-vcp")
751             dictionary[ "VCPFILES" ] = "yes";
752
753         else if (configCmdLine.at(i) == "-no-vcproj")
754             dictionary[ "VCPROJFILES" ] = "no";
755         else if (configCmdLine.at(i) == "-vcproj")
756             dictionary[ "VCPROJFILES" ] = "yes";
757
758         else if (configCmdLine.at(i) == "-no-incredibuild-xge")
759             dictionary[ "INCREDIBUILD_XGE" ] = "no";
760         else if (configCmdLine.at(i) == "-incredibuild-xge")
761             dictionary[ "INCREDIBUILD_XGE" ] = "yes";
762         else if (configCmdLine.at(i) == "-native-gestures")
763             dictionary[ "NATIVE_GESTURES" ] = "yes";
764         else if (configCmdLine.at(i) == "-no-native-gestures")
765             dictionary[ "NATIVE_GESTURES" ] = "no";
766 #if !defined(EVAL)
767         // Others ---------------------------------------------------
768         else if (configCmdLine.at(i) == "-fast")
769             dictionary[ "FAST" ] = "yes";
770         else if (configCmdLine.at(i) == "-no-fast")
771             dictionary[ "FAST" ] = "no";
772
773         else if (configCmdLine.at(i) == "-stl")
774             dictionary[ "STL" ] = "yes";
775         else if (configCmdLine.at(i) == "-no-stl")
776             dictionary[ "STL" ] = "no";
777
778         else if (configCmdLine.at(i) == "-exceptions")
779             dictionary[ "EXCEPTIONS" ] = "yes";
780         else if (configCmdLine.at(i) == "-no-exceptions")
781             dictionary[ "EXCEPTIONS" ] = "no";
782
783         else if (configCmdLine.at(i) == "-widgets")
784             dictionary[ "WIDGETS" ] = "yes";
785         else if (configCmdLine.at(i) == "-no-widgets")
786             dictionary[ "WIDGETS" ] = "no";
787
788         else if (configCmdLine.at(i) == "-rtti")
789             dictionary[ "RTTI" ] = "yes";
790         else if (configCmdLine.at(i) == "-no-rtti")
791             dictionary[ "RTTI" ] = "no";
792
793         else if (configCmdLine.at(i) == "-accessibility")
794             dictionary[ "ACCESSIBILITY" ] = "yes";
795         else if (configCmdLine.at(i) == "-no-accessibility") {
796             dictionary[ "ACCESSIBILITY" ] = "no";
797             cout << "Setting accessibility to NO" << endl;
798         }
799
800         else if (configCmdLine.at(i) == "-no-mmx")
801             dictionary[ "MMX" ] = "no";
802         else if (configCmdLine.at(i) == "-mmx")
803             dictionary[ "MMX" ] = "yes";
804         else if (configCmdLine.at(i) == "-no-3dnow")
805             dictionary[ "3DNOW" ] = "no";
806         else if (configCmdLine.at(i) == "-3dnow")
807             dictionary[ "3DNOW" ] = "yes";
808         else if (configCmdLine.at(i) == "-no-sse")
809             dictionary[ "SSE" ] = "no";
810         else if (configCmdLine.at(i) == "-sse")
811             dictionary[ "SSE" ] = "yes";
812         else if (configCmdLine.at(i) == "-no-sse2")
813             dictionary[ "SSE2" ] = "no";
814         else if (configCmdLine.at(i) == "-sse2")
815             dictionary[ "SSE2" ] = "yes";
816         else if (configCmdLine.at(i) == "-no-iwmmxt")
817             dictionary[ "IWMMXT" ] = "no";
818         else if (configCmdLine.at(i) == "-iwmmxt")
819             dictionary[ "IWMMXT" ] = "yes";
820
821         else if (configCmdLine.at(i) == "-no-openssl") {
822               dictionary[ "OPENSSL"] = "no";
823         } else if (configCmdLine.at(i) == "-openssl") {
824               dictionary[ "OPENSSL" ] = "yes";
825         } else if (configCmdLine.at(i) == "-openssl-linked") {
826               dictionary[ "OPENSSL" ] = "linked";
827         } else if (configCmdLine.at(i) == "-no-qdbus") {
828             dictionary[ "DBUS" ] = "no";
829         } else if (configCmdLine.at(i) == "-qdbus") {
830             dictionary[ "DBUS" ] = "yes";
831         } else if (configCmdLine.at(i) == "-no-dbus") {
832             dictionary[ "DBUS" ] = "no";
833         } else if (configCmdLine.at(i) == "-dbus") {
834             dictionary[ "DBUS" ] = "yes";
835         } else if (configCmdLine.at(i) == "-dbus-linked") {
836             dictionary[ "DBUS" ] = "linked";
837         } else if (configCmdLine.at(i) == "-audio-backend") {
838             dictionary[ "AUDIO_BACKEND" ] = "yes";
839         } else if (configCmdLine.at(i) == "-no-audio-backend") {
840             dictionary[ "AUDIO_BACKEND" ] = "no";
841         } else if (configCmdLine.at(i) == "-no-phonon-backend") {
842             dictionary[ "PHONON_BACKEND" ] = "no";
843         } else if (configCmdLine.at(i) == "-phonon-backend") {
844             dictionary[ "PHONON_BACKEND" ] = "yes";
845         } else if (configCmdLine.at(i) == "-phonon-wince-ds9") {
846             dictionary[ "DIRECTSHOW" ] = "yes";
847         } else if (configCmdLine.at(i) == "-no-declarative-debug") {
848             dictionary[ "DECLARATIVE_DEBUG" ] = "no";
849         } else if (configCmdLine.at(i) == "-declarative-debug") {
850             dictionary[ "DECLARATIVE_DEBUG" ] = "yes";
851         } else if (configCmdLine.at(i) == "-no-plugin-manifests") {
852             dictionary[ "PLUGIN_MANIFESTS" ] = "no";
853         } else if (configCmdLine.at(i) == "-plugin-manifests") {
854             dictionary[ "PLUGIN_MANIFESTS" ] = "yes";
855         }
856
857         // Work around compiler nesting limitation
858         else
859             continueElse[0] = true;
860         if (!continueElse[0]) {
861         }
862
863         else if (configCmdLine.at(i) == "-internal")
864             dictionary[ "QMAKE_INTERNAL" ] = "yes";
865
866         else if (configCmdLine.at(i) == "-no-syncqt")
867             dictionary[ "SYNCQT" ] = "no";
868
869         else if (configCmdLine.at(i) == "-no-qmake")
870             dictionary[ "BUILD_QMAKE" ] = "no";
871         else if (configCmdLine.at(i) == "-qmake")
872             dictionary[ "BUILD_QMAKE" ] = "yes";
873
874         else if (configCmdLine.at(i) == "-dont-process")
875             dictionary[ "NOPROCESS" ] = "yes";
876         else if (configCmdLine.at(i) == "-process")
877             dictionary[ "NOPROCESS" ] = "no";
878
879         else if (configCmdLine.at(i) == "-no-qmake-deps")
880             dictionary[ "DEPENDENCIES" ] = "no";
881         else if (configCmdLine.at(i) == "-qmake-deps")
882             dictionary[ "DEPENDENCIES" ] = "yes";
883
884
885         else if (configCmdLine.at(i) == "-qtnamespace") {
886             ++i;
887             if (i == argCount)
888                 break;
889             dictionary[ "QT_NAMESPACE" ] = configCmdLine.at(i);
890         } else if (configCmdLine.at(i) == "-qtlibinfix") {
891             ++i;
892             if (i == argCount)
893                 break;
894             dictionary[ "QT_LIBINFIX" ] = configCmdLine.at(i);
895         } else if (configCmdLine.at(i) == "-D") {
896             ++i;
897             if (i == argCount)
898                 break;
899             qmakeDefines += configCmdLine.at(i);
900         } else if (configCmdLine.at(i) == "-I") {
901             ++i;
902             if (i == argCount)
903                 break;
904             qmakeIncludes += configCmdLine.at(i);
905         } else if (configCmdLine.at(i) == "-L") {
906             ++i;
907             if (i == argCount)
908                 break;
909             QFileInfo checkDirectory(configCmdLine.at(i));
910             if (!checkDirectory.isDir()) {
911                 cout << "Argument passed to -L option is not a directory path. Did you mean the -l option?" << endl;
912                 dictionary[ "DONE" ] = "error";
913                 break;
914             }
915             qmakeLibs += QString("-L" + configCmdLine.at(i));
916         } else if (configCmdLine.at(i) == "-l") {
917             ++i;
918             if (i == argCount)
919                 break;
920             qmakeLibs += QString("-l" + configCmdLine.at(i));
921         } else if (configCmdLine.at(i).startsWith("OPENSSL_LIBS=")) {
922             opensslLibs = configCmdLine.at(i);
923         } else if (configCmdLine.at(i).startsWith("PSQL_LIBS=")) {
924             psqlLibs = configCmdLine.at(i);
925         } else if (configCmdLine.at(i).startsWith("SYBASE=")) {
926             sybase = configCmdLine.at(i);
927         } else if (configCmdLine.at(i).startsWith("SYBASE_LIBS=")) {
928             sybaseLibs = configCmdLine.at(i);
929         } else if (configCmdLine.at(i) == "-qpa") {
930             dictionary["QPA"] = "yes";
931         }
932
933         else if ((configCmdLine.at(i) == "-override-version") || (configCmdLine.at(i) == "-version-override")){
934             ++i;
935             if (i == argCount)
936                 break;
937             dictionary[ "VERSION" ] = configCmdLine.at(i);
938         }
939
940         else if (configCmdLine.at(i) == "-saveconfig") {
941             ++i;
942             if (i == argCount)
943                 break;
944             dictionary[ "CUSTOMCONFIG" ] = "_" + configCmdLine.at(i);
945         }
946
947         else if (configCmdLine.at(i) == "-confirm-license") {
948             dictionary["LICENSE_CONFIRMED"] = "yes";
949         }
950
951         else if (configCmdLine.at(i) == "-nomake") {
952             ++i;
953             if (i == argCount)
954                 break;
955             disabledBuildParts += configCmdLine.at(i);
956         }
957
958         // Directories ----------------------------------------------
959         else if (configCmdLine.at(i) == "-prefix") {
960             ++i;
961             if (i == argCount)
962                 break;
963             dictionary[ "QT_INSTALL_PREFIX" ] = configCmdLine.at(i);
964         }
965
966         else if (configCmdLine.at(i) == "-bindir") {
967             ++i;
968             if (i == argCount)
969                 break;
970             dictionary[ "QT_INSTALL_BINS" ] = configCmdLine.at(i);
971         }
972
973         else if (configCmdLine.at(i) == "-libdir") {
974             ++i;
975             if (i == argCount)
976                 break;
977             dictionary[ "QT_INSTALL_LIBS" ] = configCmdLine.at(i);
978         }
979
980         else if (configCmdLine.at(i) == "-docdir") {
981             ++i;
982             if (i == argCount)
983                 break;
984             dictionary[ "QT_INSTALL_DOCS" ] = configCmdLine.at(i);
985         }
986
987         else if (configCmdLine.at(i) == "-headerdir") {
988             ++i;
989             if (i == argCount)
990                 break;
991             dictionary[ "QT_INSTALL_HEADERS" ] = configCmdLine.at(i);
992         }
993
994         else if (configCmdLine.at(i) == "-plugindir") {
995             ++i;
996             if (i == argCount)
997                 break;
998             dictionary[ "QT_INSTALL_PLUGINS" ] = configCmdLine.at(i);
999         }
1000
1001         else if (configCmdLine.at(i) == "-importdir") {
1002             ++i;
1003             if (i == argCount)
1004                 break;
1005             dictionary[ "QT_INSTALL_IMPORTS" ] = configCmdLine.at(i);
1006         }
1007         else if (configCmdLine.at(i) == "-datadir") {
1008             ++i;
1009             if (i == argCount)
1010                 break;
1011             dictionary[ "QT_INSTALL_DATA" ] = configCmdLine.at(i);
1012         }
1013
1014         else if (configCmdLine.at(i) == "-translationdir") {
1015             ++i;
1016             if (i == argCount)
1017                 break;
1018             dictionary[ "QT_INSTALL_TRANSLATIONS" ] = configCmdLine.at(i);
1019         }
1020
1021         else if (configCmdLine.at(i) == "-examplesdir") {
1022             ++i;
1023             if (i == argCount)
1024                 break;
1025             dictionary[ "QT_INSTALL_EXAMPLES" ] = configCmdLine.at(i);
1026         }
1027
1028         else if (configCmdLine.at(i) == "-testsdir") {
1029             ++i;
1030             if (i == argCount)
1031                 break;
1032             dictionary[ "QT_INSTALL_TESTS" ] = configCmdLine.at(i);
1033         }
1034
1035         else if (configCmdLine.at(i) == "-sysroot") {
1036             ++i;
1037             if (i == argCount)
1038                 break;
1039             dictionary[ "CFG_SYSROOT" ] = configCmdLine.at(i);
1040         }
1041
1042         else if (configCmdLine.at(i) == "-hostprefix") {
1043             ++i;
1044             if (i == argCount || configCmdLine.at(i).startsWith('-'))
1045                 dictionary[ "QT_HOST_PREFIX" ] = dictionary[ "QT_BUILD_TREE" ];
1046             else
1047                 dictionary[ "QT_HOST_PREFIX" ] = configCmdLine.at(i);
1048         }
1049
1050         else if (configCmdLine.at(i) == "-hostbindir") {
1051             ++i;
1052             if (i == argCount)
1053                 break;
1054             dictionary[ "QT_HOST_BINS" ] = configCmdLine.at(i);
1055         }
1056
1057         else if (configCmdLine.at(i) == "-hostdatadir") {
1058             ++i;
1059             if (i == argCount)
1060                 break;
1061             dictionary[ "QT_HOST_DATA" ] = configCmdLine.at(i);
1062         }
1063
1064         else if (configCmdLine.at(i) == "-make") {
1065             ++i;
1066             if (i == argCount)
1067                 break;
1068             dictionary[ "MAKE" ] = configCmdLine.at(i);
1069         }
1070
1071         else if (configCmdLine.at(i).indexOf(QRegExp("^-(en|dis)able-")) != -1) {
1072             // Scan to see if any specific modules and drivers are enabled or disabled
1073             for (QStringList::Iterator module = modules.begin(); module != modules.end(); ++module) {
1074                 if (configCmdLine.at(i) == QString("-enable-") + (*module)) {
1075                     enabledModules += (*module);
1076                     break;
1077                 }
1078                 else if (configCmdLine.at(i) == QString("-disable-") + (*module)) {
1079                     disabledModules += (*module);
1080                     break;
1081                 }
1082             }
1083         }
1084
1085         else if (configCmdLine.at(i) == "-directwrite") {
1086             dictionary["DIRECTWRITE"] = "yes";
1087         } else if (configCmdLine.at(i) == "-no-directwrite") {
1088             dictionary["DIRECTWRITE"] = "no";
1089         }
1090
1091         else {
1092             dictionary[ "HELP" ] = "yes";
1093             cout << "Unknown option " << configCmdLine.at(i) << endl;
1094             break;
1095         }
1096
1097 #endif
1098     }
1099
1100     // Ensure that QMAKESPEC exists in the mkspecs folder
1101     QDir mkspec_dir = fixSeparators(sourcePath + "/mkspecs");
1102     QStringList mkspecs = mkspec_dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
1103
1104     if (dictionary["QMAKESPEC"].toLower() == "features"
1105         || !mkspecs.contains(dictionary["QMAKESPEC"], Qt::CaseInsensitive)) {
1106         dictionary[ "HELP" ] = "yes";
1107         if (dictionary ["QMAKESPEC_FROM"] == "commandline") {
1108             cout << "Invalid option \"" << dictionary["QMAKESPEC"] << "\" for -platform." << endl;
1109         } else if (dictionary ["QMAKESPEC_FROM"] == "env") {
1110             cout << "QMAKESPEC environment variable is set to \"" << dictionary["QMAKESPEC"]
1111                  << "\" which is not a supported platform" << endl;
1112         } else { // was autodetected from environment
1113             cout << "Unable to detect the platform from environment. Use -platform command line"
1114                     "argument or set the QMAKESPEC environment variable and run configure again" << endl;
1115         }
1116         cout << "See the README file for a list of supported operating systems and compilers." << endl;
1117     } else {
1118         if (dictionary[ "QMAKESPEC" ].endsWith("-icc") ||
1119             dictionary[ "QMAKESPEC" ].endsWith("-msvc") ||
1120             dictionary[ "QMAKESPEC" ].endsWith("-msvc.net") ||
1121             dictionary[ "QMAKESPEC" ].endsWith("-msvc2002") ||
1122             dictionary[ "QMAKESPEC" ].endsWith("-msvc2003") ||
1123             dictionary[ "QMAKESPEC" ].endsWith("-msvc2005") ||
1124             dictionary[ "QMAKESPEC" ].endsWith("-msvc2008") ||
1125             dictionary[ "QMAKESPEC" ].endsWith("-msvc2010")) {
1126             if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "nmake";
1127             dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32";
1128         } else if (dictionary[ "QMAKESPEC" ] == QString("win32-g++")) {
1129             if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "mingw32-make";
1130             dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32-g++";
1131         } else {
1132             if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "make";
1133             dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32";
1134         }
1135     }
1136
1137     // Tell the user how to proceed building Qt after configure finished its job
1138     dictionary["QTBUILDINSTRUCTION"] = dictionary["MAKE"];
1139     if (dictionary.contains("XQMAKESPEC")) {
1140         if (dictionary["XQMAKESPEC"].startsWith("wince")) {
1141             dictionary["QTBUILDINSTRUCTION"] =
1142                 QString("setcepaths.bat ") + dictionary["XQMAKESPEC"] + QString(" && ") + dictionary["MAKE"];
1143         }
1144     }
1145
1146     // Tell the user how to confclean before the next configure
1147     dictionary["CONFCLEANINSTRUCTION"] = dictionary["MAKE"] + QString(" confclean");
1148
1149     // Ensure that -spec (XQMAKESPEC) exists in the mkspecs folder as well
1150     if (dictionary.contains("XQMAKESPEC") &&
1151         !mkspecs.contains(dictionary["XQMAKESPEC"], Qt::CaseInsensitive)) {
1152             dictionary["HELP"] = "yes";
1153             cout << "Invalid option \"" << dictionary["XQMAKESPEC"] << "\" for -xplatform." << endl;
1154     }
1155
1156     // Ensure that the crt to be deployed can be found
1157     if (dictionary["CE_CRT"] != QLatin1String("yes") && dictionary["CE_CRT"] != QLatin1String("no")) {
1158         QDir cDir(dictionary["CE_CRT"]);
1159         QStringList entries = cDir.entryList();
1160         bool hasDebug = entries.contains("msvcr80.dll");
1161         bool hasRelease = entries.contains("msvcr80d.dll");
1162         if ((dictionary["BUILDALL"] == "auto") && (!hasDebug || !hasRelease)) {
1163             cout << "Could not find debug and release c-runtime." << endl;
1164             cout << "You need to have msvcr80.dll and msvcr80d.dll in" << endl;
1165             cout << "the path specified. Setting to -no-crt";
1166             dictionary[ "CE_CRT" ] = "no";
1167         } else if ((dictionary["BUILD"] == "debug") && !hasDebug) {
1168             cout << "Could not find debug c-runtime (msvcr80d.dll) in the directory specified." << endl;
1169             cout << "Setting c-runtime automatic deployment to -no-crt" << endl;
1170             dictionary[ "CE_CRT" ] = "no";
1171         } else if ((dictionary["BUILD"] == "release") && !hasRelease) {
1172             cout << "Could not find release c-runtime (msvcr80.dll) in the directory specified." << endl;
1173             cout << "Setting c-runtime automatic deployment to -no-crt" << endl;
1174             dictionary[ "CE_CRT" ] = "no";
1175         }
1176     }
1177
1178     useUnixSeparators = (dictionary["QMAKESPEC"] == "win32-g++");
1179
1180     // Allow tests for private classes to be compiled against internal builds
1181     if (dictionary["BUILDDEV"] == "yes")
1182         qtConfig += "private_tests";
1183
1184     if (dictionary["FORCE_ASSERTS"] == "yes")
1185         qtConfig += "force_asserts";
1186
1187 #if !defined(EVAL)
1188     for (QStringList::Iterator dis = disabledModules.begin(); dis != disabledModules.end(); ++dis) {
1189         modules.removeAll((*dis));
1190     }
1191     for (QStringList::Iterator ena = enabledModules.begin(); ena != enabledModules.end(); ++ena) {
1192         if (modules.indexOf((*ena)) == -1)
1193             modules += (*ena);
1194     }
1195     qtConfig += modules;
1196
1197     for (QStringList::Iterator it = disabledModules.begin(); it != disabledModules.end(); ++it)
1198         qtConfig.removeAll(*it);
1199
1200     if ((dictionary[ "REDO" ] != "yes") && (dictionary[ "HELP" ] != "yes"))
1201         saveCmdLine();
1202 #endif
1203 }
1204
1205 #if !defined(EVAL)
1206 void Configure::validateArgs()
1207 {
1208     // Validate the specified config
1209
1210     // Get all possible configurations from the file system.
1211     QDir dir;
1212     QStringList filters;
1213     filters << "qconfig-*.h";
1214     dir.setNameFilters(filters);
1215     dir.setPath(sourcePath + "/src/corelib/global/");
1216
1217     QStringList stringList =  dir.entryList();
1218
1219     QStringList::Iterator it;
1220     for (it = stringList.begin(); it != stringList.end(); ++it)
1221         allConfigs << it->remove("qconfig-").remove(".h");
1222     allConfigs << "full";
1223
1224     // Try internal configurations first.
1225     QStringList possible_configs = QStringList()
1226         << "minimal"
1227         << "small"
1228         << "medium"
1229         << "large"
1230         << "full";
1231     int index = possible_configs.indexOf(dictionary["QCONFIG"]);
1232     if (index >= 0) {
1233         for (int c = 0; c <= index; c++) {
1234             qmakeConfig += possible_configs[c] + "-config";
1235         }
1236         return;
1237     }
1238
1239     // If the internal configurations failed, try others.
1240     QStringList::Iterator config;
1241     for (config = allConfigs.begin(); config != allConfigs.end(); ++config) {
1242         if ((*config) == dictionary[ "QCONFIG" ])
1243             break;
1244     }
1245     if (config == allConfigs.end()) {
1246         dictionary[ "HELP" ] = "yes";
1247         cout << "No such configuration \"" << qPrintable(dictionary[ "QCONFIG" ]) << "\"" << endl ;
1248     }
1249     else
1250         qmakeConfig += (*config) + "-config";
1251 }
1252 #endif
1253
1254
1255 // Output helper functions --------------------------------[ Start ]-
1256 /*!
1257     Determines the length of a string token.
1258 */
1259 static int tokenLength(const char *str)
1260 {
1261     if (*str == 0)
1262         return 0;
1263
1264     const char *nextToken = strpbrk(str, " _/\n\r");
1265     if (nextToken == str || !nextToken)
1266         return 1;
1267
1268     return int(nextToken - str);
1269 }
1270
1271 /*!
1272     Prints out a string which starts at position \a startingAt, and
1273     indents each wrapped line with \a wrapIndent characters.
1274     The wrap point is set to the console width, unless that width
1275     cannot be determined, or is too small.
1276 */
1277 void Configure::desc(const char *description, int startingAt, int wrapIndent)
1278 {
1279     int linePos = startingAt;
1280
1281     bool firstLine = true;
1282     const char *nextToken = description;
1283     while (*nextToken) {
1284         int nextTokenLen = tokenLength(nextToken);
1285         if (*nextToken == '\n'                         // Wrap on newline, duh
1286             || (linePos + nextTokenLen > outputWidth)) // Wrap at outputWidth
1287         {
1288             printf("\n");
1289             linePos = 0;
1290             firstLine = false;
1291             if (*nextToken == '\n')
1292                 ++nextToken;
1293             continue;
1294         }
1295         if (!firstLine && linePos < wrapIndent) {  // Indent to wrapIndent
1296             printf("%*s", wrapIndent , "");
1297             linePos = wrapIndent;
1298             if (*nextToken == ' ') {
1299                 ++nextToken;
1300                 continue;
1301             }
1302         }
1303         printf("%.*s", nextTokenLen, nextToken);
1304         linePos += nextTokenLen;
1305         nextToken += nextTokenLen;
1306     }
1307 }
1308
1309 /*!
1310     Prints out an option with its description wrapped at the
1311     description starting point. If \a skipIndent is true, the
1312     indentation to the option is not outputted (used by marked option
1313     version of desc()). Extra spaces between option and its
1314     description is filled with\a fillChar, if there's available
1315     space.
1316 */
1317 void Configure::desc(const char *option, const char *description, bool skipIndent, char fillChar)
1318 {
1319     if (!skipIndent)
1320         printf("%*s", optionIndent, "");
1321
1322     int remaining  = descIndent - optionIndent - strlen(option);
1323     int wrapIndent = descIndent + qMax(0, 1 - remaining);
1324     printf("%s", option);
1325
1326     if (remaining > 2) {
1327         printf(" "); // Space in front
1328         for (int i = remaining; i > 2; --i)
1329             printf("%c", fillChar); // Fill, if available space
1330     }
1331     printf(" "); // Space between option and description
1332
1333     desc(description, wrapIndent, wrapIndent);
1334     printf("\n");
1335 }
1336
1337 /*!
1338     Same as above, except it also marks an option with an '*', if
1339     the option is default action.
1340 */
1341 void Configure::desc(const char *mark_option, const char *mark, const char *option, const char *description, char fillChar)
1342 {
1343     const QString markedAs = dictionary.value(mark_option);
1344     if (markedAs == "auto" && markedAs == mark) // both "auto", always => +
1345         printf(" +  ");
1346     else if (markedAs == "auto")                // setting marked as "auto" and option is default => +
1347         printf(" %c  " , (defaultTo(mark_option) == QLatin1String(mark))? '+' : ' ');
1348     else if (QLatin1String(mark) == "auto" && markedAs != "no")     // description marked as "auto" and option is available => +
1349         printf(" %c  " , checkAvailability(mark_option) ? '+' : ' ');
1350     else                                        // None are "auto", (markedAs == mark) => *
1351         printf(" %c  " , markedAs == QLatin1String(mark) ? '*' : ' ');
1352
1353     desc(option, description, true, fillChar);
1354 }
1355
1356 /*!
1357     Modifies the default configuration based on given -platform option.
1358     Eg. switches to different default styles for Windows CE.
1359 */
1360 void Configure::applySpecSpecifics()
1361 {
1362     if (dictionary[ "XQMAKESPEC" ].startsWith("wince")) {
1363         dictionary[ "STYLE_WINDOWSXP" ]     = "no";
1364         dictionary[ "STYLE_WINDOWSVISTA" ]  = "no";
1365         dictionary[ "STYLE_PLASTIQUE" ]     = "no";
1366         dictionary[ "STYLE_CLEANLOOKS" ]    = "no";
1367         dictionary[ "STYLE_WINDOWSCE" ]     = "yes";
1368         dictionary[ "STYLE_WINDOWSMOBILE" ] = "yes";
1369         dictionary[ "STYLE_MOTIF" ]         = "no";
1370         dictionary[ "STYLE_CDE" ]           = "no";
1371         dictionary[ "FREETYPE" ]            = "no";
1372         dictionary[ "OPENGL" ]              = "no";
1373         dictionary[ "OPENSSL" ]             = "no";
1374         dictionary[ "STL" ]                 = "no";
1375         dictionary[ "EXCEPTIONS" ]          = "no";
1376         dictionary[ "RTTI" ]                = "no";
1377         dictionary[ "3DNOW" ]               = "no";
1378         dictionary[ "SSE" ]                 = "no";
1379         dictionary[ "SSE2" ]                = "no";
1380         dictionary[ "MMX" ]                 = "no";
1381         dictionary[ "IWMMXT" ]              = "no";
1382         dictionary[ "CE_CRT" ]              = "yes";
1383         dictionary[ "DIRECTSHOW" ]          = "no";
1384         // We only apply MMX/IWMMXT for mkspecs we know they work
1385         if (dictionary[ "XQMAKESPEC" ].startsWith("wincewm")) {
1386             dictionary[ "MMX" ]    = "yes";
1387             dictionary[ "IWMMXT" ] = "yes";
1388             dictionary[ "DIRECTSHOW" ] = "yes";
1389         }
1390         dictionary[ "QT_HOST_PREFIX" ]      = dictionary[ "QT_INSTALL_PREFIX" ];
1391         dictionary[ "QT_INSTALL_PREFIX" ]   = "";
1392
1393     } else if (dictionary[ "XQMAKESPEC" ].startsWith("linux")) { //TODO actually wrong.
1394       //TODO
1395         dictionary[ "STYLE_WINDOWSXP" ]     = "no";
1396         dictionary[ "STYLE_WINDOWSVISTA" ]  = "no";
1397         dictionary[ "KBD_DRIVERS" ]         = "tty";
1398         dictionary[ "GFX_DRIVERS" ]         = "linuxfb";
1399         dictionary[ "MOUSE_DRIVERS" ]       = "pc linuxtp";
1400         dictionary[ "OPENGL" ]              = "no";
1401         dictionary[ "EXCEPTIONS" ]          = "no";
1402         dictionary[ "DBUS"]                 = "no";
1403         dictionary[ "QT_QWS_DEPTH" ]        = "4 8 16 24 32";
1404         dictionary[ "QT_SXE" ]              = "no";
1405         dictionary[ "QT_INOTIFY" ]          = "no";
1406         dictionary[ "QT_LPR" ]              = "no";
1407         dictionary[ "QT_CUPS" ]             = "no";
1408         dictionary[ "QT_GLIB" ]             = "no";
1409         dictionary[ "QT_ICONV" ]            = "no";
1410
1411         dictionary["DECORATIONS"]           = "default windows styled";
1412     }
1413 }
1414
1415 QString Configure::locateFileInPaths(const QString &fileName, const QStringList &paths)
1416 {
1417     QDir d;
1418     for (QStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it) {
1419         // Remove any leading or trailing ", this is commonly used in the environment
1420         // variables
1421         QString path = (*it);
1422         if (path.startsWith("\""))
1423             path = path.right(path.length() - 1);
1424         if (path.endsWith("\""))
1425             path = path.left(path.length() - 1);
1426         if (d.exists(path + QDir::separator() + fileName)) {
1427             return (path);
1428         }
1429     }
1430     return QString();
1431 }
1432
1433 QString Configure::locateFile(const QString &fileName)
1434 {
1435     QString file = fileName.toLower();
1436     QStringList paths;
1437 #if defined(Q_OS_WIN32)
1438     QRegExp splitReg("[;,]");
1439 #else
1440     QRegExp splitReg("[:]");
1441 #endif
1442     if (file.endsWith(".h"))
1443         paths = QString::fromLocal8Bit(getenv("INCLUDE")).split(splitReg, QString::SkipEmptyParts);
1444     else if (file.endsWith(".lib"))
1445         paths = QString::fromLocal8Bit(getenv("LIB")).split(splitReg, QString::SkipEmptyParts);
1446     else
1447         paths = QString::fromLocal8Bit(getenv("PATH")).split(splitReg, QString::SkipEmptyParts);
1448     return locateFileInPaths(file, paths);
1449 }
1450
1451 // Output helper functions ---------------------------------[ Stop ]-
1452
1453
1454 bool Configure::displayHelp()
1455 {
1456     if (dictionary[ "HELP" ] == "yes") {
1457         desc("Usage: configure\n"
1458                     "[-release] [-debug] [-debug-and-release] [-shared] [-static]\n"
1459                     "[-no-fast] [-fast] [-no-exceptions] [-exceptions]\n"
1460                     "[-no-accessibility] [-accessibility] [-no-rtti] [-rtti]\n"
1461                     "[-no-stl] [-stl] [-no-sql-<driver>] [-qt-sql-<driver>]\n"
1462                     "[-plugin-sql-<driver>] [-system-sqlite]\n"
1463                     "[-D <define>] [-I <includepath>] [-L <librarypath>]\n"
1464                     "[-help] [-no-dsp] [-dsp] [-no-vcproj] [-vcproj]\n"
1465                     "[-no-qmake] [-qmake] [-dont-process] [-process]\n"
1466                     "[-no-style-<style>] [-qt-style-<style>] [-redo]\n"
1467                     "[-saveconfig <config>] [-loadconfig <config>]\n"
1468                     "[-qt-zlib] [-system-zlib] [-qt-pcre] [-system-pcre] [-no-gif]\n"
1469                     "[-no-libpng] [-qt-libpng] [-system-libpng]\n"
1470                     "[-no-libjpeg] [-qt-libjpeg] [-system-libjpeg]\n"
1471                     "[-mmx] [-no-mmx] [-3dnow] [-no-3dnow] [-sse] [-no-sse] [-sse2] [-no-sse2]\n"
1472                     "[-no-iwmmxt] [-iwmmxt] [-openssl] [-openssl-linked]\n"
1473                     "[-no-openssl] [-no-dbus] [-dbus] [-dbus-linked] [-platform <spec>]\n"
1474                     "[-qtnamespace <namespace>] [-qtlibinfix <infix>] [-no-phonon]\n"
1475                     "[-phonon] [-no-phonon-backend] [-phonon-backend]\n"
1476                     "[-no-multimedia] [-multimedia] [-no-audio-backend] [-audio-backend]\n"
1477                     "[-no-script] [-script] [-no-scripttools] [-scripttools]\n"
1478                     "[-no-webkit] [-webkit] [-webkit-debug]\n"
1479                     "[-no-directwrite] [-directwrite] [-qpa] [-no-widgets] [-icu]\n\n", 0, 7);
1480
1481         desc("Installation options:\n\n");
1482
1483 #if !defined(EVAL)
1484         desc("Configure options:\n\n");
1485
1486         desc(" The defaults (*) are usually acceptable. A plus (+) denotes a default value"
1487              " that needs to be evaluated. If the evaluation succeeds, the feature is"
1488              " included. Here is a short explanation of each option:\n\n", 0, 1);
1489
1490         desc("BUILD", "release","-release",             "Compile and link Qt with debugging turned off.");
1491         desc("BUILD", "debug",  "-debug",               "Compile and link Qt with debugging turned on.");
1492         desc("BUILDALL", "yes", "-debug-and-release",   "Compile and link two Qt libraries, with and without debugging turned on.\n");
1493
1494         desc("OPENSOURCE", "opensource", "-opensource",   "Compile and link the Open-Source Edition of Qt.");
1495         desc("COMMERCIAL", "commercial", "-commercial",   "Compile and link the Commercial Edition of Qt.\n");
1496
1497         desc("BUILDDEV", "yes", "-developer-build",      "Compile and link Qt with Qt developer options (including auto-tests exporting)\n");
1498
1499         desc("SHARED", "yes",   "-shared",              "Create and use shared Qt libraries.");
1500         desc("SHARED", "no",    "-static",              "Create and use static Qt libraries.\n");
1501
1502         desc("LTCG", "yes",   "-ltcg",                  "Use Link Time Code Generation. (Release builds only)");
1503         desc("LTCG", "no",    "-no-ltcg",               "Do not use Link Time Code Generation.\n");
1504
1505         desc("FAST", "no",      "-no-fast",             "Configure Qt normally by generating Makefiles for all project files.");
1506         desc("FAST", "yes",     "-fast",                "Configure Qt quickly by generating Makefiles only for library and "
1507                                                         "subdirectory targets.  All other Makefiles are created as wrappers "
1508                                                         "which will in turn run qmake\n");
1509
1510         desc("EXCEPTIONS", "no", "-no-exceptions",      "Disable exceptions on platforms that support it.");
1511         desc("EXCEPTIONS", "yes","-exceptions",         "Enable exceptions on platforms that support it.\n");
1512
1513         desc("WIDGETS", "no", "-no-widgets",            "Disable QtWidgets module\n");
1514
1515         desc("ACCESSIBILITY", "no",  "-no-accessibility", "Do not compile Windows Active Accessibility support.");
1516         desc("ACCESSIBILITY", "yes", "-accessibility",    "Compile Windows Active Accessibility support.\n");
1517
1518         desc("STL", "no",       "-no-stl",              "Do not compile STL support.");
1519         desc("STL", "yes",      "-stl",                 "Compile STL support.\n");
1520
1521         desc(                   "-no-sql-<driver>",     "Disable SQL <driver> entirely, by default none are turned on.");
1522         desc(                   "-qt-sql-<driver>",     "Enable a SQL <driver> in the Qt Library.");
1523         desc(                   "-plugin-sql-<driver>", "Enable SQL <driver> as a plugin to be linked to at run time.\n"
1524                                                         "Available values for <driver>:");
1525         desc("SQL_MYSQL", "auto", "",                   "  mysql", ' ');
1526         desc("SQL_PSQL", "auto", "",                    "  psql", ' ');
1527         desc("SQL_OCI", "auto", "",                     "  oci", ' ');
1528         desc("SQL_ODBC", "auto", "",                    "  odbc", ' ');
1529         desc("SQL_TDS", "auto", "",                     "  tds", ' ');
1530         desc("SQL_DB2", "auto", "",                     "  db2", ' ');
1531         desc("SQL_SQLITE", "auto", "",                  "  sqlite", ' ');
1532         desc("SQL_SQLITE2", "auto", "",                 "  sqlite2", ' ');
1533         desc("SQL_IBASE", "auto", "",                   "  ibase", ' ');
1534         desc(                   "",                     "(drivers marked with a '+' have been detected as available on this system)\n", false, ' ');
1535
1536         desc(                   "-system-sqlite",       "Use sqlite from the operating system.\n");
1537
1538         desc("OPENGL", "no","-no-opengl",               "Disables OpenGL functionality\n");
1539         desc("OPENGL", "no","-opengl <api>",            "Enable OpenGL support with specified API version.\n"
1540                                                         "Available values for <api>:");
1541         desc("", "", "",                                "  desktop - Enable support for Desktop OpenGL", ' ');
1542         desc("OPENGL_ES_CM", "no", "",                  "  es1 - Enable support for OpenGL ES Common Profile", ' ');
1543         desc("OPENGL_ES_2",  "no", "",                  "  es2 - Enable support for OpenGL ES 2.0", ' ');
1544
1545         desc("OPENVG", "no","-no-openvg",               "Disables OpenVG functionality\n");
1546         desc("OPENVG", "yes","-openvg",                 "Enables OpenVG functionality");
1547         desc(                   "-force-asserts",       "Activate asserts in release mode.\n");
1548 #endif
1549         desc(                   "-platform <spec>",     "The operating system and compiler you are building on.\n(default %QMAKESPEC%)\n");
1550         desc(                   "-xplatform <spec>",    "The operating system and compiler you are cross compiling to.\n");
1551         desc(                   "",                     "See the README file for a list of supported operating systems and compilers.\n", false, ' ');
1552
1553 #if !defined(EVAL)
1554         desc(                   "-qtnamespace <namespace>", "Wraps all Qt library code in 'namespace name {...}");
1555         desc(                   "-qtlibinfix <infix>",  "Renames all Qt* libs to Qt*<infix>\n");
1556         desc(                   "-D <define>",          "Add an explicit define to the preprocessor.");
1557         desc(                   "-I <includepath>",     "Add an explicit include path.");
1558         desc(                   "-L <librarypath>",     "Add an explicit library path.");
1559         desc(                   "-l <libraryname>",     "Add an explicit library name, residing in a librarypath.\n");
1560 #endif
1561
1562         desc(                   "-help, -h, -?",        "Display this information.\n");
1563
1564 #if !defined(EVAL)
1565         // 3rd party stuff options go below here --------------------------------------------------------------------------------
1566         desc("Third Party Libraries:\n\n");
1567
1568         desc("ZLIB", "qt",      "-qt-zlib",             "Use the zlib bundled with Qt.");
1569         desc("ZLIB", "system",  "-system-zlib",         "Use zlib from the operating system.\nSee http://www.gzip.org/zlib\n");
1570
1571         desc("PCRE", "qt",       "-qt-pcre",            "Use the PCRE library bundled with Qt.");
1572         desc("PCRE", "qt",       "-system-pcre",        "Use the PCRE library from the operating system.\nSee http://pcre.org/\n");
1573
1574         desc("ICU", "yes",       "-icu",                "Use the ICU library.");
1575         desc("ICU", "no",        "-no-icu",             "Do not use the ICU library.\nSee http://site.icu-project.org/\n");
1576
1577         desc("GIF", "no",       "-no-gif",              "Do not compile GIF reading support.");
1578
1579         desc("LIBPNG", "no",    "-no-libpng",           "Do not compile PNG support.");
1580         desc("LIBPNG", "qt",    "-qt-libpng",           "Use the libpng bundled with Qt.");
1581         desc("LIBPNG", "system","-system-libpng",       "Use libpng from the operating system.\nSee http://www.libpng.org/pub/png\n");
1582
1583         desc("LIBJPEG", "no",    "-no-libjpeg",         "Do not compile JPEG support.");
1584         desc("LIBJPEG", "qt",    "-qt-libjpeg",         "Use the libjpeg bundled with Qt.");
1585         desc("LIBJPEG", "system","-system-libjpeg",     "Use libjpeg from the operating system.\nSee http://www.ijg.org\n");
1586
1587         desc("FREETYPE", "no",   "-no-freetype",        "Do not compile in Freetype2 support.");
1588         desc("FREETYPE", "yes",  "-qt-freetype",        "Use the libfreetype bundled with Qt.");
1589 #endif
1590         // Qt\Windows only options go below here --------------------------------------------------------------------------------
1591         desc("Qt for Windows only:\n\n");
1592
1593         desc("DSPFILES", "no",  "-no-dsp",              "Do not generate VC++ .dsp files.");
1594         desc("DSPFILES", "yes", "-dsp",                 "Generate VC++ .dsp files, only if spec \"win32-msvc\".\n");
1595
1596         desc("VCPROJFILES", "no", "-no-vcproj",         "Do not generate VC++ .vcproj files.");
1597         desc("VCPROJFILES", "yes", "-vcproj",           "Generate VC++ .vcproj files, only if platform \"win32-msvc.net\".\n");
1598
1599         desc("INCREDIBUILD_XGE", "no", "-no-incredibuild-xge", "Do not add IncrediBuild XGE distribution commands to custom build steps.");
1600         desc("INCREDIBUILD_XGE", "yes", "-incredibuild-xge",   "Add IncrediBuild XGE distribution commands to custom build steps. This will distribute MOC and UIC steps, and other custom buildsteps which are added to the INCREDIBUILD_XGE variable.\n(The IncrediBuild distribution commands are only added to Visual Studio projects)\n");
1601
1602         desc("PLUGIN_MANIFESTS", "no", "-no-plugin-manifests", "Do not embed manifests in plugins.");
1603         desc("PLUGIN_MANIFESTS", "yes", "-plugin-manifests",   "Embed manifests in plugins.\n");
1604
1605 #if !defined(EVAL)
1606         desc("BUILD_QMAKE", "no", "-no-qmake",          "Do not compile qmake.");
1607         desc("BUILD_QMAKE", "yes", "-qmake",            "Compile qmake.\n");
1608
1609         desc("NOPROCESS", "yes", "-dont-process",       "Do not generate Makefiles/Project files. This will override -no-fast if specified.");
1610         desc("NOPROCESS", "no",  "-process",            "Generate Makefiles/Project files.\n");
1611
1612         desc("RTTI", "no",      "-no-rtti",             "Do not compile runtime type information.");
1613         desc("RTTI", "yes",     "-rtti",                "Compile runtime type information.\n");
1614         desc("MMX", "no",       "-no-mmx",              "Do not compile with use of MMX instructions");
1615         desc("MMX", "yes",      "-mmx",                 "Compile with use of MMX instructions");
1616         desc("3DNOW", "no",     "-no-3dnow",            "Do not compile with use of 3DNOW instructions");
1617         desc("3DNOW", "yes",    "-3dnow",               "Compile with use of 3DNOW instructions");
1618         desc("SSE", "no",       "-no-sse",              "Do not compile with use of SSE instructions");
1619         desc("SSE", "yes",      "-sse",                 "Compile with use of SSE instructions");
1620         desc("SSE2", "no",      "-no-sse2",             "Do not compile with use of SSE2 instructions");
1621         desc("SSE2", "yes",      "-sse2",               "Compile with use of SSE2 instructions");
1622         desc("OPENSSL", "no",    "-no-openssl",         "Do not compile in OpenSSL support");
1623         desc("OPENSSL", "yes",   "-openssl",            "Compile in run-time OpenSSL support");
1624         desc("OPENSSL", "linked","-openssl-linked",     "Compile in linked OpenSSL support");
1625         desc("DBUS", "no",       "-no-dbus",            "Do not compile in D-Bus support");
1626         desc("DBUS", "yes",      "-dbus",               "Compile in D-Bus support and load libdbus-1 dynamically");
1627         desc("DBUS", "linked",   "-dbus-linked",        "Compile in D-Bus support and link to libdbus-1");
1628         desc("PHONON_BACKEND","no", "-no-phonon-backend","Do not compile the platform-specific Phonon backend-plugin");
1629         desc("PHONON_BACKEND","yes","-phonon-backend",  "Compile in the platform-specific Phonon backend-plugin");
1630         desc("AUDIO_BACKEND", "no","-no-audio-backend", "Do not compile in the platform audio backend into QtMultimedia");
1631         desc("AUDIO_BACKEND", "yes","-audio-backend",   "Compile in the platform audio backend into QtMultimedia");
1632         desc("DECLARATIVE_DEBUG", "no",    "-no-declarative-debug", "Do not build the declarative debugging support");
1633         desc("DECLARATIVE_DEBUG", "yes",   "-declarative-debug",    "Build the declarative debugging support");
1634         desc("DIRECTWRITE", "no", "-no-directwrite", "Do not build support for DirectWrite font rendering");
1635         desc("DIRECTWRITE", "yes", "-directwrite", "Build support for DirectWrite font rendering (experimental, requires DirectWrite availability on target systems, e.g. Windows Vista with Platform Update, Windows 7, etc.)");
1636
1637         desc(                   "-no-style-<style>",    "Disable <style> entirely.");
1638         desc(                   "-qt-style-<style>",    "Enable <style> in the Qt Library.\nAvailable styles: ");
1639
1640         desc("STYLE_WINDOWS", "yes", "",                "  windows", ' ');
1641         desc("STYLE_WINDOWSXP", "auto", "",             "  windowsxp", ' ');
1642         desc("STYLE_WINDOWSVISTA", "auto", "",          "  windowsvista", ' ');
1643         desc("STYLE_PLASTIQUE", "yes", "",              "  plastique", ' ');
1644         desc("STYLE_CLEANLOOKS", "yes", "",             "  cleanlooks", ' ');
1645         desc("STYLE_MOTIF", "yes", "",                  "  motif", ' ');
1646         desc("STYLE_CDE", "yes", "",                    "  cde", ' ');
1647         desc("STYLE_WINDOWSCE", "yes", "",              "  windowsce", ' ');
1648         desc("STYLE_WINDOWSMOBILE" , "yes", "",         "  windowsmobile", ' ');
1649         desc("NATIVE_GESTURES", "no", "-no-native-gestures", "Do not use native gestures on Windows 7.");
1650         desc("NATIVE_GESTURES", "yes", "-native-gestures", "Use native gestures on Windows 7.");
1651         desc("MSVC_MP", "no", "-no-mp",                 "Do not use multiple processors for compiling with MSVC");
1652         desc("MSVC_MP", "yes", "-mp",                   "Use multiple processors for compiling with MSVC (-MP)");
1653
1654 /*      We do not support -qconfig on Windows yet
1655
1656         desc(                   "-qconfig <local>",     "Use src/tools/qconfig-local.h rather than the default.\nPossible values for local:");
1657         for (int i=0; i<allConfigs.size(); ++i)
1658             desc(               "",                     qPrintable(QString("  %1").arg(allConfigs.at(i))), false, ' ');
1659         printf("\n");
1660 */
1661 #endif
1662         desc(                   "-loadconfig <config>", "Run configure with the parameters from file configure_<config>.cache.");
1663         desc(                   "-saveconfig <config>", "Run configure and save the parameters in file configure_<config>.cache.");
1664         desc(                   "-redo",                "Run configure with the same parameters as last time.\n");
1665
1666         // Qt\Windows CE only options go below here -----------------------------------------------------------------------------
1667         desc("Qt for Windows CE only:\n\n");
1668         desc("IWMMXT", "no",       "-no-iwmmxt",           "Do not compile with use of IWMMXT instructions");
1669         desc("IWMMXT", "yes",      "-iwmmxt",              "Do compile with use of IWMMXT instructions (Qt for Windows CE on Arm only)");
1670         desc("CE_CRT", "no",       "-no-crt" ,             "Do not add the C runtime to default deployment rules");
1671         desc("CE_CRT", "yes",      "-qt-crt",              "Qt identifies C runtime during project generation");
1672         desc(                      "-crt <path>",          "Specify path to C runtime used for project generation.");
1673         desc("CETEST", "no",       "-no-cetest",           "Do not compile Windows CE remote test application");
1674         desc("CETEST", "yes",      "-cetest",              "Compile Windows CE remote test application");
1675         desc(                      "-signature <file>",    "Use file for signing the target project");
1676
1677         desc("DIRECTSHOW", "no",   "-phonon-wince-ds9",    "Enable Phonon Direct Show 9 backend for Windows CE");
1678         return true;
1679     }
1680     return false;
1681 }
1682
1683 QString Configure::findFileInPaths(const QString &fileName, const QString &paths)
1684 {
1685 #if defined(Q_OS_WIN32)
1686     QRegExp splitReg("[;,]");
1687 #else
1688     QRegExp splitReg("[:]");
1689 #endif
1690     QStringList pathList = paths.split(splitReg, QString::SkipEmptyParts);
1691     QDir d;
1692     for (QStringList::ConstIterator it = pathList.begin(); it != pathList.end(); ++it) {
1693         // Remove any leading or trailing ", this is commonly used in the environment
1694         // variables
1695         QString path = (*it);
1696         if (path.startsWith('\"'))
1697             path = path.right(path.length() - 1);
1698         if (path.endsWith('\"'))
1699             path = path.left(path.length() - 1);
1700         if (d.exists(path + QDir::separator() + fileName))
1701             return path;
1702     }
1703     return QString();
1704 }
1705
1706 static QString mingwPaths(const QString &mingwPath, const QString &pathName)
1707 {
1708     QString ret;
1709     QDir mingwDir = QFileInfo(mingwPath).dir();
1710     const QFileInfoList subdirs = mingwDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
1711     for (int i = 0 ;i < subdirs.length(); ++i) {
1712         const QFileInfo &fi = subdirs.at(i);
1713         const QString name = fi.fileName();
1714         if (name == pathName)
1715             ret += fi.absoluteFilePath() + ';';
1716         else if (name.contains("mingw"))
1717             ret += fi.absoluteFilePath() + QDir::separator() + pathName + ';';
1718     }
1719     return ret;
1720 }
1721
1722 bool Configure::findFile(const QString &fileName)
1723 {
1724     const QString file = fileName.toLower();
1725     const QString pathEnvVar = QString::fromLocal8Bit(getenv("PATH"));
1726     const QString mingwPath = dictionary["QMAKESPEC"].endsWith("-g++") ?
1727         findFileInPaths("g++.exe", pathEnvVar) : QString();
1728
1729     QString paths;
1730     if (file.endsWith(".h")) {
1731         if (!mingwPath.isNull()) {
1732             if (!findFileInPaths(file, mingwPaths(mingwPath, "include")).isNull())
1733                 return true;
1734             //now let's try the additional compiler path
1735
1736             const QFileInfoList mingwConfigs = QDir(mingwPath + QLatin1String("/../lib/gcc")).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
1737             for (int i = 0; i < mingwConfigs.length(); ++i) {
1738                 const QDir mingwLibDir = mingwConfigs.at(i).absoluteFilePath();
1739                 foreach(const QFileInfo &version, mingwLibDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
1740                     if (!findFileInPaths(file, version.absoluteFilePath() + QLatin1String("/include")).isNull())
1741                         return true;
1742                 }
1743             }
1744         }
1745         paths = QString::fromLocal8Bit(getenv("INCLUDE"));
1746     } else if (file.endsWith(".lib") ||  file.endsWith(".a")) {
1747         if (!mingwPath.isNull() && !findFileInPaths(file, mingwPaths(mingwPath, "lib")).isNull())
1748             return true;
1749         paths = QString::fromLocal8Bit(getenv("LIB"));
1750     } else {
1751         paths = pathEnvVar;
1752     }
1753     return !findFileInPaths(file, paths).isNull();
1754 }
1755
1756 /*!
1757     Default value for options marked as "auto" if the test passes.
1758     (Used both by the autoDetection() below, and the desc() function
1759     to mark (+) the default option of autodetecting options.
1760 */
1761 QString Configure::defaultTo(const QString &option)
1762 {
1763     // We prefer using the system version of the 3rd party libs
1764     if (option == "ZLIB"
1765         || option == "PCRE"
1766         || option == "LIBJPEG"
1767         || option == "LIBPNG")
1768         return "system";
1769
1770     // PNG is always built-in, never a plugin
1771     if (option == "PNG")
1772         return "yes";
1773
1774     // These database drivers and image formats can be built-in or plugins.
1775     // Prefer plugins when Qt is shared.
1776     if (dictionary[ "SHARED" ] == "yes") {
1777         if (option == "SQL_MYSQL"
1778             || option == "SQL_MYSQL"
1779             || option == "SQL_ODBC"
1780             || option == "SQL_OCI"
1781             || option == "SQL_PSQL"
1782             || option == "SQL_TDS"
1783             || option == "SQL_DB2"
1784             || option == "SQL_SQLITE"
1785             || option == "SQL_SQLITE2"
1786             || option == "SQL_IBASE"
1787             || option == "JPEG"
1788             || option == "GIF")
1789             return "plugin";
1790     }
1791
1792     // By default we do not want to compile OCI driver when compiling with
1793     // MinGW, due to lack of such support from Oracle. It prob. wont work.
1794     // (Customer may force the use though)
1795     if (dictionary["QMAKESPEC"].endsWith("-g++")
1796         && option == "SQL_OCI")
1797         return "no";
1798
1799     if (option == "SYNCQT"
1800         && (!QFile::exists(sourcePath + "/bin/syncqt") ||
1801             !QFile::exists(sourcePath + "/bin/syncqt.bat")))
1802         return "no";
1803
1804     return "yes";
1805 }
1806
1807 /*!
1808     Checks the system for the availability of a feature.
1809     Returns true if the feature is available, else false.
1810 */
1811 bool Configure::checkAvailability(const QString &part)
1812 {
1813     bool available = false;
1814     if (part == "STYLE_WINDOWSXP")
1815         available = findFile("uxtheme.h");
1816
1817     else if (part == "ZLIB")
1818         available = findFile("zlib.h");
1819
1820     else if (part == "PCRE")
1821         available = findFile("pcre.h");
1822
1823     else if (part == "ICU")
1824         available = findFile("unicode/utypes.h") && findFile("unicode/ucol.h") && findFile("unicode/ustring.h") && findFile("icuin.lib");
1825
1826     else if (part == "LIBJPEG")
1827         available = findFile("jpeglib.h");
1828     else if (part == "LIBPNG")
1829         available = findFile("png.h");
1830     else if (part == "SQL_MYSQL")
1831         available = findFile("mysql.h") && findFile("libmySQL.lib");
1832     else if (part == "SQL_ODBC")
1833         available = findFile("sql.h") && findFile("sqlext.h") && findFile("odbc32.lib");
1834     else if (part == "SQL_OCI")
1835         available = findFile("oci.h") && findFile("oci.lib");
1836     else if (part == "SQL_PSQL")
1837         available = findFile("libpq-fe.h") && findFile("libpq.lib") && findFile("ws2_32.lib") && findFile("advapi32.lib");
1838     else if (part == "SQL_TDS")
1839         available = findFile("sybfront.h") && findFile("sybdb.h") && findFile("ntwdblib.lib");
1840     else if (part == "SQL_DB2")
1841         available = findFile("sqlcli.h") && findFile("sqlcli1.h") && findFile("db2cli.lib");
1842     else if (part == "SQL_SQLITE")
1843         available = true; // Built in, we have a fork
1844     else if (part == "SQL_SQLITE_LIB") {
1845         if (dictionary[ "SQL_SQLITE_LIB" ] == "system") {
1846             available = findFile("sqlite3.h") && findFile("sqlite3.lib");
1847             if (available)
1848                 dictionary[ "QT_LFLAGS_SQLITE" ] += "sqlite3.lib";
1849         } else
1850             available = true;
1851     } else if (part == "SQL_SQLITE2")
1852         available = findFile("sqlite.h") && findFile("sqlite.lib");
1853     else if (part == "SQL_IBASE")
1854         available = findFile("ibase.h") && (findFile("gds32_ms.lib") || findFile("gds32.lib"));
1855     else if (part == "IWMMXT")
1856         available = (dictionary.value("XQMAKESPEC").startsWith("wince"));
1857     else if (part == "OPENGL_ES_CM")
1858         available = (dictionary.value("XQMAKESPEC").startsWith("wince"));
1859     else if (part == "OPENGL_ES_2")
1860         available = (dictionary.value("XQMAKESPEC").startsWith("wince"));
1861     else if (part == "DIRECTSHOW")
1862         available = (dictionary.value("XQMAKESPEC").startsWith("wince"));
1863     else if (part == "SSE2")
1864         available = (dictionary.value("QMAKESPEC") != "win32-msvc");
1865     else if (part == "3DNOW")
1866         available = (dictionary.value("QMAKESPEC") != "win32-msvc") && (dictionary.value("QMAKESPEC") != "win32-icc") && findFile("mm3dnow.h");
1867     else if (part == "MMX" || part == "SSE")
1868         available = (dictionary.value("QMAKESPEC") != "win32-msvc");
1869     else if (part == "OPENSSL")
1870         available = findFile("openssl\\ssl.h");
1871     else if (part == "DBUS")
1872         available = findFile("dbus\\dbus.h");
1873     else if (part == "CETEST") {
1874         QString rapiHeader = locateFile("rapi.h");
1875         QString rapiLib = locateFile("rapi.lib");
1876         available = (dictionary.value("XQMAKESPEC").startsWith("wince")) && !rapiHeader.isEmpty() && !rapiLib.isEmpty();
1877         if (available) {
1878             dictionary[ "QT_CE_RAPI_INC" ] += QLatin1String("\"") + rapiHeader + QLatin1String("\"");
1879             dictionary[ "QT_CE_RAPI_LIB" ] += QLatin1String("\"") + rapiLib + QLatin1String("\"");
1880         }
1881         else if (dictionary[ "CETEST_REQUESTED" ] == "yes") {
1882             cout << "cetest could not be enabled: rapi.h and rapi.lib could not be found." << endl;
1883             cout << "Make sure the environment is set up for compiling with ActiveSync." << endl;
1884             dictionary[ "DONE" ] = "error";
1885         }
1886     }
1887     else if (part == "INCREDIBUILD_XGE")
1888         available = findFile("BuildConsole.exe") && findFile("xgConsole.exe");
1889     else if (part == "PHONON") {
1890         available = findFile("vmr9.h") && findFile("dshow.h") && findFile("dmo.h") && findFile("dmodshow.h")
1891             && (findFile("strmiids.lib") || findFile("libstrmiids.a"))
1892             && (findFile("dmoguids.lib") || findFile("libdmoguids.a"))
1893             && (findFile("msdmo.lib") || findFile("libmsdmo.a"))
1894             && findFile("d3d9.h");
1895
1896         if (!available) {
1897             cout << "All the required DirectShow/Direct3D files couldn't be found." << endl
1898                  << "Make sure you have either the platform SDK AND the DirectShow SDK or the Windows SDK installed." << endl
1899                  << "If you have the DirectShow SDK installed, please make sure that you have run the <path to SDK>\\SetEnv.Cmd script." << endl;
1900             if (!findFile("vmr9.h"))  cout << "vmr9.h not found" << endl;
1901             if (!findFile("dshow.h")) cout << "dshow.h not found" << endl;
1902             if (!findFile("strmiids.lib")) cout << "strmiids.lib not found" << endl;
1903             if (!findFile("dmoguids.lib")) cout << "dmoguids.lib not found" << endl;
1904             if (!findFile("msdmo.lib")) cout << "msdmo.lib not found" << endl;
1905             if (!findFile("d3d9.h")) cout << "d3d9.h not found" << endl;
1906         }
1907     } else if (part == "WMSDK") {
1908         available = findFile("wmsdk.h");
1909     } else if (part == "V8SNAPSHOT") {
1910         available = true;
1911     } else if (part == "AUDIO_BACKEND") {
1912         available = true;
1913     } else if (part == "DIRECTWRITE") {
1914         available = findFile("dwrite.h") && findFile("d2d1.h") && findFile("dwrite.lib");
1915     }
1916
1917     return available;
1918 }
1919
1920 /*
1921     Autodetect options marked as "auto".
1922 */
1923 void Configure::autoDetection()
1924 {
1925     // Style detection
1926     if (dictionary["STYLE_WINDOWSXP"] == "auto")
1927         dictionary["STYLE_WINDOWSXP"] = checkAvailability("STYLE_WINDOWSXP") ? defaultTo("STYLE_WINDOWSXP") : "no";
1928     if (dictionary["STYLE_WINDOWSVISTA"] == "auto") // Vista style has the same requirements as XP style
1929         dictionary["STYLE_WINDOWSVISTA"] = checkAvailability("STYLE_WINDOWSXP") ? defaultTo("STYLE_WINDOWSVISTA") : "no";
1930
1931     // Compression detection
1932     if (dictionary["ZLIB"] == "auto")
1933         dictionary["ZLIB"] =  checkAvailability("ZLIB") ? defaultTo("ZLIB") : "qt";
1934
1935     // PCRE detection
1936     if (dictionary["PCRE"] == "auto")
1937         dictionary["PCRE"] = checkAvailability("PCRE") ? defaultTo("PCRE") : "qt";
1938
1939     // ICU detection
1940     if (dictionary["ICU"] == "auto")
1941         dictionary["ICU"] = checkAvailability("ICU") ? "yes" : "no";
1942
1943     // Image format detection
1944     if (dictionary["GIF"] == "auto")
1945         dictionary["GIF"] = defaultTo("GIF");
1946     if (dictionary["JPEG"] == "auto")
1947         dictionary["JPEG"] = defaultTo("JPEG");
1948     if (dictionary["PNG"] == "auto")
1949         dictionary["PNG"] = defaultTo("PNG");
1950     if (dictionary["LIBJPEG"] == "auto")
1951         dictionary["LIBJPEG"] = checkAvailability("LIBJPEG") ? defaultTo("LIBJPEG") : "qt";
1952     if (dictionary["LIBPNG"] == "auto")
1953         dictionary["LIBPNG"] = checkAvailability("LIBPNG") ? defaultTo("LIBPNG") : "qt";
1954
1955     // SQL detection (not on by default)
1956     if (dictionary["SQL_MYSQL"] == "auto")
1957         dictionary["SQL_MYSQL"] = checkAvailability("SQL_MYSQL") ? defaultTo("SQL_MYSQL") : "no";
1958     if (dictionary["SQL_ODBC"] == "auto")
1959         dictionary["SQL_ODBC"] = checkAvailability("SQL_ODBC") ? defaultTo("SQL_ODBC") : "no";
1960     if (dictionary["SQL_OCI"] == "auto")
1961         dictionary["SQL_OCI"] = checkAvailability("SQL_OCI") ? defaultTo("SQL_OCI") : "no";
1962     if (dictionary["SQL_PSQL"] == "auto")
1963         dictionary["SQL_PSQL"] = checkAvailability("SQL_PSQL") ? defaultTo("SQL_PSQL") : "no";
1964     if (dictionary["SQL_TDS"] == "auto")
1965         dictionary["SQL_TDS"] = checkAvailability("SQL_TDS") ? defaultTo("SQL_TDS") : "no";
1966     if (dictionary["SQL_DB2"] == "auto")
1967         dictionary["SQL_DB2"] = checkAvailability("SQL_DB2") ? defaultTo("SQL_DB2") : "no";
1968     if (dictionary["SQL_SQLITE"] == "auto")
1969         dictionary["SQL_SQLITE"] = checkAvailability("SQL_SQLITE") ? defaultTo("SQL_SQLITE") : "no";
1970     if (dictionary["SQL_SQLITE_LIB"] == "system")
1971         if (!checkAvailability("SQL_SQLITE_LIB"))
1972             dictionary["SQL_SQLITE_LIB"] = "no";
1973     if (dictionary["SQL_SQLITE2"] == "auto")
1974         dictionary["SQL_SQLITE2"] = checkAvailability("SQL_SQLITE2") ? defaultTo("SQL_SQLITE2") : "no";
1975     if (dictionary["SQL_IBASE"] == "auto")
1976         dictionary["SQL_IBASE"] = checkAvailability("SQL_IBASE") ? defaultTo("SQL_IBASE") : "no";
1977     if (dictionary["MMX"] == "auto")
1978         dictionary["MMX"] = checkAvailability("MMX") ? "yes" : "no";
1979     if (dictionary["3DNOW"] == "auto")
1980         dictionary["3DNOW"] = checkAvailability("3DNOW") ? "yes" : "no";
1981     if (dictionary["SSE"] == "auto")
1982         dictionary["SSE"] = checkAvailability("SSE") ? "yes" : "no";
1983     if (dictionary["SSE2"] == "auto")
1984         dictionary["SSE2"] = checkAvailability("SSE2") ? "yes" : "no";
1985     if (dictionary["IWMMXT"] == "auto")
1986         dictionary["IWMMXT"] = checkAvailability("IWMMXT") ? "yes" : "no";
1987     if (dictionary["OPENSSL"] == "auto")
1988         dictionary["OPENSSL"] = checkAvailability("OPENSSL") ? "yes" : "no";
1989     if (dictionary["DBUS"] == "auto")
1990         dictionary["DBUS"] = checkAvailability("DBUS") ? "yes" : "no";
1991     if (dictionary["V8SNAPSHOT"] == "auto")
1992         dictionary["V8SNAPSHOT"] = (dictionary["V8"] == "yes") && checkAvailability("V8SNAPSHOT") ? "yes" : "no";
1993     if (dictionary["DECLARATIVE_DEBUG"] == "auto")
1994         dictionary["DECLARATIVE_DEBUG"] = dictionary["DECLARATIVE"] == "yes" ? "yes" : "no";
1995     if (dictionary["AUDIO_BACKEND"] == "auto")
1996         dictionary["AUDIO_BACKEND"] = checkAvailability("AUDIO_BACKEND") ? "yes" : "no";
1997     if (dictionary["WMSDK"] == "auto")
1998         dictionary["WMSDK"] = checkAvailability("WMSDK") ? "yes" : "no";
1999
2000     // Qt/WinCE remote test application
2001     if (dictionary["CETEST"] == "auto")
2002         dictionary["CETEST"] = checkAvailability("CETEST") ? "yes" : "no";
2003
2004     // Detection of IncrediBuild buildconsole
2005     if (dictionary["INCREDIBUILD_XGE"] == "auto")
2006         dictionary["INCREDIBUILD_XGE"] = checkAvailability("INCREDIBUILD_XGE") ? "yes" : "no";
2007
2008     // Mark all unknown "auto" to the default value..
2009     for (QMap<QString,QString>::iterator i = dictionary.begin(); i != dictionary.end(); ++i) {
2010         if (i.value() == "auto")
2011             i.value() = defaultTo(i.key());
2012     }
2013 }
2014
2015 bool Configure::verifyConfiguration()
2016 {
2017     if (dictionary["SQL_SQLITE_LIB"] == "no" && dictionary["SQL_SQLITE"] != "no") {
2018         cout << "WARNING: Configure could not detect the presence of a system SQLite3 lib." << endl
2019              << "Configure will therefore continue with the SQLite3 lib bundled with Qt." << endl
2020              << "(Press any key to continue..)";
2021         if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
2022             exit(0);      // Exit cleanly for Ctrl+C
2023
2024         dictionary["SQL_SQLITE_LIB"] = "qt"; // Set to Qt's bundled lib an continue
2025     }
2026     if (dictionary["QMAKESPEC"].endsWith("-g++")
2027         && dictionary["SQL_OCI"] != "no") {
2028         cout << "WARNING: Qt does not support compiling the Oracle database driver with" << endl
2029              << "MinGW, due to lack of such support from Oracle. Consider disabling the" << endl
2030              << "Oracle driver, as the current build will most likely fail." << endl;
2031         cout << "(Press any key to continue..)";
2032         if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
2033             exit(0);      // Exit cleanly for Ctrl+C
2034     }
2035     if (dictionary["QMAKESPEC"].endsWith("win32-msvc.net")) {
2036         cout << "WARNING: The makespec win32-msvc.net is deprecated. Consider using" << endl
2037              << "win32-msvc2002 or win32-msvc2003 instead." << endl;
2038         cout << "(Press any key to continue..)";
2039         if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
2040             exit(0);      // Exit cleanly for Ctrl+C
2041     }
2042     if (0 != dictionary["ARM_FPU_TYPE"].size()) {
2043             QStringList l= QStringList()
2044                     << "softvfp"
2045                     << "softvfp+vfpv2"
2046                     << "vfpv2";
2047             if (!(l.contains(dictionary["ARM_FPU_TYPE"])))
2048                     cout << QString("WARNING: Using unsupported fpu flag: %1").arg(dictionary["ARM_FPU_TYPE"]) << endl;
2049     }
2050     if (dictionary["DIRECTWRITE"] == "yes" && !checkAvailability("DIRECTWRITE")) {
2051         cout << "WARNING: To be able to compile the DirectWrite font engine you will" << endl
2052              << "need the Microsoft DirectWrite and Microsoft Direct2D development" << endl
2053              << "files such as headers and libraries." << endl
2054              << "(Press any key to continue..)";
2055         if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
2056             exit(0);      // Exit cleanly for Ctrl+C
2057     }
2058
2059     return true;
2060 }
2061
2062 /*
2063  Things that affect the Qt API/ABI:
2064    Options:
2065      minimal-config small-config medium-config large-config full-config
2066
2067    Options:
2068      debug release
2069      stl
2070
2071  Things that do not affect the Qt API/ABI:
2072      system-jpeg no-jpeg jpeg
2073      system-png no-png png
2074      system-zlib no-zlib zlib
2075      no-gif gif
2076      dll staticlib
2077
2078      nocrosscompiler
2079      GNUmake
2080      largefile
2081      nis
2082      nas
2083      tablet
2084
2085      X11     : x11sm xinerama xcursor xfixes xrandr xrender fontconfig xkb
2086      Embedded: embedded freetype
2087 */
2088 void Configure::generateBuildKey()
2089 {
2090     QString spec = dictionary["QMAKESPEC"];
2091
2092     QString compiler = "msvc"; // ICC is compatible
2093     if (spec.endsWith("-g++"))
2094         compiler = "mingw";
2095     else if (spec.endsWith("-borland"))
2096         compiler = "borland";
2097
2098     // Build options which changes the Qt API/ABI
2099     QStringList build_options;
2100     if (!dictionary["QCONFIG"].isEmpty())
2101         build_options += dictionary["QCONFIG"] + "-config ";
2102     build_options.sort();
2103
2104     // Sorted defines that start with QT_NO_
2105     QStringList build_defines = qmakeDefines.filter(QRegExp("^QT_NO_"));
2106     build_defines.sort();
2107 }
2108
2109 void Configure::generateOutputVars()
2110 {
2111     // Generate variables for output
2112     QString build = dictionary[ "BUILD" ];
2113     bool buildAll = (dictionary[ "BUILDALL" ] == "yes");
2114     if (build == "debug") {
2115         if (buildAll)
2116             qtConfig += "release";
2117         qtConfig += "debug";
2118     } else if (build == "release") {
2119         if (buildAll)
2120             qtConfig += "debug";
2121         qtConfig += "release";
2122     }
2123
2124     if (dictionary[ "WIDGETS" ] == "no")
2125         qtConfig += "no-widgets";
2126
2127     // Compression --------------------------------------------------
2128     if (dictionary[ "ZLIB" ] == "qt")
2129         qtConfig += "zlib";
2130     else if (dictionary[ "ZLIB" ] == "system")
2131         qtConfig += "system-zlib";
2132
2133     // PCRE ---------------------------------------------------------
2134     if (dictionary[ "PCRE" ] == "qt")
2135         qmakeConfig += "pcre";
2136
2137     // ICU ---------------------------------------------------------
2138     if (dictionary[ "ICU" ] == "yes")
2139         qtConfig  += "icu";
2140
2141     // Image formates -----------------------------------------------
2142     if (dictionary[ "GIF" ] == "no")
2143         qtConfig += "no-gif";
2144     else if (dictionary[ "GIF" ] == "yes")
2145         qtConfig += "gif";
2146
2147     if (dictionary[ "JPEG" ] == "no")
2148         qtConfig += "no-jpeg";
2149     else if (dictionary[ "JPEG" ] == "yes")
2150         qtConfig += "jpeg";
2151     if (dictionary[ "LIBJPEG" ] == "system")
2152         qtConfig += "system-jpeg";
2153
2154     if (dictionary[ "PNG" ] == "no")
2155         qtConfig += "no-png";
2156     else if (dictionary[ "PNG" ] == "yes")
2157         qtConfig += "png";
2158     if (dictionary[ "LIBPNG" ] == "system")
2159         qtConfig += "system-png";
2160
2161     // Text rendering --------------------------------------------------
2162     if (dictionary[ "FREETYPE" ] == "yes")
2163         qtConfig += "freetype";
2164
2165     // Styles -------------------------------------------------------
2166     if (dictionary[ "STYLE_WINDOWS" ] == "yes")
2167         qmakeStyles += "windows";
2168
2169     if (dictionary[ "STYLE_PLASTIQUE" ] == "yes")
2170         qmakeStyles += "plastique";
2171
2172     if (dictionary[ "STYLE_CLEANLOOKS" ] == "yes")
2173         qmakeStyles += "cleanlooks";
2174
2175     if (dictionary[ "STYLE_WINDOWSXP" ] == "yes")
2176         qmakeStyles += "windowsxp";
2177
2178     if (dictionary[ "STYLE_WINDOWSVISTA" ] == "yes")
2179         qmakeStyles += "windowsvista";
2180
2181     if (dictionary[ "STYLE_MOTIF" ] == "yes")
2182         qmakeStyles += "motif";
2183
2184     if (dictionary[ "STYLE_SGI" ] == "yes")
2185         qmakeStyles += "sgi";
2186
2187     if (dictionary[ "STYLE_WINDOWSCE" ] == "yes")
2188     qmakeStyles += "windowsce";
2189
2190     if (dictionary[ "STYLE_WINDOWSMOBILE" ] == "yes")
2191     qmakeStyles += "windowsmobile";
2192
2193     if (dictionary[ "STYLE_CDE" ] == "yes")
2194         qmakeStyles += "cde";
2195
2196     // Databases ----------------------------------------------------
2197     if (dictionary[ "SQL_MYSQL" ] == "yes")
2198         qmakeSql += "mysql";
2199     else if (dictionary[ "SQL_MYSQL" ] == "plugin")
2200         qmakeSqlPlugins += "mysql";
2201
2202     if (dictionary[ "SQL_ODBC" ] == "yes")
2203         qmakeSql += "odbc";
2204     else if (dictionary[ "SQL_ODBC" ] == "plugin")
2205         qmakeSqlPlugins += "odbc";
2206
2207     if (dictionary[ "SQL_OCI" ] == "yes")
2208         qmakeSql += "oci";
2209     else if (dictionary[ "SQL_OCI" ] == "plugin")
2210         qmakeSqlPlugins += "oci";
2211
2212     if (dictionary[ "SQL_PSQL" ] == "yes")
2213         qmakeSql += "psql";
2214     else if (dictionary[ "SQL_PSQL" ] == "plugin")
2215         qmakeSqlPlugins += "psql";
2216
2217     if (dictionary[ "SQL_TDS" ] == "yes")
2218         qmakeSql += "tds";
2219     else if (dictionary[ "SQL_TDS" ] == "plugin")
2220         qmakeSqlPlugins += "tds";
2221
2222     if (dictionary[ "SQL_DB2" ] == "yes")
2223         qmakeSql += "db2";
2224     else if (dictionary[ "SQL_DB2" ] == "plugin")
2225         qmakeSqlPlugins += "db2";
2226
2227     if (dictionary[ "SQL_SQLITE" ] == "yes")
2228         qmakeSql += "sqlite";
2229     else if (dictionary[ "SQL_SQLITE" ] == "plugin")
2230         qmakeSqlPlugins += "sqlite";
2231
2232     if (dictionary[ "SQL_SQLITE_LIB" ] == "system")
2233         qmakeConfig += "system-sqlite";
2234
2235     if (dictionary[ "SQL_SQLITE2" ] == "yes")
2236         qmakeSql += "sqlite2";
2237     else if (dictionary[ "SQL_SQLITE2" ] == "plugin")
2238         qmakeSqlPlugins += "sqlite2";
2239
2240     if (dictionary[ "SQL_IBASE" ] == "yes")
2241         qmakeSql += "ibase";
2242     else if (dictionary[ "SQL_IBASE" ] == "plugin")
2243         qmakeSqlPlugins += "ibase";
2244
2245     // Other options ------------------------------------------------
2246     if (dictionary[ "BUILDALL" ] == "yes") {
2247         qtConfig += "build_all";
2248     }
2249     qmakeConfig += dictionary[ "BUILD" ];
2250     dictionary[ "QMAKE_OUTDIR" ] = dictionary[ "BUILD" ];
2251
2252     if (dictionary["MSVC_MP"] == "yes")
2253         qmakeConfig += "msvc_mp";
2254
2255     if (dictionary[ "SHARED" ] == "yes") {
2256         QString version = dictionary[ "VERSION" ];
2257         if (!version.isEmpty()) {
2258             qmakeVars += "QMAKE_QT_VERSION_OVERRIDE = " + version.left(version.indexOf("."));
2259             version.remove(QLatin1Char('.'));
2260         }
2261         dictionary[ "QMAKE_OUTDIR" ] += "_shared";
2262     } else {
2263         dictionary[ "QMAKE_OUTDIR" ] += "_static";
2264     }
2265
2266     if (dictionary[ "ACCESSIBILITY" ] == "yes")
2267         qtConfig += "accessibility";
2268
2269     if (!qmakeLibs.isEmpty())
2270         qmakeVars += "LIBS           += " + escapeSeparators(qmakeLibs.join(" "));
2271
2272     if (!dictionary["QT_LFLAGS_SQLITE"].isEmpty())
2273         qmakeVars += "QT_LFLAGS_SQLITE += " + escapeSeparators(dictionary["QT_LFLAGS_SQLITE"]);
2274
2275     if (dictionary[ "OPENGL" ] == "yes")
2276         qtConfig += "opengl";
2277
2278     if (dictionary["OPENGL_ES_CM"] == "yes") {
2279         qtConfig += "opengles1";
2280         qtConfig += "egl";
2281     }
2282
2283     if (dictionary["OPENGL_ES_2"] == "yes") {
2284         qtConfig += "opengles2";
2285         qtConfig += "egl";
2286     }
2287
2288     if (dictionary["OPENVG"] == "yes") {
2289         qtConfig += "openvg";
2290         qtConfig += "egl";
2291     }
2292
2293     // ### Vestige
2294      if (dictionary["DIRECTSHOW"] == "yes")
2295         qtConfig += "directshow";
2296
2297     if (dictionary[ "OPENSSL" ] == "yes")
2298         qtConfig += "openssl";
2299     else if (dictionary[ "OPENSSL" ] == "linked")
2300         qtConfig += "openssl-linked";
2301
2302     if (dictionary[ "DBUS" ] == "yes")
2303         qtConfig += "dbus";
2304     else if (dictionary[ "DBUS" ] == "linked")
2305         qtConfig += "dbus dbus-linked";
2306
2307     if (dictionary[ "CETEST" ] == "yes")
2308         qtConfig += "cetest";
2309
2310     // ### Vestige
2311     if (dictionary["PHONON_BACKEND"] == "yes")
2312         qtConfig += "phonon-backend";
2313
2314     // ### Vestige
2315     if (dictionary["AUDIO_BACKEND"] == "yes")
2316         qtConfig += "audio-backend";
2317
2318     if (dictionary["DIRECTWRITE"] == "yes")
2319         qtConfig += "directwrite";
2320
2321     if (dictionary[ "NATIVE_GESTURES" ] == "yes")
2322         qtConfig += "native-gestures";
2323
2324     // We currently have no switch for QtConcurrent, so add it unconditionally.
2325     qtConfig += "concurrent";
2326
2327     // ### Vestige
2328     if (dictionary[ "V8SNAPSHOT" ] == "yes")
2329         qtConfig += "v8snapshot";
2330
2331     // Add config levels --------------------------------------------
2332     QStringList possible_configs = QStringList()
2333         << "minimal"
2334         << "small"
2335         << "medium"
2336         << "large"
2337         << "full";
2338
2339     QString set_config = dictionary["QCONFIG"];
2340     if (possible_configs.contains(set_config)) {
2341         foreach (const QString &cfg, possible_configs) {
2342             qtConfig += (cfg + "-config");
2343             if (cfg == set_config)
2344                 break;
2345         }
2346     }
2347
2348     if (dictionary.contains("XQMAKESPEC") && (dictionary["QMAKESPEC"] != dictionary["XQMAKESPEC"])) {
2349             qmakeConfig += "cross_compile";
2350             dictionary["CROSS_COMPILE"] = "yes";
2351     }
2352
2353     // Directories and settings for .qmake.cache --------------------
2354
2355     // if QT_INSTALL_* have not been specified on commandline, define them now from QT_INSTALL_PREFIX
2356     // if prefix is empty (WINCE), make all of them empty, if they aren't set
2357     bool qipempty = false;
2358     if (dictionary[ "QT_INSTALL_PREFIX" ].isEmpty())
2359         qipempty = true;
2360
2361     if (!dictionary[ "QT_INSTALL_DOCS" ].size())
2362         dictionary[ "QT_INSTALL_DOCS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/doc");
2363     if (!dictionary[ "QT_INSTALL_HEADERS" ].size())
2364         dictionary[ "QT_INSTALL_HEADERS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/include");
2365     if (!dictionary[ "QT_INSTALL_LIBS" ].size())
2366         dictionary[ "QT_INSTALL_LIBS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/lib");
2367     if (!dictionary[ "QT_INSTALL_BINS" ].size())
2368         dictionary[ "QT_INSTALL_BINS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/bin");
2369     if (!dictionary[ "QT_INSTALL_PLUGINS" ].size())
2370         dictionary[ "QT_INSTALL_PLUGINS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/plugins");
2371     if (!dictionary[ "QT_INSTALL_IMPORTS" ].size())
2372         dictionary[ "QT_INSTALL_IMPORTS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/imports");
2373     if (!dictionary[ "QT_INSTALL_DATA" ].size())
2374         dictionary[ "QT_INSTALL_DATA" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ]);
2375     if (!dictionary[ "QT_INSTALL_TRANSLATIONS" ].size())
2376         dictionary[ "QT_INSTALL_TRANSLATIONS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/translations");
2377     if (!dictionary[ "QT_INSTALL_EXAMPLES" ].size())
2378         dictionary[ "QT_INSTALL_EXAMPLES" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/examples");
2379     if (!dictionary[ "QT_INSTALL_TESTS" ].size())
2380         dictionary[ "QT_INSTALL_TESTS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/tests");
2381
2382     bool haveHpx = false;
2383     if (dictionary[ "QT_HOST_PREFIX" ].isEmpty())
2384         dictionary[ "QT_HOST_PREFIX" ] = dictionary[ "QT_INSTALL_PREFIX" ];
2385     else
2386         haveHpx = true;
2387     if (dictionary[ "QT_HOST_BINS" ].isEmpty())
2388         dictionary[ "QT_HOST_BINS" ] = haveHpx ? fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/bin") : dictionary[ "QT_INSTALL_BINS" ];
2389     if (dictionary[ "QT_HOST_DATA" ].isEmpty())
2390         dictionary[ "QT_HOST_DATA" ] = haveHpx ? dictionary[ "QT_HOST_PREFIX" ] : dictionary[ "QT_INSTALL_DATA" ];
2391
2392     if (dictionary.contains("XQMAKESPEC") && dictionary[ "XQMAKESPEC" ].startsWith("linux"))
2393         dictionary[ "QMAKE_RPATHDIR" ] = dictionary[ "QT_INSTALL_LIBS" ];
2394
2395     qmakeVars += QString("OBJECTS_DIR     = ") + fixSeparators("tmp/obj/" + dictionary[ "QMAKE_OUTDIR" ], true);
2396     qmakeVars += QString("MOC_DIR         = ") + fixSeparators("tmp/moc/" + dictionary[ "QMAKE_OUTDIR" ], true);
2397     qmakeVars += QString("RCC_DIR         = ") + fixSeparators("tmp/rcc/" + dictionary["QMAKE_OUTDIR"], true);
2398
2399     if (!qmakeDefines.isEmpty())
2400         qmakeVars += QString("DEFINES        += ") + qmakeDefines.join(" ");
2401     if (!qmakeIncludes.isEmpty())
2402         qmakeVars += QString("INCLUDEPATH    += ") + escapeSeparators(qmakeIncludes.join(" "));
2403     if (!opensslLibs.isEmpty())
2404         qmakeVars += opensslLibs;
2405     else if (dictionary[ "OPENSSL" ] == "linked")
2406         qmakeVars += QString("OPENSSL_LIBS    = -lssleay32 -llibeay32");
2407     if (!psqlLibs.isEmpty())
2408         qmakeVars += QString("QT_LFLAGS_PSQL=") + psqlLibs.section("=", 1);
2409
2410     {
2411         QStringList lflagsTDS;
2412         if (!sybase.isEmpty())
2413             lflagsTDS += QString("-L") + fixSeparators(sybase.section("=", 1) + "/lib");
2414         if (!sybaseLibs.isEmpty())
2415             lflagsTDS += sybaseLibs.section("=", 1);
2416         if (!lflagsTDS.isEmpty())
2417             qmakeVars += QString("QT_LFLAGS_TDS=") + lflagsTDS.join(" ");
2418     }
2419
2420     if (!qmakeSql.isEmpty())
2421         qmakeVars += QString("sql-drivers    += ") + qmakeSql.join(" ");
2422     if (!qmakeSqlPlugins.isEmpty())
2423         qmakeVars += QString("sql-plugins    += ") + qmakeSqlPlugins.join(" ");
2424     if (!qmakeStyles.isEmpty())
2425         qmakeVars += QString("styles         += ") + qmakeStyles.join(" ");
2426     if (!qmakeStylePlugins.isEmpty())
2427         qmakeVars += QString("style-plugins  += ") + qmakeStylePlugins.join(" ");
2428
2429     if (dictionary["QMAKESPEC"].endsWith("-g++")) {
2430         QString includepath = qgetenv("INCLUDE");
2431         bool hasSh = Environment::detectExecutable("sh.exe");
2432         QChar separator = (!includepath.contains(":\\") && hasSh ? QChar(':') : QChar(';'));
2433         qmakeVars += QString("TMPPATH            = $$quote($$(INCLUDE))");
2434         qmakeVars += QString("QMAKE_INCDIR_POST += $$split(TMPPATH,\"%1\")").arg(separator);
2435         qmakeVars += QString("TMPPATH            = $$quote($$(LIB))");
2436         qmakeVars += QString("QMAKE_LIBDIR_POST += $$split(TMPPATH,\"%1\")").arg(separator);
2437     }
2438
2439     if (!dictionary[ "QMAKESPEC" ].length()) {
2440         cout << "Configure could not detect your compiler. QMAKESPEC must either" << endl
2441              << "be defined as an environment variable, or specified as an" << endl
2442              << "argument with -platform" << endl;
2443         dictionary[ "HELP" ] = "yes";
2444
2445         QStringList winPlatforms;
2446         QDir mkspecsDir(sourcePath + "/mkspecs");
2447         const QFileInfoList &specsList = mkspecsDir.entryInfoList();
2448         for (int i = 0; i < specsList.size(); ++i) {
2449             const QFileInfo &fi = specsList.at(i);
2450             if (fi.fileName().left(5) == "win32") {
2451                 winPlatforms += fi.fileName();
2452             }
2453         }
2454         cout << "Available platforms are: " << qPrintable(winPlatforms.join(", ")) << endl;
2455         dictionary[ "DONE" ] = "error";
2456     }
2457 }
2458
2459 #if !defined(EVAL)
2460 void Configure::generateCachefile()
2461 {
2462     // Generate .qmake.cache
2463     QFile cacheFile(buildPath + "/.qmake.cache");
2464     if (cacheFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
2465         QTextStream cacheStream(&cacheFile);
2466
2467         cacheStream << "include($$PWD/mkspecs/qmodule.pri)" << endl;
2468
2469         for (QStringList::Iterator var = qmakeVars.begin(); var != qmakeVars.end(); ++var) {
2470             cacheStream << (*var) << endl;
2471         }
2472         cacheStream << "CONFIG         += " << qmakeConfig.join(" ") << "depend_includepath no_private_qt_headers_warning QTDIR_build" << endl;
2473
2474         cacheStream.flush();
2475         cacheFile.close();
2476     }
2477
2478     // Generate qmodule.pri
2479     QFile moduleFile(dictionary[ "QT_BUILD_TREE" ] + "/mkspecs/qmodule.pri");
2480     if (moduleFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
2481         QTextStream moduleStream(&moduleFile);
2482
2483         moduleStream << "#paths" << endl;
2484         moduleStream << "QT_BUILD_TREE   = " << fixSeparators(dictionary[ "QT_BUILD_TREE" ], true) << endl;
2485         moduleStream << "QT_SOURCE_TREE  = " << fixSeparators(dictionary[ "QT_SOURCE_TREE" ], true) << endl;
2486         QStringList buildParts;
2487         buildParts << QStringLiteral("libs") << QStringLiteral("examples") << QStringLiteral("tests");
2488         foreach (const QString &item, disabledBuildParts) {
2489             buildParts.removeAll(item);
2490         }
2491         moduleStream << "QT_BUILD_PARTS  = " << buildParts.join(" ") << endl << endl;
2492
2493         //so that we can build without an install first (which would be impossible)
2494         moduleStream << "#local paths that cannot be queried from the QT_INSTALL_* properties while building QTDIR" << endl;
2495         moduleStream << "QMAKE_INCDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/include", true) << endl;
2496         moduleStream << "QMAKE_LIBDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/lib", true) << endl;
2497
2498
2499         QString targetSpec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
2500         QString mkspec_path = fixSeparators(sourcePath + "/mkspecs/" + targetSpec);
2501         if (QFile::exists(mkspec_path))
2502             moduleStream << "QMAKESPEC       = " << escapeSeparators(mkspec_path) << endl;
2503         else
2504             moduleStream << "QMAKESPEC       = " << fixSeparators(targetSpec, true) << endl;
2505
2506         if (dictionary["QT_EDITION"] != "QT_EDITION_OPENSOURCE")
2507             moduleStream << "DEFINES        *= QT_EDITION=QT_EDITION_DESKTOP" << endl;
2508
2509         if (dictionary["CETEST"] == "yes") {
2510             moduleStream << "QT_CE_RAPI_INC  = " << fixSeparators(dictionary[ "QT_CE_RAPI_INC" ], true) << endl;
2511             moduleStream << "QT_CE_RAPI_LIB  = " << fixSeparators(dictionary[ "QT_CE_RAPI_LIB" ], true) << endl;
2512         }
2513
2514         moduleStream << "#Qt for Windows CE c-runtime deployment" << endl
2515                      << "QT_CE_C_RUNTIME = " << fixSeparators(dictionary[ "CE_CRT" ], true) << endl;
2516
2517         if (dictionary["CE_SIGNATURE"] != QLatin1String("no"))
2518             moduleStream << "DEFAULT_SIGNATURE=" << dictionary["CE_SIGNATURE"] << endl;
2519
2520         if (!dictionary["QMAKE_RPATHDIR"].isEmpty())
2521             moduleStream << "QMAKE_RPATHDIR += " << dictionary["QMAKE_RPATHDIR"] << endl;
2522
2523         if (!dictionary["QT_LIBINFIX"].isEmpty())
2524             moduleStream << "QT_LIBINFIX = " << dictionary["QT_LIBINFIX"] << endl;
2525
2526         if (!dictionary["QT_NAMESPACE"].isEmpty()) {
2527             moduleStream << "#namespaces" << endl << "QT_NAMESPACE = " << dictionary["QT_NAMESPACE"] << endl;
2528         }
2529
2530         // embedded
2531         if (!dictionary["KBD_DRIVERS"].isEmpty())
2532             moduleStream << "kbd-drivers += "<< dictionary["KBD_DRIVERS"]<<endl;
2533         if (!dictionary["GFX_DRIVERS"].isEmpty())
2534             moduleStream << "gfx-drivers += "<< dictionary["GFX_DRIVERS"]<<endl;
2535         if (!dictionary["MOUSE_DRIVERS"].isEmpty())
2536             moduleStream << "mouse-drivers += "<< dictionary["MOUSE_DRIVERS"]<<endl;
2537         if (!dictionary["DECORATIONS"].isEmpty())
2538             moduleStream << "decorations += "<<dictionary["DECORATIONS"]<<endl;
2539
2540         if (!dictionary["QMAKE_RPATHDIR"].isEmpty())
2541             moduleStream << "QMAKE_RPATHDIR += "<<dictionary["QMAKE_RPATHDIR"]<<endl;
2542
2543         moduleStream << "CONFIG += create_prl link_prl" << endl;
2544
2545         moduleStream.flush();
2546         moduleFile.close();
2547     }
2548 }
2549
2550 /*
2551     Runs qmake on config.tests/arch/arch.pro, which will detect the target arch
2552     for the compiler we are using
2553 */
2554 void Configure::detectArch()
2555 {
2556     QString oldpwd = QDir::currentPath();
2557
2558     QString newpwd = fixSeparators(QString("%1/config.tests/arch").arg(buildPath));
2559     if (!QDir().exists(newpwd) && !QDir().mkpath(newpwd)) {
2560         cout << "Failed to create directory " << qPrintable(newpwd) << endl;
2561         dictionary["DONE"] = "error";
2562         return;
2563     }
2564     if (!QDir::setCurrent(newpwd)) {
2565         cout << "Failed to change working directory to " << qPrintable(newpwd) << endl;
2566         dictionary["DONE"] = "error";
2567         return;
2568     }
2569
2570     QList<QPair<QString, QString> > qmakespecs;
2571     if (dictionary.contains("XQMAKESPEC"))
2572         qmakespecs << qMakePair(QString("XQMAKESPEC"), QString("QT_ARCH"));
2573     qmakespecs << qMakePair(QString("QMAKESPEC"), QString("QT_HOST_ARCH"));
2574
2575     for (int i = 0; i < qmakespecs.count(); ++i) {
2576         const QPair<QString, QString> &pair = qmakespecs.at(i);
2577         QString qmakespec = dictionary.value(pair.first);
2578         QString key = pair.second;
2579
2580         QString command =
2581                 fixSeparators(QString("%1/bin/qmake.exe -spec %2 %3/config.tests/arch/arch.pro -o %4/Makefile.unused 2>&1")
2582                               .arg(buildPath, qmakespec, sourcePath, newpwd));
2583         QString output = Environment::execute(command);
2584         if (output.isEmpty())
2585             continue;
2586
2587         QRegExp re("Project MESSAGE:.*Architecture: ([a-zA-Z0-9]*)");
2588         if (re.indexIn(output) != -1)
2589             dictionary[key] = re.cap(1);
2590     }
2591
2592     if (!dictionary.contains("QT_HOST_ARCH"))
2593         dictionary["QT_HOST_ARCH"] = "unknown";
2594     if (!dictionary.contains("QT_ARCH"))
2595         dictionary["QT_ARCH"] = dictionary["QT_HOST_ARCH"];
2596
2597     QDir::setCurrent(oldpwd);
2598 }
2599
2600 void Configure::generateQConfigPri()
2601 {
2602     // Generate qconfig.pri
2603     QFile configFile(dictionary[ "QT_BUILD_TREE" ] + "/mkspecs/qconfig.pri");
2604     if (configFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
2605         QTextStream configStream(&configFile);
2606
2607         configStream << "CONFIG+= ";
2608         configStream << dictionary[ "BUILD" ];
2609         if (dictionary[ "SHARED" ] == "yes")
2610             configStream << " shared";
2611         else
2612             configStream << " static";
2613
2614         if (dictionary[ "LTCG" ] == "yes")
2615             configStream << " ltcg";
2616         if (dictionary[ "STL" ] == "yes")
2617             configStream << " stl";
2618         if (dictionary[ "EXCEPTIONS" ] == "yes")
2619             configStream << " exceptions";
2620         if (dictionary[ "EXCEPTIONS" ] == "no")
2621             configStream << " exceptions_off";
2622         if (dictionary[ "RTTI" ] == "yes")
2623             configStream << " rtti";
2624         if (dictionary[ "MMX" ] == "yes")
2625             configStream << " mmx";
2626         if (dictionary[ "3DNOW" ] == "yes")
2627             configStream << " 3dnow";
2628         if (dictionary[ "SSE" ] == "yes")
2629             configStream << " sse";
2630         if (dictionary[ "SSE2" ] == "yes")
2631             configStream << " sse2";
2632         if (dictionary[ "IWMMXT" ] == "yes")
2633             configStream << " iwmmxt";
2634         if (dictionary["INCREDIBUILD_XGE"] == "yes")
2635             configStream << " incredibuild_xge";
2636         if (dictionary["PLUGIN_MANIFESTS"] == "no")
2637             configStream << " no_plugin_manifest";
2638         if (dictionary["QPA"] == "yes")
2639             configStream << " qpa";
2640         if (dictionary["CROSS_COMPILE"] == "yes")
2641             configStream << " cross_compile";
2642
2643         if (dictionary["DIRECTWRITE"] == "yes")
2644             configStream << "directwrite";
2645
2646         configStream << endl;
2647         configStream << "QT_ARCH = " << dictionary["QT_ARCH"] << endl;
2648         configStream << "QT_HOST_ARCH = " << dictionary["QT_HOST_ARCH"] << endl;
2649         if (dictionary["QT_EDITION"].contains("OPENSOURCE"))
2650             configStream << "QT_EDITION = " << QLatin1String("OpenSource") << endl;
2651         else
2652             configStream << "QT_EDITION = " << dictionary["EDITION"] << endl;
2653         configStream << "QT_CONFIG += " << qtConfig.join(" ") << endl;
2654
2655         configStream << "#versioning " << endl
2656                      << "QT_VERSION = " << dictionary["VERSION"] << endl
2657                      << "QT_MAJOR_VERSION = " << dictionary["VERSION_MAJOR"] << endl
2658                      << "QT_MINOR_VERSION = " << dictionary["VERSION_MINOR"] << endl
2659                      << "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl;
2660
2661         if (!dictionary["CFG_SYSROOT"].isEmpty()) {
2662             QString targetSpec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
2663             configStream << endl
2664                          << "# sysroot" << endl
2665                          << targetSpec << " {" << endl
2666                          << "    QMAKE_CFLAGS    += --sysroot=$$[QT_SYSROOT]" << endl
2667                          << "    QMAKE_CXXFLAGS  += --sysroot=$$[QT_SYSROOT]" << endl
2668                          << "    QMAKE_LFLAGS    += --sysroot=$$[QT_SYSROOT]" << endl
2669                          << "}" << endl;
2670         }
2671
2672         configStream.flush();
2673         configFile.close();
2674     }
2675 }
2676 #endif
2677
2678 QString Configure::addDefine(QString def)
2679 {
2680     QString result, defNeg, defD = def;
2681
2682     defD.replace(QRegExp("=.*"), "");
2683     def.replace(QRegExp("="), " ");
2684
2685     if (def.startsWith("QT_NO_")) {
2686         defNeg = defD;
2687         defNeg.replace("QT_NO_", "QT_");
2688     } else if (def.startsWith("QT_")) {
2689         defNeg = defD;
2690         defNeg.replace("QT_", "QT_NO_");
2691     }
2692
2693     if (defNeg.isEmpty()) {
2694         result = "#ifndef $DEFD\n"
2695                  "# define $DEF\n"
2696                  "#endif\n\n";
2697     } else {
2698         result = "#if defined($DEFD) && defined($DEFNEG)\n"
2699                  "# undef $DEFD\n"
2700                  "#elif !defined($DEFD)\n"
2701                  "# define $DEF\n"
2702                  "#endif\n\n";
2703     }
2704     result.replace("$DEFNEG", defNeg);
2705     result.replace("$DEFD", defD);
2706     result.replace("$DEF", def);
2707     return result;
2708 }
2709
2710 #if !defined(EVAL)
2711 bool Configure::copySpec(const char *name, const char *pfx, const QString &spec)
2712 {
2713     // Copy configured mkspec to default directory, but remove the old one first, if there is any
2714     QString defSpec = buildPath + "/mkspecs/" + name;
2715     QFileInfo defSpecInfo(defSpec);
2716     if (defSpecInfo.exists()) {
2717         if (!Environment::rmdir(defSpec)) {
2718             cout << "Couldn't update default " << pfx << "mkspec! Are files in " << qPrintable(defSpec) << " read-only?" << endl;
2719             dictionary["DONE"] = "error";
2720             return false;
2721         }
2722     }
2723
2724     QString pltSpec = sourcePath + "/mkspecs/" + spec;
2725     QString includeSpec = buildPath + "/mkspecs/" + spec;
2726     if (!Environment::cpdir(pltSpec, defSpec, includeSpec)) {
2727         cout << "Couldn't update default " << pfx << "mkspec! Does " << qPrintable(pltSpec) << " exist?" << endl;
2728         dictionary["DONE"] = "error";
2729         return false;
2730     }
2731     return true;
2732 }
2733
2734 void Configure::generateConfigfiles()
2735 {
2736     QDir(buildPath).mkpath("src/corelib/global");
2737     QString outName(buildPath + "/src/corelib/global/qconfig.h");
2738     QTemporaryFile tmpFile;
2739     QTextStream tmpStream;
2740
2741     if (tmpFile.open()) {
2742         tmpStream.setDevice(&tmpFile);
2743
2744         if (dictionary[ "QCONFIG" ] == "full") {
2745             tmpStream << "/* Everything */" << endl;
2746         } else {
2747             QString configName("qconfig-" + dictionary[ "QCONFIG" ] + ".h");
2748             tmpStream << "/* Copied from " << configName << "*/" << endl;
2749             tmpStream << "#ifndef QT_BOOTSTRAPPED" << endl;
2750             QFile inFile(sourcePath + "/src/corelib/global/" + configName);
2751             if (inFile.open(QFile::ReadOnly)) {
2752                 QByteArray buffer = inFile.readAll();
2753                 tmpFile.write(buffer.constData(), buffer.size());
2754                 inFile.close();
2755             }
2756             tmpStream << "#endif // QT_BOOTSTRAPPED" << endl;
2757         }
2758         tmpStream << endl;
2759
2760         if (dictionary[ "SHARED" ] == "yes") {
2761             tmpStream << "#ifndef QT_DLL" << endl;
2762             tmpStream << "#define QT_DLL" << endl;
2763             tmpStream << "#endif" << endl;
2764         }
2765         tmpStream << endl;
2766         tmpStream << "/* License information */" << endl;
2767         tmpStream << "#define QT_PRODUCT_LICENSEE \"" << licenseInfo[ "LICENSEE" ] << "\"" << endl;
2768         tmpStream << "#define QT_PRODUCT_LICENSE \"" << dictionary[ "EDITION" ] << "\"" << endl;
2769         tmpStream << endl;
2770         tmpStream << "// Qt Edition" << endl;
2771         tmpStream << "#ifndef QT_EDITION" << endl;
2772         tmpStream << "#  define QT_EDITION " << dictionary["QT_EDITION"] << endl;
2773         tmpStream << "#endif" << endl;
2774         tmpStream << endl;
2775         if (dictionary["BUILDDEV"] == "yes") {
2776             dictionary["QMAKE_INTERNAL"] = "yes";
2777             tmpStream << "/* Used for example to export symbols for the certain autotests*/" << endl;
2778             tmpStream << "#define QT_BUILD_INTERNAL" << endl;
2779             tmpStream << endl;
2780         }
2781
2782         if (dictionary[ "QPA" ] == "yes")
2783             tmpStream << endl << "#define Q_WS_QPA" << endl;
2784
2785         tmpStream << endl << "// Compile time features" << endl;
2786
2787         QStringList qconfigList;
2788         if (dictionary["STL"] == "no")                qconfigList += "QT_NO_STL";
2789         if (dictionary["STYLE_WINDOWS"] != "yes")     qconfigList += "QT_NO_STYLE_WINDOWS";
2790         if (dictionary["STYLE_PLASTIQUE"] != "yes")   qconfigList += "QT_NO_STYLE_PLASTIQUE";
2791         if (dictionary["STYLE_CLEANLOOKS"] != "yes")   qconfigList += "QT_NO_STYLE_CLEANLOOKS";
2792         if (dictionary["STYLE_WINDOWSXP"] != "yes" && dictionary["STYLE_WINDOWSVISTA"] != "yes")
2793             qconfigList += "QT_NO_STYLE_WINDOWSXP";
2794         if (dictionary["STYLE_WINDOWSVISTA"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSVISTA";
2795         if (dictionary["STYLE_MOTIF"] != "yes")       qconfigList += "QT_NO_STYLE_MOTIF";
2796         if (dictionary["STYLE_CDE"] != "yes")         qconfigList += "QT_NO_STYLE_CDE";
2797
2798         // ### We still need the QT_NO_STYLE_S60 define for compiling Qt. Remove later!
2799         qconfigList += "QT_NO_STYLE_S60";
2800
2801         if (dictionary["STYLE_WINDOWSCE"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSCE";
2802         if (dictionary["STYLE_WINDOWSMOBILE"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSMOBILE";
2803         if (dictionary["STYLE_GTK"] != "yes")         qconfigList += "QT_NO_STYLE_GTK";
2804
2805         if (dictionary["GIF"] == "yes")              qconfigList += "QT_BUILTIN_GIF_READER=1";
2806         if (dictionary["PNG"] != "yes")              qconfigList += "QT_NO_IMAGEFORMAT_PNG";
2807         if (dictionary["JPEG"] != "yes")             qconfigList += "QT_NO_IMAGEFORMAT_JPEG";
2808         if (dictionary["ZLIB"] == "no") {
2809             qconfigList += "QT_NO_ZLIB";
2810             qconfigList += "QT_NO_COMPRESS";
2811         }
2812
2813         if (dictionary["ACCESSIBILITY"] == "no")     qconfigList += "QT_NO_ACCESSIBILITY";
2814         if (dictionary["EXCEPTIONS"] == "no")        qconfigList += "QT_NO_EXCEPTIONS";
2815         if (dictionary["WIDGETS"] == "no")           qconfigList += "QT_NO_WIDGETS";
2816         if (dictionary["OPENGL"] == "no")            qconfigList += "QT_NO_OPENGL";
2817         if (dictionary["OPENVG"] == "no")            qconfigList += "QT_NO_OPENVG";
2818         if (dictionary["OPENSSL"] == "no") {
2819             qconfigList += "QT_NO_OPENSSL";
2820             qconfigList += "QT_NO_SSL";
2821         }
2822         if (dictionary["OPENSSL"] == "linked")       qconfigList += "QT_LINKED_OPENSSL";
2823         if (dictionary["DBUS"] == "no")              qconfigList += "QT_NO_DBUS";
2824         if (dictionary["DECLARATIVE_DEBUG"] == "no") qconfigList += "QDECLARATIVE_NO_DEBUG_PROTOCOL";
2825         if (dictionary["FREETYPE"] == "no")          qconfigList += "QT_NO_FREETYPE";
2826         if (dictionary["NATIVE_GESTURES"] == "no")   qconfigList += "QT_NO_NATIVE_GESTURES";
2827
2828         if (dictionary["OPENGL_ES_CM"] == "yes" ||
2829            dictionary["OPENGL_ES_2"]  == "yes")     qconfigList += "QT_OPENGL_ES";
2830
2831         if (dictionary["OPENGL_ES_CM"] == "yes")     qconfigList += "QT_OPENGL_ES_1";
2832         if (dictionary["OPENGL_ES_2"]  == "yes")     qconfigList += "QT_OPENGL_ES_2";
2833         if (dictionary["SQL_MYSQL"] == "yes")        qconfigList += "QT_SQL_MYSQL";
2834         if (dictionary["SQL_ODBC"] == "yes")         qconfigList += "QT_SQL_ODBC";
2835         if (dictionary["SQL_OCI"] == "yes")          qconfigList += "QT_SQL_OCI";
2836         if (dictionary["SQL_PSQL"] == "yes")         qconfigList += "QT_SQL_PSQL";
2837         if (dictionary["SQL_TDS"] == "yes")          qconfigList += "QT_SQL_TDS";
2838         if (dictionary["SQL_DB2"] == "yes")          qconfigList += "QT_SQL_DB2";
2839         if (dictionary["SQL_SQLITE"] == "yes")       qconfigList += "QT_SQL_SQLITE";
2840         if (dictionary["SQL_SQLITE2"] == "yes")      qconfigList += "QT_SQL_SQLITE2";
2841         if (dictionary["SQL_IBASE"] == "yes")        qconfigList += "QT_SQL_IBASE";
2842
2843         qconfigList.sort();
2844         for (int i = 0; i < qconfigList.count(); ++i)
2845             tmpStream << addDefine(qconfigList.at(i));
2846
2847         if (dictionary["EMBEDDED"] == "yes")
2848         {
2849             // Check for keyboard, mouse, gfx.
2850             QStringList kbdDrivers = dictionary["KBD_DRIVERS"].split(" ");;
2851             QStringList allKbdDrivers;
2852             allKbdDrivers<<"tty"<<"usb"<<"sl5000"<<"yopy"<<"vr41xx"<<"qvfb"<<"um";
2853             foreach (const QString &kbd, allKbdDrivers) {
2854                 if (!kbdDrivers.contains(kbd))
2855                     tmpStream<<"#define QT_NO_QWS_KBD_"<<kbd.toUpper()<<endl;
2856             }
2857
2858             QStringList mouseDrivers = dictionary["MOUSE_DRIVERS"].split(" ");
2859             QStringList allMouseDrivers;
2860             allMouseDrivers << "pc"<<"bus"<<"linuxtp"<<"yopy"<<"vr41xx"<<"tslib"<<"qvfb";
2861             foreach (const QString &mouse, allMouseDrivers) {
2862                 if (!mouseDrivers.contains(mouse))
2863                     tmpStream<<"#define QT_NO_QWS_MOUSE_"<<mouse.toUpper()<<endl;
2864             }
2865
2866             QStringList gfxDrivers = dictionary["GFX_DRIVERS"].split(" ");
2867             QStringList allGfxDrivers;
2868             allGfxDrivers<<"linuxfb"<<"transformed"<<"qvfb"<<"multiscreen"<<"ahi";
2869             foreach (const QString &gfx, allGfxDrivers) {
2870                 if (!gfxDrivers.contains(gfx))
2871                     tmpStream<<"#define QT_NO_QWS_"<<gfx.toUpper()<<endl;
2872             }
2873
2874             tmpStream<<"#define Q_WS_QWS"<<endl;
2875
2876             QStringList depths = dictionary[ "QT_QWS_DEPTH" ].split(" ");
2877             foreach (const QString &depth, depths)
2878               tmpStream<<"#define QT_QWS_DEPTH_"+depth<<endl;
2879         }
2880
2881         if (dictionary[ "QT_CUPS" ] == "no")
2882           tmpStream<<"#define QT_NO_CUPS"<<endl;
2883
2884         if (dictionary[ "QT_ICONV" ]  == "no")
2885           tmpStream<<"#define QT_NO_ICONV"<<endl;
2886
2887         if (dictionary[ "QT_GLIB" ] == "no")
2888           tmpStream<<"#define QT_NO_GLIB"<<endl;
2889
2890         if (dictionary[ "QT_LPR" ] == "no")
2891           tmpStream<<"#define QT_NO_LPR"<<endl;
2892
2893         if (dictionary[ "QT_INOTIFY" ] == "no")
2894           tmpStream<<"#define QT_NO_INOTIFY"<<endl;
2895
2896         if (dictionary[ "QT_SXE" ] == "no")
2897           tmpStream<<"#define QT_NO_SXE"<<endl;
2898
2899         tmpStream.flush();
2900         tmpFile.flush();
2901
2902         // Replace old qconfig.h with new one
2903         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
2904         QFile::remove(outName);
2905         tmpFile.copy(outName);
2906         tmpFile.close();
2907     }
2908
2909     QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
2910     if (!copySpec("default", "", spec))
2911         return;
2912
2913     // Generate the new qconfig.cpp file
2914     QDir(buildPath).mkpath("src/corelib/global");
2915     outName = buildPath + "/src/corelib/global/qconfig.cpp";
2916
2917     QTemporaryFile tmpFile2;
2918     if (tmpFile2.open()) {
2919         tmpStream.setDevice(&tmpFile2);
2920         tmpStream << "/* Licensed */" << endl
2921                   << "static const char qt_configure_licensee_str          [512 + 12] = \"qt_lcnsuser=" << licenseInfo["LICENSEE"] << "\";" << endl
2922                   << "static const char qt_configure_licensed_products_str [512 + 12] = \"qt_lcnsprod=" << dictionary["EDITION"] << "\";" << endl
2923                   << endl
2924                   << "/* Build date */" << endl
2925                   << "static const char qt_configure_installation          [11  + 12] = \"qt_instdate=" << QDate::currentDate().toString(Qt::ISODate) << "\";" << endl
2926                   << endl
2927                   << "static const char qt_configure_prefix_path_strs[][12 + 512] = {" << endl
2928                   << "    \"qt_prfxpath=" << escapeSeparators(dictionary["QT_INSTALL_PREFIX"]) << "\"," << endl
2929                   << "    \"qt_docspath=" << escapeSeparators(dictionary["QT_INSTALL_DOCS"]) << "\","  << endl
2930                   << "    \"qt_hdrspath=" << escapeSeparators(dictionary["QT_INSTALL_HEADERS"]) << "\","  << endl
2931                   << "    \"qt_libspath=" << escapeSeparators(dictionary["QT_INSTALL_LIBS"]) << "\","  << endl
2932                   << "    \"qt_binspath=" << escapeSeparators(dictionary["QT_INSTALL_BINS"]) << "\","  << endl
2933                   << "    \"qt_plugpath=" << escapeSeparators(dictionary["QT_INSTALL_PLUGINS"]) << "\","  << endl
2934                   << "    \"qt_impspath=" << escapeSeparators(dictionary["QT_INSTALL_IMPORTS"]) << "\","  << endl
2935                   << "    \"qt_datapath=" << escapeSeparators(dictionary["QT_INSTALL_DATA"]) << "\","  << endl
2936                   << "    \"qt_trnspath=" << escapeSeparators(dictionary["QT_INSTALL_TRANSLATIONS"]) << "\"," << endl
2937                   << "    \"qt_xmplpath=" << escapeSeparators(dictionary["QT_INSTALL_EXAMPLES"]) << "\","  << endl
2938                   << "    \"qt_tstspath=" << escapeSeparators(dictionary["QT_INSTALL_TESTS"]) << "\","  << endl
2939                   << "#ifdef QT_BUILD_QMAKE" << endl
2940                   << "    \"qt_ssrtpath=" << escapeSeparators(dictionary["CFG_SYSROOT"]) << "\"," << endl
2941                   << "    \"qt_hpfxpath=" << escapeSeparators(dictionary["QT_HOST_PREFIX"]) << "\"," << endl
2942                   << "    \"qt_hbinpath=" << escapeSeparators(dictionary["QT_HOST_BINS"]) << "\"," << endl
2943                   << "    \"qt_hdatpath=" << escapeSeparators(dictionary["QT_HOST_DATA"]) << "\"," << endl
2944                   << "#endif" << endl
2945                   << "};" << endl
2946                   //<< "static const char qt_configure_settings_path_str [256] = \"qt_stngpath=" << escapeSeparators(dictionary["QT_INSTALL_SETTINGS"]) << "\";" << endl
2947                   << endl
2948                   << "/* strlen( \"qt_lcnsxxxx\") == 12 */" << endl
2949                   << "#define QT_CONFIGURE_LICENSEE qt_configure_licensee_str + 12;" << endl
2950                   << "#define QT_CONFIGURE_LICENSED_PRODUCTS qt_configure_licensed_products_str + 12;" << endl
2951                   //<< "#define QT_CONFIGURE_SETTINGS_PATH qt_configure_settings_path_str + 12;" << endl
2952                   << endl;
2953
2954         tmpStream.flush();
2955         tmpFile2.flush();
2956
2957         // Replace old qconfig.cpp with new one
2958         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
2959         QFile::remove(outName);
2960         tmpFile2.copy(outName);
2961         tmpFile2.close();
2962     }
2963
2964     QTemporaryFile tmpFile3;
2965     if (tmpFile3.open()) {
2966         tmpStream.setDevice(&tmpFile3);
2967         tmpStream << "/* Evaluation license key */" << endl
2968                   << "static const volatile char qt_eval_key_data              [512 + 12] = \"qt_qevalkey=" << licenseInfo["LICENSEKEYEXT"] << "\";" << endl;
2969
2970         tmpStream.flush();
2971         tmpFile3.flush();
2972
2973         outName = buildPath + "/src/corelib/global/qconfig_eval.cpp";
2974         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
2975         QFile::remove(outName);
2976
2977         if (dictionary["EDITION"] == "Evaluation" || qmakeDefines.contains("QT_EVAL"))
2978             tmpFile3.copy(outName);
2979         tmpFile3.close();
2980     }
2981 }
2982 #endif
2983
2984 #if !defined(EVAL)
2985 void Configure::displayConfig()
2986 {
2987     // Give some feedback
2988     cout << "Environment:" << endl;
2989     QString env = QString::fromLocal8Bit(getenv("INCLUDE")).replace(QRegExp("[;,]"), "\r\n      ");
2990     if (env.isEmpty())
2991         env = "Unset";
2992     cout << "    INCLUDE=\r\n      " << env << endl;
2993     env = QString::fromLocal8Bit(getenv("LIB")).replace(QRegExp("[;,]"), "\r\n      ");
2994     if (env.isEmpty())
2995         env = "Unset";
2996     cout << "    LIB=\r\n      " << env << endl;
2997     env = QString::fromLocal8Bit(getenv("PATH")).replace(QRegExp("[;,]"), "\r\n      ");
2998     if (env.isEmpty())
2999         env = "Unset";
3000     cout << "    PATH=\r\n      " << env << endl;
3001
3002     if (dictionary["EDITION"] == "OpenSource") {
3003         cout << "You are licensed to use this software under the terms of the GNU GPL version 3.";
3004         cout << "You are licensed to use this software under the terms of the Lesser GNU LGPL version 2.1." << endl;
3005         cout << "See " << dictionary["LICENSE FILE"] << "3" << endl << endl
3006              << " or " << dictionary["LICENSE FILE"] << "L" << endl << endl;
3007     } else {
3008         QString l1 = licenseInfo[ "LICENSEE" ];
3009         QString l2 = licenseInfo[ "LICENSEID" ];
3010         QString l3 = dictionary["EDITION"] + ' ' + "Edition";
3011         QString l4 = licenseInfo[ "EXPIRYDATE" ];
3012         cout << "Licensee...................." << (l1.isNull() ? "" : l1) << endl;
3013         cout << "License ID.................." << (l2.isNull() ? "" : l2) << endl;
3014         cout << "Product license............." << (l3.isNull() ? "" : l3) << endl;
3015         cout << "Expiry Date................." << (l4.isNull() ? "" : l4) << endl << endl;
3016     }
3017
3018     cout << "Configuration:" << endl;
3019     cout << "    " << qmakeConfig.join("\r\n    ") << endl;
3020     cout << "Qt Configuration:" << endl;
3021     cout << "    " << qtConfig.join("\r\n    ") << endl;
3022     cout << endl;
3023
3024     if (dictionary.contains("XQMAKESPEC"))
3025         cout << "QMAKESPEC..................." << dictionary[ "XQMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
3026     else
3027         cout << "QMAKESPEC..................." << dictionary[ "QMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
3028     cout << "Architecture................" << dictionary["QT_ARCH"] << endl;
3029     cout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"] << endl;
3030     cout << "Maketool...................." << dictionary[ "MAKE" ] << endl;
3031     cout << "Debug symbols..............." << (dictionary[ "BUILD" ] == "debug" ? "yes" : "no") << endl;
3032     cout << "Link Time Code Generation..." << dictionary[ "LTCG" ] << endl;
3033     cout << "Accessibility support......." << dictionary[ "ACCESSIBILITY" ] << endl;
3034     cout << "STL support................." << dictionary[ "STL" ] << endl;
3035     cout << "Exception support..........." << dictionary[ "EXCEPTIONS" ] << endl;
3036     cout << "RTTI support................" << dictionary[ "RTTI" ] << endl;
3037     cout << "MMX support................." << dictionary[ "MMX" ] << endl;
3038     cout << "3DNOW support..............." << dictionary[ "3DNOW" ] << endl;
3039     cout << "SSE support................." << dictionary[ "SSE" ] << endl;
3040     cout << "SSE2 support................" << dictionary[ "SSE2" ] << endl;
3041     cout << "IWMMXT support.............." << dictionary[ "IWMMXT" ] << endl;
3042     cout << "OpenGL support.............." << dictionary[ "OPENGL" ] << endl;
3043     cout << "OpenVG support.............." << dictionary[ "OPENVG" ] << endl;
3044     cout << "OpenSSL support............." << dictionary[ "OPENSSL" ] << endl;
3045     cout << "QtDBus support.............." << dictionary[ "DBUS" ] << endl;
3046     cout << "QtWidgets module support...." << dictionary[ "WIDGETS" ] << endl;
3047     cout << "Declarative debugging......." << dictionary[ "DECLARATIVE_DEBUG" ] << endl;
3048     cout << "DirectWrite support........." << dictionary[ "DIRECTWRITE" ] << endl << endl;
3049
3050     cout << "Third Party Libraries:" << endl;
3051     cout << "    ZLIB support............" << dictionary[ "ZLIB" ] << endl;
3052     cout << "    GIF support............." << dictionary[ "GIF" ] << endl;
3053     cout << "    JPEG support............" << dictionary[ "JPEG" ] << endl;
3054     cout << "    PNG support............." << dictionary[ "PNG" ] << endl;
3055     cout << "    FreeType support........" << dictionary[ "FREETYPE" ] << endl << endl;
3056     cout << "    PCRE support............" << dictionary[ "PCRE" ] << endl;
3057     cout << "    ICU support............." << dictionary[ "ICU" ] << endl;
3058
3059     cout << "Styles:" << endl;
3060     cout << "    Windows................." << dictionary[ "STYLE_WINDOWS" ] << endl;
3061     cout << "    Windows XP.............." << dictionary[ "STYLE_WINDOWSXP" ] << endl;
3062     cout << "    Windows Vista..........." << dictionary[ "STYLE_WINDOWSVISTA" ] << endl;
3063     cout << "    Plastique..............." << dictionary[ "STYLE_PLASTIQUE" ] << endl;
3064     cout << "    Cleanlooks.............." << dictionary[ "STYLE_CLEANLOOKS" ] << endl;
3065     cout << "    Motif..................." << dictionary[ "STYLE_MOTIF" ] << endl;
3066     cout << "    CDE....................." << dictionary[ "STYLE_CDE" ] << endl;
3067     cout << "    Windows CE.............." << dictionary[ "STYLE_WINDOWSCE" ] << endl;
3068     cout << "    Windows Mobile.........." << dictionary[ "STYLE_WINDOWSMOBILE" ] << endl << endl;
3069
3070     cout << "Sql Drivers:" << endl;
3071     cout << "    ODBC...................." << dictionary[ "SQL_ODBC" ] << endl;
3072     cout << "    MySQL..................." << dictionary[ "SQL_MYSQL" ] << endl;
3073     cout << "    OCI....................." << dictionary[ "SQL_OCI" ] << endl;
3074     cout << "    PostgreSQL.............." << dictionary[ "SQL_PSQL" ] << endl;
3075     cout << "    TDS....................." << dictionary[ "SQL_TDS" ] << endl;
3076     cout << "    DB2....................." << dictionary[ "SQL_DB2" ] << endl;
3077     cout << "    SQLite.................." << dictionary[ "SQL_SQLITE" ] << " (" << dictionary[ "SQL_SQLITE_LIB" ] << ")" << endl;
3078     cout << "    SQLite2................." << dictionary[ "SQL_SQLITE2" ] << endl;
3079     cout << "    InterBase..............." << dictionary[ "SQL_IBASE" ] << endl << endl;
3080
3081     cout << "Sources are in.............." << dictionary[ "QT_SOURCE_TREE" ] << endl;
3082     cout << "Build is done in............" << dictionary[ "QT_BUILD_TREE" ] << endl;
3083     cout << "Install prefix.............." << dictionary[ "QT_INSTALL_PREFIX" ] << endl;
3084     cout << "Headers installed to........" << dictionary[ "QT_INSTALL_HEADERS" ] << endl;
3085     cout << "Libraries installed to......" << dictionary[ "QT_INSTALL_LIBS" ] << endl;
3086     cout << "Plugins installed to........" << dictionary[ "QT_INSTALL_PLUGINS" ] << endl;
3087     cout << "Imports installed to........" << dictionary[ "QT_INSTALL_IMPORTS" ] << endl;
3088     cout << "Binaries installed to......." << dictionary[ "QT_INSTALL_BINS" ] << endl;
3089     cout << "Docs installed to..........." << dictionary[ "QT_INSTALL_DOCS" ] << endl;
3090     cout << "Data installed to..........." << dictionary[ "QT_INSTALL_DATA" ] << endl;
3091     cout << "Translations installed to..." << dictionary[ "QT_INSTALL_TRANSLATIONS" ] << endl;
3092     cout << "Examples installed to......." << dictionary[ "QT_INSTALL_EXAMPLES" ] << endl;
3093     cout << "Tests installed to.........." << dictionary[ "QT_INSTALL_TESTS" ] << endl;
3094
3095     if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith(QLatin1String("wince"))) {
3096         cout << "Using c runtime detection..." << dictionary[ "CE_CRT" ] << endl;
3097         cout << "Cetest support.............." << dictionary[ "CETEST" ] << endl;
3098         cout << "Signature..................." << dictionary[ "CE_SIGNATURE"] << endl << endl;
3099     }
3100
3101     if (checkAvailability("INCREDIBUILD_XGE"))
3102         cout << "Using IncrediBuild XGE......" << dictionary["INCREDIBUILD_XGE"] << endl;
3103     if (!qmakeDefines.isEmpty()) {
3104         cout << "Defines.....................";
3105         for (QStringList::Iterator defs = qmakeDefines.begin(); defs != qmakeDefines.end(); ++defs)
3106             cout << (*defs) << " ";
3107         cout << endl;
3108     }
3109     if (!qmakeIncludes.isEmpty()) {
3110         cout << "Include paths...............";
3111         for (QStringList::Iterator incs = qmakeIncludes.begin(); incs != qmakeIncludes.end(); ++incs)
3112             cout << (*incs) << " ";
3113         cout << endl;
3114     }
3115     if (!qmakeLibs.isEmpty()) {
3116         cout << "Additional libraries........";
3117         for (QStringList::Iterator libs = qmakeLibs.begin(); libs != qmakeLibs.end(); ++libs)
3118             cout << (*libs) << " ";
3119         cout << endl;
3120     }
3121     if (dictionary[ "QMAKE_INTERNAL" ] == "yes") {
3122         cout << "Using internal configuration." << endl;
3123     }
3124     if (dictionary[ "SHARED" ] == "no") {
3125         cout << "WARNING: Using static linking will disable the use of plugins." << endl;
3126         cout << "         Make sure you compile ALL needed modules into the library." << endl;
3127     }
3128     if (dictionary[ "OPENSSL" ] == "linked" && opensslLibs.isEmpty()) {
3129         cout << "NOTE: When linking against OpenSSL, you can override the default" << endl;
3130         cout << "library names through OPENSSL_LIBS." << endl;
3131         cout << "For example:" << endl;
3132         cout << "    configure -openssl-linked OPENSSL_LIBS=\"-lssleay32 -llibeay32\"" << endl;
3133     }
3134     if (dictionary[ "ZLIB_FORCED" ] == "yes") {
3135         QString which_zlib = "supplied";
3136         if (dictionary[ "ZLIB" ] == "system")
3137             which_zlib = "system";
3138
3139         cout << "NOTE: The -no-zlib option was supplied but is no longer supported." << endl
3140              << endl
3141              << "Qt now requires zlib support in all builds, so the -no-zlib" << endl
3142              << "option was ignored. Qt will be built using the " << which_zlib
3143              << "zlib" << endl;
3144     }
3145     if (dictionary["OBSOLETE_ARCH_ARG"] == "yes") {
3146         cout << endl
3147              << "NOTE: The -arch option is obsolete." << endl
3148              << endl
3149              << "Qt now detects the target and host architectures based on compiler" << endl
3150              << "output. Qt will be built using " << dictionary["QT_ARCH"] << " for the target architecture" << endl
3151              << "and " << dictionary["QT_HOST_ARCH"] << " for the host architecture (note that these two" << endl
3152              << "will be the same unless you are cross-compiling)." << endl
3153              << endl;
3154     }
3155 }
3156 #endif
3157
3158 #if !defined(EVAL)
3159 void Configure::generateHeaders()
3160 {
3161     if (dictionary["SYNCQT"] == "yes") {
3162         if (findFile("perl.exe")) {
3163             cout << "Running syncqt..." << endl;
3164             QStringList args;
3165             args += buildPath + "/bin/syncqt.bat";
3166             args += sourcePath;
3167             QStringList env;
3168             env += QString("QTDIR=" + sourcePath);
3169             env += QString("PATH=" + buildPath + "/bin/;" + qgetenv("PATH"));
3170             int retc = Environment::execute(args, env, QStringList());
3171             if (retc) {
3172                 cout << "syncqt failed, return code " << retc << endl << endl;
3173                 dictionary["DONE"] = "error";
3174             }
3175         } else {
3176             cout << "Perl not found in environment - cannot run syncqt." << endl;
3177             dictionary["DONE"] = "error";
3178         }
3179     }
3180 }
3181
3182 void Configure::buildQmake()
3183 {
3184     if (dictionary[ "BUILD_QMAKE" ] == "yes") {
3185         QStringList args;
3186
3187         // Build qmake
3188         QString pwd = QDir::currentPath();
3189         if (!QDir(buildPath).mkpath("qmake")) {
3190             cout << "Cannot create qmake build dir." << endl;
3191             dictionary[ "DONE" ] = "error";
3192             return;
3193         }
3194         if (!QDir::setCurrent(buildPath + "/qmake")) {
3195             cout << "Cannot enter qmake build dir." << endl;
3196             dictionary[ "DONE" ] = "error";
3197             return;
3198         }
3199
3200         QString makefile = "Makefile";
3201         {
3202             QFile out(makefile);
3203             if (out.open(QFile::WriteOnly | QFile::Text)) {
3204                 QTextStream stream(&out);
3205                 stream << "#AutoGenerated by configure.exe" << endl
3206                     << "BUILD_PATH = " << QDir::toNativeSeparators(buildPath) << endl
3207                     << "SOURCE_PATH = " << QDir::toNativeSeparators(sourcePath) << endl;
3208                 stream << "QMAKESPEC = " << dictionary["QMAKESPEC"] << endl
3209                        << "QT_VERSION = " << dictionary["VERSION"] << endl;
3210
3211                 if (dictionary["EDITION"] == "OpenSource" ||
3212                     dictionary["QT_EDITION"].contains("OPENSOURCE"))
3213                     stream << "QMAKE_OPENSOURCE_EDITION = yes" << endl;
3214                 stream << "\n\n";
3215
3216                 QFile in(sourcePath + "/qmake/" + dictionary["QMAKEMAKEFILE"]);
3217                 if (in.open(QFile::ReadOnly | QFile::Text)) {
3218                     QString d = in.readAll();
3219                     //### need replaces (like configure.sh)? --Sam
3220                     stream << d << endl;
3221                 }
3222                 stream.flush();
3223                 out.close();
3224             }
3225         }
3226
3227         args += dictionary[ "MAKE" ];
3228         args += "-f";
3229         args += makefile;
3230
3231         cout << "Creating qmake..." << endl;
3232         int exitCode = Environment::execute(args, QStringList(), QStringList());
3233         if (exitCode) {
3234             args.clear();
3235             args += dictionary[ "MAKE" ];
3236             args += "-f";
3237             args += makefile;
3238             args += "clean";
3239             exitCode = Environment::execute(args, QStringList(), QStringList());
3240             if (exitCode) {
3241                 cout << "Cleaning qmake failed, return code " << exitCode << endl << endl;
3242                 dictionary[ "DONE" ] = "error";
3243             } else {
3244                 args.clear();
3245                 args += dictionary[ "MAKE" ];
3246                 args += "-f";
3247                 args += makefile;
3248                 exitCode = Environment::execute(args, QStringList(), QStringList());
3249                 if (exitCode) {
3250                     cout << "Building qmake failed, return code " << exitCode << endl << endl;
3251                     dictionary[ "DONE" ] = "error";
3252                 }
3253             }
3254         }
3255         QDir::setCurrent(pwd);
3256     }
3257 }
3258 #endif
3259
3260 void Configure::buildHostTools()
3261 {
3262     if (dictionary[ "NOPROCESS" ] == "yes")
3263         dictionary[ "DONE" ] = "yes";
3264
3265     if (!dictionary.contains("XQMAKESPEC"))
3266         return;
3267
3268     QString pwd = QDir::currentPath();
3269     QStringList hostToolsDirs;
3270     hostToolsDirs
3271         << "src/tools";
3272
3273     for (int i = 0; i < hostToolsDirs.count(); ++i) {
3274         cout << "Creating " << hostToolsDirs.at(i) << " ..." << endl;
3275         QString toolBuildPath = buildPath + "/" + hostToolsDirs.at(i);
3276         QString toolSourcePath = sourcePath + "/" + hostToolsDirs.at(i);
3277
3278         // generate Makefile
3279         QStringList args;
3280         args << QDir::toNativeSeparators(buildPath + "/bin/qmake");
3281         // override .qmake.cache because we are not cross-building these.
3282         // we need a full path so that a build with -prefix will still find it.
3283         args << "-spec" << QDir::toNativeSeparators(buildPath + "/mkspecs/" + dictionary["QMAKESPEC"]);
3284         args << "-r";
3285         args << "-o" << QDir::toNativeSeparators(toolBuildPath + "/Makefile");
3286
3287         QDir().mkpath(toolBuildPath);
3288         QDir::setCurrent(toolSourcePath);
3289         int exitCode = Environment::execute(args, QStringList(), QStringList());
3290         if (exitCode) {
3291             cout << "qmake failed, return code " << exitCode << endl << endl;
3292             dictionary["DONE"] = "error";
3293             break;
3294         }
3295
3296         // build app
3297         args.clear();
3298         args += dictionary["MAKE"];
3299         QDir::setCurrent(toolBuildPath);
3300         exitCode = Environment::execute(args, QStringList(), QStringList());
3301         if (exitCode) {
3302             args.clear();
3303             args += dictionary["MAKE"];
3304             args += "clean";
3305             exitCode = Environment::execute(args, QStringList(), QStringList());
3306             if (exitCode) {
3307                 cout << "Cleaning " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl;
3308                 dictionary["DONE"] = "error";
3309                 break;
3310             } else {
3311                 args.clear();
3312                 args += dictionary["MAKE"];
3313                 exitCode = Environment::execute(args, QStringList(), QStringList());
3314                 if (exitCode) {
3315                     cout << "Building " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl;
3316                     dictionary["DONE"] = "error";
3317                     break;
3318                 }
3319             }
3320         }
3321     }
3322     QDir::setCurrent(pwd);
3323 }
3324
3325 void Configure::findProjects(const QString& dirName)
3326 {
3327     if (dictionary[ "NOPROCESS" ] == "no") {
3328         QDir dir(dirName);
3329         QString entryName;
3330         int makeListNumber;
3331         ProjectType qmakeTemplate;
3332         const QFileInfoList &list = dir.entryInfoList(QStringList(QLatin1String("*.pro")),
3333                                                       QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
3334         for (int i = 0; i < list.size(); ++i) {
3335             const QFileInfo &fi = list.at(i);
3336             if (fi.fileName() != "qmake.pro") {
3337                 entryName = dirName + "/" + fi.fileName();
3338                 if (fi.isDir()) {
3339                     findProjects(entryName);
3340                 } else {
3341                     qmakeTemplate = projectType(fi.absoluteFilePath());
3342                     switch (qmakeTemplate) {
3343                     case Lib:
3344                     case Subdirs:
3345                         makeListNumber = 1;
3346                         break;
3347                     default:
3348                         makeListNumber = 2;
3349                         break;
3350                     }
3351                     makeList[makeListNumber].append(new MakeItem(sourceDir.relativeFilePath(fi.absolutePath()),
3352                                                     fi.fileName(),
3353                                                     "Makefile",
3354                                                     qmakeTemplate));
3355                 }
3356             }
3357
3358         }
3359     }
3360 }
3361
3362 void Configure::appendMakeItem(int inList, const QString &item)
3363 {
3364     QString dir;
3365     if (item != "src")
3366         dir = "/" + item;
3367     dir.prepend("/src");
3368     makeList[inList].append(new MakeItem(sourcePath + dir,
3369         item + ".pro", buildPath + dir + "/Makefile", Lib));
3370     if (dictionary[ "DSPFILES" ] == "yes") {
3371         makeList[inList].append(new MakeItem(sourcePath + dir,
3372             item + ".pro", buildPath + dir + "/" + item + ".dsp", Lib));
3373     }
3374     if (dictionary[ "VCPFILES" ] == "yes") {
3375         makeList[inList].append(new MakeItem(sourcePath + dir,
3376             item + ".pro", buildPath + dir + "/" + item + ".vcp", Lib));
3377     }
3378     if (dictionary[ "VCPROJFILES" ] == "yes") {
3379         makeList[inList].append(new MakeItem(sourcePath + dir,
3380             item + ".pro", buildPath + dir + "/" + item + ".vcproj", Lib));
3381     }
3382 }
3383
3384 void Configure::generateMakefiles()
3385 {
3386     if (dictionary[ "NOPROCESS" ] == "no") {
3387 #if !defined(EVAL)
3388         cout << "Creating makefiles in src..." << endl;
3389 #endif
3390
3391         QString spec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
3392         if (spec != "win32-msvc")
3393             dictionary[ "DSPFILES" ] = "no";
3394
3395         if (spec != "win32-msvc.net" && !spec.startsWith("win32-msvc2") && !spec.startsWith(QLatin1String("wince")))
3396             dictionary[ "VCPROJFILES" ] = "no";
3397
3398         int i = 0;
3399         QString pwd = QDir::currentPath();
3400         if (dictionary["FAST"] != "yes") {
3401             QString dirName;
3402             bool generate = true;
3403             bool doDsp = (dictionary["DSPFILES"] == "yes" || dictionary["VCPFILES"] == "yes"
3404                           || dictionary["VCPROJFILES"] == "yes");
3405             while (generate) {
3406                 QString pwd = QDir::currentPath();
3407                 QString dirPath = fixSeparators(buildPath + dirName);
3408                 QStringList args;
3409
3410                 args << fixSeparators(buildPath + "/bin/qmake");
3411
3412                 if (doDsp) {
3413                     if (dictionary[ "DEPENDENCIES" ] == "no")
3414                         args << "-nodepend";
3415                     args << "-tp" <<  "vc";
3416                     doDsp = false; // DSP files will be done
3417                     printf("Generating Visual Studio project files...\n");
3418                 } else {
3419                     printf("Generating Makefiles...\n");
3420                     generate = false; // Now Makefiles will be done
3421                 }
3422                 // don't pass -spec - .qmake.cache has it already
3423                 args << "-r";
3424                 args << (sourcePath + "/qtbase.pro");
3425                 args << "-o";
3426                 args << buildPath;
3427                 if (!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
3428                     args << dictionary[ "QMAKEADDITIONALARGS" ];
3429
3430                 QDir::setCurrent(fixSeparators(dirPath));
3431                 if (int exitCode = Environment::execute(args, QStringList(), QStringList())) {
3432                     cout << "Qmake failed, return code " << exitCode  << endl << endl;
3433                     dictionary[ "DONE" ] = "error";
3434                 }
3435             }
3436         } else {
3437             findProjects(sourcePath);
3438             for (i=0; i<3; i++) {
3439                 for (int j=0; j<makeList[i].size(); ++j) {
3440                     MakeItem *it=makeList[i][j];
3441                     QString dirPath = fixSeparators(it->directory + "/");
3442                     QString projectName = it->proFile;
3443                     QString makefileName = buildPath + "/" + dirPath + it->target;
3444
3445                     // For shadowbuilds, we need to create the path first
3446                     QDir buildPathDir(buildPath);
3447                     if (sourcePath != buildPath && !buildPathDir.exists(dirPath))
3448                         buildPathDir.mkpath(dirPath);
3449
3450                     QStringList args;
3451
3452                     args << fixSeparators(buildPath + "/bin/qmake");
3453                     args << sourcePath + "/" + dirPath + projectName;
3454                     args << dictionary[ "QMAKE_ALL_ARGS" ];
3455
3456                     cout << "For " << qPrintable(dirPath + projectName) << endl;
3457                     args << "-o";
3458                     args << it->target;
3459                     args << "-spec";
3460                     args << spec;
3461                     if (!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
3462                         args << dictionary[ "QMAKEADDITIONALARGS" ];
3463
3464                     QDir::setCurrent(fixSeparators(dirPath));
3465
3466                     QFile file(makefileName);
3467                     if (!file.open(QFile::WriteOnly)) {
3468                         printf("failed on dirPath=%s, makefile=%s\n",
3469                             qPrintable(dirPath), qPrintable(makefileName));
3470                         continue;
3471                     }
3472                     QTextStream txt(&file);
3473                     txt << "all:\n";
3474                     txt << "\t" << args.join(" ") << "\n";
3475                     txt << "\t\"$(MAKE)\" -$(MAKEFLAGS) -f " << it->target << "\n";
3476                     txt << "first: all\n";
3477                     txt << "qmake:\n";
3478                     txt << "\t" << args.join(" ") << "\n";
3479                 }
3480             }
3481         }
3482         QDir::setCurrent(pwd);
3483     } else {
3484         cout << "Processing of project files have been disabled." << endl;
3485         cout << "Only use this option if you really know what you're doing." << endl << endl;
3486         return;
3487     }
3488 }
3489
3490 void Configure::showSummary()
3491 {
3492     QString make = dictionary[ "MAKE" ];
3493     if (!dictionary.contains("XQMAKESPEC")) {
3494         cout << endl << endl << "Qt is now configured for building. Just run " << qPrintable(make) << "." << endl;
3495         cout << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl;
3496     } else if (dictionary.value("QMAKESPEC").startsWith("wince")) {
3497         // we are cross compiling for Windows CE
3498         cout << endl << endl << "Qt is now configured for building. To start the build run:" << endl
3499              << "\tsetcepaths " << dictionary.value("XQMAKESPEC") << endl
3500              << "\t" << qPrintable(make) << endl
3501              << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl;
3502     }
3503 }
3504
3505 Configure::ProjectType Configure::projectType(const QString& proFileName)
3506 {
3507     QFile proFile(proFileName);
3508     if (proFile.open(QFile::ReadOnly)) {
3509         QString buffer = proFile.readLine(1024);
3510         while (!buffer.isEmpty()) {
3511             QStringList segments = buffer.split(QRegExp("\\s"));
3512             QStringList::Iterator it = segments.begin();
3513
3514             if (segments.size() >= 3) {
3515                 QString keyword = (*it++);
3516                 QString operation = (*it++);
3517                 QString value = (*it++);
3518
3519                 if (keyword == "TEMPLATE") {
3520                     if (value == "lib")
3521                         return Lib;
3522                     else if (value == "subdirs")
3523                         return Subdirs;
3524                 }
3525             }
3526             // read next line
3527             buffer = proFile.readLine(1024);
3528         }
3529         proFile.close();
3530     }
3531     // Default to app handling
3532     return App;
3533 }
3534
3535 #if !defined(EVAL)
3536
3537 bool Configure::showLicense(QString orgLicenseFile)
3538 {
3539     if (dictionary["LICENSE_CONFIRMED"] == "yes") {
3540         cout << "You have already accepted the terms of the license." << endl << endl;
3541         return true;
3542     }
3543
3544     bool haveGpl3 = false;
3545     QString licenseFile = orgLicenseFile;
3546     QString theLicense;
3547     if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3548         haveGpl3 = QFile::exists(orgLicenseFile + "/LICENSE.GPL3");
3549         theLicense = "GNU Lesser General Public License (LGPL) version 2.1";
3550         if (haveGpl3)
3551             theLicense += "\nor the GNU General Public License (GPL) version 3";
3552     } else {
3553         // the first line of the license file tells us which license it is
3554         QFile file(licenseFile);
3555         if (!file.open(QFile::ReadOnly)) {
3556             cout << "Failed to load LICENSE file" << endl;
3557             return false;
3558         }
3559         theLicense = file.readLine().trimmed();
3560     }
3561
3562     forever {
3563         char accept = '?';
3564         cout << "You are licensed to use this software under the terms of" << endl
3565              << "the " << theLicense << "." << endl
3566              << endl;
3567         if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3568             if (haveGpl3)
3569                 cout << "Type '3' to view the GNU General Public License version 3 (GPLv3)." << endl;
3570             cout << "Type 'L' to view the Lesser GNU General Public License version 2.1 (LGPLv2.1)." << endl;
3571         } else {
3572             cout << "Type '?' to view the " << theLicense << "." << endl;
3573         }
3574         cout << "Type 'y' to accept this license offer." << endl
3575              << "Type 'n' to decline this license offer." << endl
3576              << endl
3577              << "Do you accept the terms of the license?" << endl;
3578         cin >> accept;
3579         accept = tolower(accept);
3580
3581         if (accept == 'y') {
3582             return true;
3583         } else if (accept == 'n') {
3584             return false;
3585         } else {
3586             if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3587                 if (accept == '3')
3588                     licenseFile = orgLicenseFile + "/LICENSE.GPL3";
3589                 else
3590                     licenseFile = orgLicenseFile + "/LICENSE.LGPL";
3591             }
3592             // Get console line height, to fill the screen properly
3593             int i = 0, screenHeight = 25; // default
3594             CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
3595             HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
3596             if (GetConsoleScreenBufferInfo(stdOut, &consoleInfo))
3597                 screenHeight = consoleInfo.srWindow.Bottom
3598                              - consoleInfo.srWindow.Top
3599                              - 1; // Some overlap for context
3600
3601             // Prompt the license content to the user
3602             QFile file(licenseFile);
3603             if (!file.open(QFile::ReadOnly)) {
3604                 cout << "Failed to load LICENSE file" << licenseFile << endl;
3605                 return false;
3606             }
3607             QStringList licenseContent = QString(file.readAll()).split('\n');
3608             while (i < licenseContent.size()) {
3609                 cout << licenseContent.at(i) << endl;
3610                 if (++i % screenHeight == 0) {
3611                     cout << "(Press any key for more..)";
3612                     if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
3613                         exit(0);      // Exit cleanly for Ctrl+C
3614                     cout << "\r";     // Overwrite text above
3615                 }
3616             }
3617         }
3618     }
3619 }
3620
3621 void Configure::readLicense()
3622 {
3623    if (QFile::exists(dictionary["QT_SOURCE_TREE"] + "/src/corelib/kernel/qfunctions_wince.h") &&
3624        (dictionary.value("QMAKESPEC").startsWith("wince") || dictionary.value("XQMAKESPEC").startsWith("wince")))
3625         dictionary["PLATFORM NAME"] = "Qt for Windows CE";
3626     else
3627         dictionary["PLATFORM NAME"] = "Qt for Windows";
3628     dictionary["LICENSE FILE"] = sourcePath;
3629
3630     bool openSource = false;
3631     bool hasOpenSource = QFile::exists(dictionary["LICENSE FILE"] + "/LICENSE.GPL3") || QFile::exists(dictionary["LICENSE FILE"] + "/LICENSE.LGPL");
3632     if (dictionary["BUILDTYPE"] == "commercial") {
3633         openSource = false;
3634     } else if (dictionary["BUILDTYPE"] == "opensource") {
3635         openSource = true;
3636     } else if (hasOpenSource) { // No Open Source? Just display the commercial license right away
3637         forever {
3638             char accept = '?';
3639             cout << "Which edition of Qt do you want to use ?" << endl;
3640             cout << "Type 'c' if you want to use the Commercial Edition." << endl;
3641             cout << "Type 'o' if you want to use the Open Source Edition." << endl;
3642             cin >> accept;
3643             accept = tolower(accept);
3644
3645             if (accept == 'c') {
3646                 openSource = false;
3647                 break;
3648             } else if (accept == 'o') {
3649                 openSource = true;
3650                 break;
3651             }
3652         }
3653     }
3654     if (hasOpenSource && openSource) {
3655         cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " Open Source Edition." << endl;
3656         licenseInfo["LICENSEE"] = "Open Source";
3657         dictionary["EDITION"] = "OpenSource";
3658         dictionary["QT_EDITION"] = "QT_EDITION_OPENSOURCE";
3659         cout << endl;
3660         if (!showLicense(dictionary["LICENSE FILE"])) {
3661             cout << "Configuration aborted since license was not accepted";
3662             dictionary["DONE"] = "error";
3663             return;
3664         }
3665     } else if (openSource) {
3666         cout << endl << "Cannot find the GPL license files! Please download the Open Source version of the library." << endl;
3667         dictionary["DONE"] = "error";
3668     }
3669 #ifdef COMMERCIAL_VERSION
3670     else {
3671         Tools::checkLicense(dictionary, licenseInfo, firstLicensePath());
3672         if (dictionary["DONE"] != "error") {
3673             // give the user some feedback, and prompt for license acceptance
3674             cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl;
3675             if (!showLicense(dictionary["LICENSE FILE"])) {
3676                 cout << "Configuration aborted since license was not accepted";
3677                 dictionary["DONE"] = "error";
3678                 return;
3679             }
3680         }
3681     }
3682 #else // !COMMERCIAL_VERSION
3683     else {
3684         cout << endl << "Cannot build commercial edition from the open source version of the library." << endl;
3685         dictionary["DONE"] = "error";
3686     }
3687 #endif
3688 }
3689
3690 void Configure::reloadCmdLine()
3691 {
3692     if (dictionary[ "REDO" ] == "yes") {
3693         QFile inFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
3694         if (inFile.open(QFile::ReadOnly)) {
3695             QTextStream inStream(&inFile);
3696             QString buffer;
3697             inStream >> buffer;
3698             while (buffer.length()) {
3699                 configCmdLine += buffer;
3700                 inStream >> buffer;
3701             }
3702             inFile.close();
3703         }
3704     }
3705 }
3706
3707 void Configure::saveCmdLine()
3708 {
3709     if (dictionary[ "REDO" ] != "yes") {
3710         QFile outFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
3711         if (outFile.open(QFile::WriteOnly | QFile::Text)) {
3712             QTextStream outStream(&outFile);
3713             for (QStringList::Iterator it = configCmdLine.begin(); it != configCmdLine.end(); ++it) {
3714                 outStream << (*it) << " " << endl;
3715             }
3716             outStream.flush();
3717             outFile.close();
3718         }
3719     }
3720 }
3721 #endif // !EVAL
3722
3723 bool Configure::isDone()
3724 {
3725     return !dictionary["DONE"].isEmpty();
3726 }
3727
3728 bool Configure::isOk()
3729 {
3730     return (dictionary[ "DONE" ] != "error");
3731 }
3732
3733 bool
3734 Configure::filesDiffer(const QString &fn1, const QString &fn2)
3735 {
3736     QFile file1(fn1), file2(fn2);
3737     if (!file1.open(QFile::ReadOnly) || !file2.open(QFile::ReadOnly))
3738         return true;
3739     const int chunk = 2048;
3740     int used1 = 0, used2 = 0;
3741     char b1[chunk], b2[chunk];
3742     while (!file1.atEnd() && !file2.atEnd()) {
3743         if (!used1)
3744             used1 = file1.read(b1, chunk);
3745         if (!used2)
3746             used2 = file2.read(b2, chunk);
3747         if (used1 > 0 && used2 > 0) {
3748             const int cmp = qMin(used1, used2);
3749             if (memcmp(b1, b2, cmp))
3750                 return true;
3751             if ((used1 -= cmp))
3752                 memcpy(b1, b1+cmp, used1);
3753             if ((used2 -= cmp))
3754                 memcpy(b2, b2+cmp, used2);
3755         }
3756     }
3757     return !file1.atEnd() || !file2.atEnd();
3758 }
3759
3760 QT_END_NAMESPACE