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