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