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