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