Merge "Merge branch 'buildsystem'" into refs/staging/master
[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         QString hostSpec = dictionary[ "QMAKESPEC" ];
2587         QString targetSpec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : hostSpec;
2588         QString xmkspec_path = sourcePath + "/mkspecs/" + targetSpec;
2589         if (QFile::exists(xmkspec_path))
2590             moduleStream << "XQMAKESPEC      = " << xmkspec_path << endl;
2591         else
2592             moduleStream << "XQMAKESPEC      = " << targetSpec << endl;
2593         QString mkspec_path = sourcePath + "/mkspecs/" + hostSpec;
2594         if (QFile::exists(mkspec_path))
2595             moduleStream << "QMAKESPEC       = " << mkspec_path << endl;
2596         else
2597             moduleStream << "QMAKESPEC       = " << hostSpec << endl;
2598
2599         if (dictionary["QT_EDITION"] != "QT_EDITION_OPENSOURCE")
2600             moduleStream << "DEFINES        *= QT_EDITION=QT_EDITION_DESKTOP" << endl;
2601
2602         if (dictionary["CETEST"] == "yes") {
2603             moduleStream << "QT_CE_RAPI_INC  = " << formatPath(dictionary["QT_CE_RAPI_INC"]) << endl;
2604             moduleStream << "QT_CE_RAPI_LIB  = " << formatPath(dictionary["QT_CE_RAPI_LIB"]) << endl;
2605         }
2606
2607         moduleStream << "#Qt for Windows CE c-runtime deployment" << endl
2608                      << "QT_CE_C_RUNTIME = " << formatPath(dictionary["CE_CRT"]) << endl;
2609
2610         if (dictionary["CE_SIGNATURE"] != QLatin1String("no"))
2611             moduleStream << "DEFAULT_SIGNATURE=" << dictionary["CE_SIGNATURE"] << endl;
2612
2613         // embedded
2614         if (!dictionary["KBD_DRIVERS"].isEmpty())
2615             moduleStream << "kbd-drivers += "<< dictionary["KBD_DRIVERS"]<<endl;
2616         if (!dictionary["GFX_DRIVERS"].isEmpty())
2617             moduleStream << "gfx-drivers += "<< dictionary["GFX_DRIVERS"]<<endl;
2618         if (!dictionary["MOUSE_DRIVERS"].isEmpty())
2619             moduleStream << "mouse-drivers += "<< dictionary["MOUSE_DRIVERS"]<<endl;
2620         if (!dictionary["DECORATIONS"].isEmpty())
2621             moduleStream << "decorations += "<<dictionary["DECORATIONS"]<<endl;
2622
2623         moduleStream << "CONFIG += create_prl link_prl";
2624         if (dictionary[ "SSE2" ] == "yes")
2625             moduleStream << " sse2";
2626         if (dictionary[ "SSE3" ] == "yes")
2627             moduleStream << " sse3";
2628         if (dictionary[ "SSSE3" ] == "yes")
2629             moduleStream << " ssse3";
2630         if (dictionary[ "SSE4_1" ] == "yes")
2631             moduleStream << " sse4_1";
2632         if (dictionary[ "SSE4_2" ] == "yes")
2633             moduleStream << " sse4_2";
2634         if (dictionary[ "AVX" ] == "yes")
2635             moduleStream << " avx";
2636         if (dictionary[ "AVX2" ] == "yes")
2637             moduleStream << " avx2";
2638         if (dictionary[ "IWMMXT" ] == "yes")
2639             moduleStream << " iwmmxt";
2640         moduleStream << endl;
2641
2642         moduleStream.flush();
2643         moduleFile.close();
2644     }
2645 }
2646
2647 struct ArchData {
2648     const char *qmakespec;
2649     const char *key;
2650     const char *subarchKey;
2651     const char *type;
2652     ArchData() {}
2653     ArchData(const char *t, const char *qm, const char *k, const char *sak)
2654         : qmakespec(qm), key(k), subarchKey(sak), type(t)
2655     {}
2656 };
2657
2658 /*
2659     Runs qmake on config.tests/arch/arch.pro, which will detect the target arch
2660     for the compiler we are using
2661 */
2662 void Configure::detectArch()
2663 {
2664     QString oldpwd = QDir::currentPath();
2665
2666     QString newpwd = QString("%1/config.tests/arch").arg(buildPath);
2667     if (!QDir().exists(newpwd) && !QDir().mkpath(newpwd)) {
2668         cout << "Failed to create directory " << qPrintable(QDir::toNativeSeparators(newpwd)) << endl;
2669         dictionary["DONE"] = "error";
2670         return;
2671     }
2672     if (!QDir::setCurrent(newpwd)) {
2673         cout << "Failed to change working directory to " << qPrintable(QDir::toNativeSeparators(newpwd)) << endl;
2674         dictionary["DONE"] = "error";
2675         return;
2676     }
2677
2678     QVector<ArchData> qmakespecs;
2679     if (dictionary.contains("XQMAKESPEC"))
2680         qmakespecs << ArchData("target", "XQMAKESPEC", "QT_ARCH", "QT_CPU_FEATURES");
2681     qmakespecs << ArchData("host", "QMAKESPEC", "QT_HOST_ARCH", "QT_HOST_CPU_FEATURES");
2682
2683     for (int i = 0; i < qmakespecs.count(); ++i) {
2684         const ArchData &data = qmakespecs.at(i);
2685         QString qmakespec = dictionary.value(data.qmakespec);
2686         QString key = data.key;
2687         QString subarchKey = data.subarchKey;
2688
2689         // run qmake
2690         QString command = QString("%1 -spec %2 %3 2>&1")
2691             .arg(QDir::toNativeSeparators(buildPath + "/bin/qmake.exe"),
2692                  QDir::toNativeSeparators(qmakespec),
2693                  QDir::toNativeSeparators(sourcePath + "/config.tests/arch/arch.pro"));
2694         Environment::execute(command);
2695
2696         // compile
2697         command = dictionary[ "MAKE" ];
2698         if (command.contains("nmake"))
2699             command += " /NOLOGO";
2700         command += " -s";
2701         Environment::execute(command);
2702
2703         // find the executable that was generated
2704         QFile exe("arch.exe");
2705         if (!exe.open(QFile::ReadOnly)) { // no Text, this is binary
2706             exe.setFileName("arch");
2707             if (!exe.open(QFile::ReadOnly)) {
2708                 cout << "Could not find output file: " << qPrintable(exe.errorString()) << endl;
2709                 dictionary["DONE"] = "error";
2710                 return;
2711             }
2712         }
2713         QByteArray exeContents = exe.readAll();
2714         exe.close();
2715
2716         static const char archMagic[] = "==Qt=magic=Qt== Architecture:";
2717         int magicPos = exeContents.indexOf(archMagic);
2718         if (magicPos == -1) {
2719             cout << "Internal error, could not find the architecture of the "
2720                  << data.type << " executable" << endl;
2721             dictionary["DONE"] = "error";
2722             return;
2723         }
2724         //cout << "Found magic at offset 0x" << hex << magicPos << endl;
2725
2726         // the conversion from QByteArray will stop at the ending NUL anyway
2727         QString arch = QString::fromLatin1(exeContents.constData() + magicPos
2728                                            + sizeof(archMagic) - 1);
2729         dictionary[key] = arch;
2730
2731         static const char subarchMagic[] = "==Qt=magic=Qt== Sub-architecture:";
2732         magicPos = exeContents.indexOf(subarchMagic);
2733         if (magicPos == -1) {
2734             cout << "Internal error, could not find the sub-architecture of the "
2735                  << data.type << " executable" << endl;
2736             dictionary["DONE"] = "error";
2737             return;
2738         }
2739
2740         QString subarch = QString::fromLatin1(exeContents.constData() + magicPos
2741                                               + sizeof(subarchMagic) - 1);
2742         dictionary[subarchKey] = subarch;
2743
2744         //cout << "Detected arch '" << qPrintable(arch) << "'\n";
2745         //cout << "Detected sub-arch '" << qPrintable(subarch) << "'\n";
2746
2747         // clean up
2748         Environment::execute(command + " distclean");
2749     }
2750
2751     if (!dictionary.contains("QT_HOST_ARCH"))
2752         dictionary["QT_HOST_ARCH"] = "unknown";
2753     if (!dictionary.contains("QT_ARCH")) {
2754         dictionary["QT_ARCH"] = dictionary["QT_HOST_ARCH"];
2755         dictionary["QT_CPU_FEATURES"] = dictionary["QT_HOST_CPU_FEATURES"];
2756     }
2757
2758     QDir::setCurrent(oldpwd);
2759 }
2760
2761 bool Configure::tryCompileProject(const QString &projectPath, const QString &extraOptions)
2762 {
2763     QString oldpwd = QDir::currentPath();
2764
2765     QString newpwd = QString("%1/config.tests/%2").arg(buildPath, projectPath);
2766     if (!QDir().exists(newpwd) && !QDir().mkpath(newpwd)) {
2767         cout << "Failed to create directory " << qPrintable(QDir::toNativeSeparators(newpwd)) << endl;
2768         dictionary["DONE"] = "error";
2769         return false;
2770     }
2771     if (!QDir::setCurrent(newpwd)) {
2772         cout << "Failed to change working directory to " << qPrintable(QDir::toNativeSeparators(newpwd)) << endl;
2773         dictionary["DONE"] = "error";
2774         return false;
2775     }
2776
2777     // run qmake
2778     QString command = QString("%1 %2 %3 2>&1")
2779         .arg(QDir::toNativeSeparators(buildPath + "/bin/qmake.exe"),
2780              QDir::toNativeSeparators(sourcePath + "/config.tests/" + projectPath),
2781              extraOptions);
2782     int code = 0;
2783     QString output = Environment::execute(command, &code);
2784     //cout << output << endl;
2785
2786     if (code == 0) {
2787         // compile
2788         command = dictionary[ "MAKE" ];
2789         if (command.contains("nmake"))
2790             command += " /NOLOGO";
2791         command += " -s 2>&1";
2792         output = Environment::execute(command, &code);
2793         //cout << output << endl;
2794
2795         // clean up
2796         Environment::execute(command + " distclean 2>&1");
2797     }
2798
2799     QDir::setCurrent(oldpwd);
2800     return code == 0;
2801 }
2802
2803 void Configure::generateQConfigPri()
2804 {
2805     // Generate qconfig.pri
2806     QFile configFile(dictionary[ "QT_BUILD_TREE" ] + "/mkspecs/qconfig.pri");
2807     if (configFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
2808         QTextStream configStream(&configFile);
2809
2810         configStream << "CONFIG+= ";
2811         configStream << dictionary[ "BUILD" ];
2812         if (dictionary[ "SHARED" ] == "yes")
2813             configStream << " shared";
2814         else
2815             configStream << " static";
2816
2817         if (dictionary[ "LTCG" ] == "yes")
2818             configStream << " ltcg";
2819         if (dictionary[ "RTTI" ] == "yes")
2820             configStream << " rtti";
2821         if (dictionary["INCREDIBUILD_XGE"] == "yes")
2822             configStream << " incredibuild_xge";
2823         if (dictionary["PLUGIN_MANIFESTS"] == "no")
2824             configStream << " no_plugin_manifest";
2825         if (dictionary["CROSS_COMPILE"] == "yes")
2826             configStream << " cross_compile";
2827
2828         if (dictionary["DIRECTWRITE"] == "yes")
2829             configStream << "directwrite";
2830
2831         // ### For compatibility only, should be removed later.
2832         configStream << " qpa";
2833
2834         configStream << endl;
2835         configStream << "QT_ARCH = " << dictionary["QT_ARCH"] << endl;
2836         configStream << "QT_HOST_ARCH = " << dictionary["QT_HOST_ARCH"] << endl;
2837         configStream << "QT_CPU_FEATURES = " << dictionary["QT_CPU_FEATURES"] << endl;
2838         configStream << "QT_HOST_CPU_FEATURES = " << dictionary["QT_HOST_CPU_FEATURES"] << endl;
2839         if (dictionary["QT_EDITION"].contains("OPENSOURCE"))
2840             configStream << "QT_EDITION = " << QLatin1String("OpenSource") << endl;
2841         else
2842             configStream << "QT_EDITION = " << dictionary["EDITION"] << endl;
2843         configStream << "QT_CONFIG += " << qtConfig.join(" ") << endl;
2844
2845         configStream << "#versioning " << endl
2846                      << "QT_VERSION = " << dictionary["VERSION"] << endl
2847                      << "QT_MAJOR_VERSION = " << dictionary["VERSION_MAJOR"] << endl
2848                      << "QT_MINOR_VERSION = " << dictionary["VERSION_MINOR"] << endl
2849                      << "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl;
2850
2851         if (!dictionary["CFG_SYSROOT"].isEmpty()) {
2852             QString targetSpec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
2853             configStream << endl
2854                          << "# sysroot" << endl
2855                          << targetSpec << " {" << endl
2856                          << "    QMAKE_CFLAGS    += --sysroot=$$[QT_SYSROOT]" << endl
2857                          << "    QMAKE_CXXFLAGS  += --sysroot=$$[QT_SYSROOT]" << endl
2858                          << "    QMAKE_LFLAGS    += --sysroot=$$[QT_SYSROOT]" << endl
2859                          << "}" << endl;
2860         }
2861
2862         if (!dictionary["QMAKE_RPATHDIR"].isEmpty())
2863             configStream << "QMAKE_RPATHDIR += " << formatPath(dictionary["QMAKE_RPATHDIR"]) << endl;
2864
2865         if (!dictionary["QT_LIBINFIX"].isEmpty())
2866             configStream << "QT_LIBINFIX = " << dictionary["QT_LIBINFIX"] << endl;
2867
2868         if (!dictionary["QT_NAMESPACE"].isEmpty())
2869             configStream << "#namespaces" << endl << "QT_NAMESPACE = " << dictionary["QT_NAMESPACE"] << endl;
2870
2871         if (dictionary.value(QStringLiteral("OPENGL_ES_2")) == QStringLiteral("yes")) {
2872             const QString angleDir = dictionary.value(QStringLiteral("ANGLE_DIR"));
2873             if (!angleDir.isEmpty()) {
2874                 configStream
2875                     << "QMAKE_INCDIR_OPENGL_ES2 = " << angleDir << "/include\n"
2876                     << "QMAKE_LIBDIR_OPENGL_ES2_DEBUG = " << angleDir << "/lib/Debug\n"
2877                     << "QMAKE_LIBDIR_OPENGL_ES2_RELEASE = " << angleDir << "/lib/Release\n";
2878             }
2879         }
2880
2881         configStream.flush();
2882         configFile.close();
2883     }
2884 }
2885 #endif
2886
2887 QString Configure::addDefine(QString def)
2888 {
2889     QString result, defNeg, defD = def;
2890
2891     defD.replace(QRegExp("=.*"), "");
2892     def.replace(QRegExp("="), " ");
2893
2894     if (def.startsWith("QT_NO_")) {
2895         defNeg = defD;
2896         defNeg.replace("QT_NO_", "QT_");
2897     } else if (def.startsWith("QT_")) {
2898         defNeg = defD;
2899         defNeg.replace("QT_", "QT_NO_");
2900     }
2901
2902     if (defNeg.isEmpty()) {
2903         result = "#ifndef $DEFD\n"
2904                  "# define $DEF\n"
2905                  "#endif\n\n";
2906     } else {
2907         result = "#if defined($DEFD) && defined($DEFNEG)\n"
2908                  "# undef $DEFD\n"
2909                  "#elif !defined($DEFD)\n"
2910                  "# define $DEF\n"
2911                  "#endif\n\n";
2912     }
2913     result.replace("$DEFNEG", defNeg);
2914     result.replace("$DEFD", defD);
2915     result.replace("$DEF", def);
2916     return result;
2917 }
2918
2919 #if !defined(EVAL)
2920 bool Configure::copySpec(const char *name, const char *pfx, const QString &spec)
2921 {
2922     // Copy configured mkspec to default directory, but remove the old one first, if there is any
2923     QString defSpec = buildPath + "/mkspecs/" + name;
2924     QFileInfo defSpecInfo(defSpec);
2925     if (defSpecInfo.exists()) {
2926         if (!Environment::rmdir(defSpec)) {
2927             cout << "Couldn't update default " << pfx << "mkspec! Are files in " << qPrintable(defSpec) << " read-only?" << endl;
2928             dictionary["DONE"] = "error";
2929             return false;
2930         }
2931     }
2932
2933     QString pltSpec = sourcePath + "/mkspecs/" + spec;
2934     QString includeSpec = buildPath + "/mkspecs/" + spec;
2935     if (!Environment::cpdir(pltSpec, defSpec, includeSpec)) {
2936         cout << "Couldn't update default " << pfx << "mkspec! Does " << qPrintable(pltSpec) << " exist?" << endl;
2937         dictionary["DONE"] = "error";
2938         return false;
2939     }
2940     return true;
2941 }
2942
2943 void Configure::generateConfigfiles()
2944 {
2945     QDir(buildPath).mkpath("src/corelib/global");
2946     QString outName(buildPath + "/src/corelib/global/qconfig.h");
2947     QTemporaryFile tmpFile;
2948     QTextStream tmpStream;
2949
2950     if (tmpFile.open()) {
2951         tmpStream.setDevice(&tmpFile);
2952
2953         if (dictionary[ "QCONFIG" ] == "full") {
2954             tmpStream << "/* Everything */" << endl;
2955         } else {
2956             QString configName("qconfig-" + dictionary[ "QCONFIG" ] + ".h");
2957             tmpStream << "/* Copied from " << configName << "*/" << endl;
2958             tmpStream << "#ifndef QT_BOOTSTRAPPED" << endl;
2959             QFile inFile(sourcePath + "/src/corelib/global/" + configName);
2960             if (inFile.open(QFile::ReadOnly)) {
2961                 QByteArray buffer = inFile.readAll();
2962                 tmpFile.write(buffer.constData(), buffer.size());
2963                 inFile.close();
2964             }
2965             tmpStream << "#endif // QT_BOOTSTRAPPED" << endl;
2966         }
2967         tmpStream << endl;
2968
2969         if (dictionary[ "SHARED" ] == "yes") {
2970             tmpStream << "#ifndef QT_DLL" << endl;
2971             tmpStream << "#define QT_DLL" << endl;
2972             tmpStream << "#endif" << endl;
2973         }
2974         tmpStream << endl;
2975         tmpStream << "/* License information */" << endl;
2976         tmpStream << "#define QT_PRODUCT_LICENSEE \"" << licenseInfo[ "LICENSEE" ] << "\"" << endl;
2977         tmpStream << "#define QT_PRODUCT_LICENSE \"" << dictionary[ "EDITION" ] << "\"" << endl;
2978         tmpStream << endl;
2979         tmpStream << "// Qt Edition" << endl;
2980         tmpStream << "#ifndef QT_EDITION" << endl;
2981         tmpStream << "#  define QT_EDITION " << dictionary["QT_EDITION"] << endl;
2982         tmpStream << "#endif" << endl;
2983         tmpStream << endl;
2984         if (dictionary["BUILDDEV"] == "yes") {
2985             dictionary["QMAKE_INTERNAL"] = "yes";
2986             tmpStream << "/* Used for example to export symbols for the certain autotests*/" << endl;
2987             tmpStream << "#define QT_BUILD_INTERNAL" << endl;
2988             tmpStream << endl;
2989         }
2990
2991         // ### For compatibility only, should be removed later.
2992         tmpStream << endl << "#define Q_WS_QPA" << endl;
2993
2994         tmpStream << endl << "// Compile time features" << endl;
2995
2996         QStringList qconfigList;
2997         if (dictionary["STYLE_WINDOWS"] != "yes")     qconfigList += "QT_NO_STYLE_WINDOWS";
2998         if (dictionary["STYLE_PLASTIQUE"] != "yes")   qconfigList += "QT_NO_STYLE_PLASTIQUE";
2999         if (dictionary["STYLE_CLEANLOOKS"] != "yes")   qconfigList += "QT_NO_STYLE_CLEANLOOKS";
3000         if (dictionary["STYLE_WINDOWSXP"] != "yes" && dictionary["STYLE_WINDOWSVISTA"] != "yes")
3001             qconfigList += "QT_NO_STYLE_WINDOWSXP";
3002         if (dictionary["STYLE_WINDOWSVISTA"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSVISTA";
3003         if (dictionary["STYLE_MOTIF"] != "yes")       qconfigList += "QT_NO_STYLE_MOTIF";
3004         if (dictionary["STYLE_CDE"] != "yes")         qconfigList += "QT_NO_STYLE_CDE";
3005
3006         // ### We still need the QT_NO_STYLE_S60 define for compiling Qt. Remove later!
3007         qconfigList += "QT_NO_STYLE_S60";
3008
3009         if (dictionary["STYLE_WINDOWSCE"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSCE";
3010         if (dictionary["STYLE_WINDOWSMOBILE"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSMOBILE";
3011         if (dictionary["STYLE_GTK"] != "yes")         qconfigList += "QT_NO_STYLE_GTK";
3012
3013         if (dictionary["GIF"] == "yes")              qconfigList += "QT_BUILTIN_GIF_READER=1";
3014         if (dictionary["PNG"] != "yes")              qconfigList += "QT_NO_IMAGEFORMAT_PNG";
3015         if (dictionary["JPEG"] != "yes")             qconfigList += "QT_NO_IMAGEFORMAT_JPEG";
3016         if (dictionary["ZLIB"] == "no") {
3017             qconfigList += "QT_NO_ZLIB";
3018             qconfigList += "QT_NO_COMPRESS";
3019         }
3020
3021         if (dictionary["ACCESSIBILITY"] == "no")     qconfigList += "QT_NO_ACCESSIBILITY";
3022         if (dictionary["WIDGETS"] == "no")           qconfigList += "QT_NO_WIDGETS";
3023         if (dictionary["OPENGL"] == "no")            qconfigList += "QT_NO_OPENGL";
3024         if (dictionary["OPENVG"] == "no")            qconfigList += "QT_NO_OPENVG";
3025         if (dictionary["OPENSSL"] == "no") {
3026             qconfigList += "QT_NO_OPENSSL";
3027             qconfigList += "QT_NO_SSL";
3028         }
3029         if (dictionary["OPENSSL"] == "linked")       qconfigList += "QT_LINKED_OPENSSL";
3030         if (dictionary["DBUS"] == "no")              qconfigList += "QT_NO_DBUS";
3031         if (dictionary["QML_DEBUG"] == "no")         qconfigList += "QT_QML_NO_DEBUGGER";
3032         if (dictionary["FREETYPE"] == "no")          qconfigList += "QT_NO_FREETYPE";
3033         if (dictionary["NATIVE_GESTURES"] == "no")   qconfigList += "QT_NO_NATIVE_GESTURES";
3034
3035         if (dictionary["OPENGL_ES_CM"] == "yes" ||
3036            dictionary["OPENGL_ES_2"]  == "yes")     qconfigList += "QT_OPENGL_ES";
3037
3038         if (dictionary["OPENGL_ES_CM"] == "yes")     qconfigList += "QT_OPENGL_ES_1";
3039         if (dictionary["OPENGL_ES_2"]  == "yes")     qconfigList += "QT_OPENGL_ES_2";
3040         if (dictionary["SQL_MYSQL"] == "yes")        qconfigList += "QT_SQL_MYSQL";
3041         if (dictionary["SQL_ODBC"] == "yes")         qconfigList += "QT_SQL_ODBC";
3042         if (dictionary["SQL_OCI"] == "yes")          qconfigList += "QT_SQL_OCI";
3043         if (dictionary["SQL_PSQL"] == "yes")         qconfigList += "QT_SQL_PSQL";
3044         if (dictionary["SQL_TDS"] == "yes")          qconfigList += "QT_SQL_TDS";
3045         if (dictionary["SQL_DB2"] == "yes")          qconfigList += "QT_SQL_DB2";
3046         if (dictionary["SQL_SQLITE"] == "yes")       qconfigList += "QT_SQL_SQLITE";
3047         if (dictionary["SQL_SQLITE2"] == "yes")      qconfigList += "QT_SQL_SQLITE2";
3048         if (dictionary["SQL_IBASE"] == "yes")        qconfigList += "QT_SQL_IBASE";
3049
3050         qconfigList.sort();
3051         for (int i = 0; i < qconfigList.count(); ++i)
3052             tmpStream << addDefine(qconfigList.at(i));
3053
3054         if (dictionary["EMBEDDED"] == "yes")
3055         {
3056             // Check for keyboard, mouse, gfx.
3057             QStringList kbdDrivers = dictionary["KBD_DRIVERS"].split(" ");;
3058             QStringList allKbdDrivers;
3059             allKbdDrivers<<"tty"<<"usb"<<"sl5000"<<"yopy"<<"vr41xx"<<"qvfb"<<"um";
3060             foreach (const QString &kbd, allKbdDrivers) {
3061                 if (!kbdDrivers.contains(kbd))
3062                     tmpStream<<"#define QT_NO_QWS_KBD_"<<kbd.toUpper()<<endl;
3063             }
3064
3065             QStringList mouseDrivers = dictionary["MOUSE_DRIVERS"].split(" ");
3066             QStringList allMouseDrivers;
3067             allMouseDrivers << "pc"<<"bus"<<"linuxtp"<<"yopy"<<"vr41xx"<<"tslib"<<"qvfb";
3068             foreach (const QString &mouse, allMouseDrivers) {
3069                 if (!mouseDrivers.contains(mouse))
3070                     tmpStream<<"#define QT_NO_QWS_MOUSE_"<<mouse.toUpper()<<endl;
3071             }
3072
3073             QStringList gfxDrivers = dictionary["GFX_DRIVERS"].split(" ");
3074             QStringList allGfxDrivers;
3075             allGfxDrivers<<"linuxfb"<<"transformed"<<"qvfb"<<"multiscreen"<<"ahi";
3076             foreach (const QString &gfx, allGfxDrivers) {
3077                 if (!gfxDrivers.contains(gfx))
3078                     tmpStream<<"#define QT_NO_QWS_"<<gfx.toUpper()<<endl;
3079             }
3080
3081             tmpStream<<"#define Q_WS_QWS"<<endl;
3082
3083             QStringList depths = dictionary[ "QT_QWS_DEPTH" ].split(" ");
3084             foreach (const QString &depth, depths)
3085               tmpStream<<"#define QT_QWS_DEPTH_"+depth<<endl;
3086         }
3087
3088         if (dictionary[ "QT_CUPS" ] == "no")
3089           tmpStream<<"#define QT_NO_CUPS"<<endl;
3090
3091         if (dictionary[ "QT_ICONV" ]  == "no")
3092           tmpStream<<"#define QT_NO_ICONV"<<endl;
3093
3094         if (dictionary[ "QT_GLIB" ] == "no")
3095           tmpStream<<"#define QT_NO_GLIB"<<endl;
3096
3097         if (dictionary[ "QT_INOTIFY" ] == "no")
3098           tmpStream<<"#define QT_NO_INOTIFY"<<endl;
3099
3100         if (dictionary[ "QT_SXE" ] == "no")
3101           tmpStream<<"#define QT_NO_SXE"<<endl;
3102
3103         tmpStream<<"#define QT_QPA_DEFAULT_PLATFORM_NAME \"" << qpaPlatformName() << "\""<<endl;
3104
3105         tmpStream.flush();
3106         tmpFile.flush();
3107
3108         // Replace old qconfig.h with new one
3109         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
3110         QFile::remove(outName);
3111         tmpFile.copy(outName);
3112         tmpFile.close();
3113     }
3114
3115     QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
3116     if (!copySpec("default", "", spec)
3117         || !copySpec("default-host", "host ", dictionary["QMAKESPEC"]))
3118         return;
3119
3120     // Generate the new qconfig.cpp file
3121     QDir(buildPath).mkpath("src/corelib/global");
3122     outName = buildPath + "/src/corelib/global/qconfig.cpp";
3123
3124     QTemporaryFile tmpFile2;
3125     if (tmpFile2.open()) {
3126         tmpStream.setDevice(&tmpFile2);
3127         tmpStream << "/* Licensed */" << endl
3128                   << "static const char qt_configure_licensee_str          [512 + 12] = \"qt_lcnsuser=" << licenseInfo["LICENSEE"] << "\";" << endl
3129                   << "static const char qt_configure_licensed_products_str [512 + 12] = \"qt_lcnsprod=" << dictionary["EDITION"] << "\";" << endl
3130                   << endl
3131                   << "/* Build date */" << endl
3132                   << "static const char qt_configure_installation          [11  + 12] = \"qt_instdate=" << QDate::currentDate().toString(Qt::ISODate) << "\";" << endl
3133                   << endl
3134                   << "static const char qt_configure_prefix_path_strs[][12 + 512] = {" << endl
3135                   << "    \"qt_prfxpath=" << formatPath(dictionary["QT_INSTALL_PREFIX"]) << "\"," << endl
3136                   << "    \"qt_docspath=" << formatPath(dictionary["QT_INSTALL_DOCS"]) << "\","  << endl
3137                   << "    \"qt_hdrspath=" << formatPath(dictionary["QT_INSTALL_HEADERS"]) << "\","  << endl
3138                   << "    \"qt_libspath=" << formatPath(dictionary["QT_INSTALL_LIBS"]) << "\","  << endl
3139                   << "    \"qt_binspath=" << formatPath(dictionary["QT_INSTALL_BINS"]) << "\","  << endl
3140                   << "    \"qt_plugpath=" << formatPath(dictionary["QT_INSTALL_PLUGINS"]) << "\","  << endl
3141                   << "    \"qt_impspath=" << formatPath(dictionary["QT_INSTALL_IMPORTS"]) << "\","  << endl
3142                   << "    \"qt_datapath=" << formatPath(dictionary["QT_INSTALL_DATA"]) << "\","  << endl
3143                   << "    \"qt_trnspath=" << formatPath(dictionary["QT_INSTALL_TRANSLATIONS"]) << "\"," << endl
3144                   << "    \"qt_xmplpath=" << formatPath(dictionary["QT_INSTALL_EXAMPLES"]) << "\","  << endl
3145                   << "    \"qt_tstspath=" << formatPath(dictionary["QT_INSTALL_TESTS"]) << "\","  << endl
3146                   << "#ifdef QT_BUILD_QMAKE" << endl
3147                   << "    \"qt_ssrtpath=" << formatPath(dictionary["CFG_SYSROOT"]) << "\"," << endl
3148                   << "    \"qt_hpfxpath=" << formatPath(dictionary["QT_HOST_PREFIX"]) << "\"," << endl
3149                   << "    \"qt_hbinpath=" << formatPath(dictionary["QT_HOST_BINS"]) << "\"," << endl
3150                   << "    \"qt_hdatpath=" << formatPath(dictionary["QT_HOST_DATA"]) << "\"," << endl
3151                   << "#endif" << endl
3152                   << "};" << endl
3153                   //<< "static const char qt_configure_settings_path_str [256] = \"qt_stngpath=" << formatPath(dictionary["QT_INSTALL_SETTINGS"]) << "\";" << endl
3154                   << endl
3155                   << "/* strlen( \"qt_lcnsxxxx\") == 12 */" << endl
3156                   << "#define QT_CONFIGURE_LICENSEE qt_configure_licensee_str + 12;" << endl
3157                   << "#define QT_CONFIGURE_LICENSED_PRODUCTS qt_configure_licensed_products_str + 12;" << endl
3158                   //<< "#define QT_CONFIGURE_SETTINGS_PATH qt_configure_settings_path_str + 12;" << endl
3159                   << endl;
3160
3161         tmpStream.flush();
3162         tmpFile2.flush();
3163
3164         // Replace old qconfig.cpp with new one
3165         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
3166         QFile::remove(outName);
3167         tmpFile2.copy(outName);
3168         tmpFile2.close();
3169     }
3170
3171     QTemporaryFile tmpFile3;
3172     if (tmpFile3.open()) {
3173         tmpStream.setDevice(&tmpFile3);
3174         tmpStream << "/* Evaluation license key */" << endl
3175                   << "static const volatile char qt_eval_key_data              [512 + 12] = \"qt_qevalkey=" << licenseInfo["LICENSEKEYEXT"] << "\";" << endl;
3176
3177         tmpStream.flush();
3178         tmpFile3.flush();
3179
3180         outName = buildPath + "/src/corelib/global/qconfig_eval.cpp";
3181         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
3182         QFile::remove(outName);
3183
3184         if (dictionary["EDITION"] == "Evaluation" || qmakeDefines.contains("QT_EVAL"))
3185             tmpFile3.copy(outName);
3186         tmpFile3.close();
3187     }
3188 }
3189 #endif
3190
3191 #if !defined(EVAL)
3192 void Configure::displayConfig()
3193 {
3194     fstream sout;
3195     sout.open(QString(buildPath + "/config.summary").toLocal8Bit().constData(),
3196               ios::in | ios::out | ios::trunc);
3197
3198     // Give some feedback
3199     sout << "Environment:" << endl;
3200     QString env = QString::fromLocal8Bit(getenv("INCLUDE")).replace(QRegExp("[;,]"), "\r\n      ");
3201     if (env.isEmpty())
3202         env = "Unset";
3203     sout << "    INCLUDE=\r\n      " << env << endl;
3204     env = QString::fromLocal8Bit(getenv("LIB")).replace(QRegExp("[;,]"), "\r\n      ");
3205     if (env.isEmpty())
3206         env = "Unset";
3207     sout << "    LIB=\r\n      " << env << endl;
3208     env = QString::fromLocal8Bit(getenv("PATH")).replace(QRegExp("[;,]"), "\r\n      ");
3209     if (env.isEmpty())
3210         env = "Unset";
3211     sout << "    PATH=\r\n      " << env << endl;
3212
3213     if (dictionary[QStringLiteral("EDITION")] != QStringLiteral("OpenSource")) {
3214         QString l1 = licenseInfo[ "LICENSEE" ];
3215         QString l2 = licenseInfo[ "LICENSEID" ];
3216         QString l3 = dictionary["EDITION"] + ' ' + "Edition";
3217         QString l4 = licenseInfo[ "EXPIRYDATE" ];
3218         sout << "Licensee...................." << (l1.isNull() ? "" : l1) << endl;
3219         sout << "License ID.................." << (l2.isNull() ? "" : l2) << endl;
3220         sout << "Product license............." << (l3.isNull() ? "" : l3) << endl;
3221         sout << "Expiry Date................." << (l4.isNull() ? "" : l4) << endl << endl;
3222     }
3223
3224     sout << "Configuration:" << endl;
3225     sout << "    " << qmakeConfig.join("\r\n    ") << endl;
3226     sout << "Qt Configuration:" << endl;
3227     sout << "    " << qtConfig.join("\r\n    ") << endl;
3228     sout << endl;
3229
3230     if (dictionary.contains("XQMAKESPEC"))
3231         sout << "QMAKESPEC..................." << dictionary[ "XQMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
3232     else
3233         sout << "QMAKESPEC..................." << dictionary[ "QMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
3234     sout << "Architecture................" << dictionary["QT_ARCH"]
3235          << ", features:" << dictionary["QT_CPU_FEATURES"] << endl;
3236     sout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"]
3237          << ", features:" << dictionary["QT_HOST_CPU_FEATURES"]  << endl;
3238     sout << "Maketool...................." << dictionary[ "MAKE" ] << endl;
3239     sout << "Debug symbols..............." << (dictionary[ "BUILD" ] == "debug" ? "yes" : "no") << endl;
3240     sout << "Link Time Code Generation..." << dictionary[ "LTCG" ] << endl;
3241     sout << "Accessibility support......." << dictionary[ "ACCESSIBILITY" ] << endl;
3242     sout << "RTTI support................" << dictionary[ "RTTI" ] << endl;
3243     sout << "SSE2 support................" << dictionary[ "SSE2" ] << endl;
3244     sout << "SSE3 support................" << dictionary[ "SSE3" ] << endl;
3245     sout << "SSSE3 support..............." << dictionary[ "SSSE3" ] << endl;
3246     sout << "SSE4.1 support.............." << dictionary[ "SSE4_1" ] << endl;
3247     sout << "SSE4.2 support.............." << dictionary[ "SSE4_2" ] << endl;
3248     sout << "AVX support................." << dictionary[ "AVX" ] << endl;
3249     sout << "AVX2 support................" << dictionary[ "AVX2" ] << endl;
3250     sout << "IWMMXT support.............." << dictionary[ "IWMMXT" ] << endl;
3251     sout << "OpenGL support.............." << dictionary[ "OPENGL" ] << endl;
3252     if (dictionary.value(QStringLiteral("OPENGL_ES_2")) == QStringLiteral("yes")) {
3253         const QString angleDir = dictionary.value(QStringLiteral("ANGLE_DIR"));
3254         if (!angleDir.isEmpty())
3255             sout << "ANGLE......................." << QDir::toNativeSeparators(angleDir) << endl;
3256     }
3257     sout << "OpenVG support.............." << dictionary[ "OPENVG" ] << endl;
3258     sout << "OpenSSL support............." << dictionary[ "OPENSSL" ] << endl;
3259     sout << "QtDBus support.............." << dictionary[ "DBUS" ] << endl;
3260     sout << "QtWidgets module support...." << dictionary[ "WIDGETS" ] << endl;
3261     sout << "QML debugging..............." << dictionary[ "QML_DEBUG" ] << endl;
3262     sout << "DirectWrite support........." << dictionary[ "DIRECTWRITE" ] << endl << endl;
3263
3264     sout << "Third Party Libraries:" << endl;
3265     sout << "    ZLIB support............" << dictionary[ "ZLIB" ] << endl;
3266     sout << "    GIF support............." << dictionary[ "GIF" ] << endl;
3267     sout << "    JPEG support............" << dictionary[ "JPEG" ] << endl;
3268     sout << "    PNG support............." << dictionary[ "PNG" ] << endl;
3269     sout << "    FreeType support........" << dictionary[ "FREETYPE" ] << endl << endl;
3270     sout << "    PCRE support............" << dictionary[ "PCRE" ] << endl;
3271     sout << "    ICU support............." << dictionary[ "ICU" ] << endl;
3272
3273     sout << "Styles:" << endl;
3274     sout << "    Windows................." << dictionary[ "STYLE_WINDOWS" ] << endl;
3275     sout << "    Windows XP.............." << dictionary[ "STYLE_WINDOWSXP" ] << endl;
3276     sout << "    Windows Vista..........." << dictionary[ "STYLE_WINDOWSVISTA" ] << endl;
3277     sout << "    Plastique..............." << dictionary[ "STYLE_PLASTIQUE" ] << endl;
3278     sout << "    Cleanlooks.............." << dictionary[ "STYLE_CLEANLOOKS" ] << endl;
3279     sout << "    Motif..................." << dictionary[ "STYLE_MOTIF" ] << endl;
3280     sout << "    CDE....................." << dictionary[ "STYLE_CDE" ] << endl;
3281     sout << "    Windows CE.............." << dictionary[ "STYLE_WINDOWSCE" ] << endl;
3282     sout << "    Windows Mobile.........." << dictionary[ "STYLE_WINDOWSMOBILE" ] << endl << endl;
3283
3284     sout << "Sql Drivers:" << endl;
3285     sout << "    ODBC...................." << dictionary[ "SQL_ODBC" ] << endl;
3286     sout << "    MySQL..................." << dictionary[ "SQL_MYSQL" ] << endl;
3287     sout << "    OCI....................." << dictionary[ "SQL_OCI" ] << endl;
3288     sout << "    PostgreSQL.............." << dictionary[ "SQL_PSQL" ] << endl;
3289     sout << "    TDS....................." << dictionary[ "SQL_TDS" ] << endl;
3290     sout << "    DB2....................." << dictionary[ "SQL_DB2" ] << endl;
3291     sout << "    SQLite.................." << dictionary[ "SQL_SQLITE" ] << " (" << dictionary[ "SQL_SQLITE_LIB" ] << ")" << endl;
3292     sout << "    SQLite2................." << dictionary[ "SQL_SQLITE2" ] << endl;
3293     sout << "    InterBase..............." << dictionary[ "SQL_IBASE" ] << endl << endl;
3294
3295     sout << "Sources are in.............." << QDir::toNativeSeparators(dictionary["QT_SOURCE_TREE"]) << endl;
3296     sout << "Build is done in............" << QDir::toNativeSeparators(dictionary["QT_BUILD_TREE"]) << endl;
3297     sout << "Install prefix.............." << QDir::toNativeSeparators(dictionary["QT_INSTALL_PREFIX"]) << endl;
3298     sout << "Headers installed to........" << QDir::toNativeSeparators(dictionary["QT_INSTALL_HEADERS"]) << endl;
3299     sout << "Libraries installed to......" << QDir::toNativeSeparators(dictionary["QT_INSTALL_LIBS"]) << endl;
3300     sout << "Plugins installed to........" << QDir::toNativeSeparators(dictionary["QT_INSTALL_PLUGINS"]) << endl;
3301     sout << "Imports installed to........" << QDir::toNativeSeparators(dictionary["QT_INSTALL_IMPORTS"]) << endl;
3302     sout << "Binaries installed to......." << QDir::toNativeSeparators(dictionary["QT_INSTALL_BINS"]) << endl;
3303     sout << "Docs installed to..........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_DOCS"]) << endl;
3304     sout << "Data installed to..........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_DATA"]) << endl;
3305     sout << "Translations installed to..." << QDir::toNativeSeparators(dictionary["QT_INSTALL_TRANSLATIONS"]) << endl;
3306     sout << "Examples installed to......." << QDir::toNativeSeparators(dictionary["QT_INSTALL_EXAMPLES"]) << endl;
3307     sout << "Tests installed to.........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_TESTS"]) << endl;
3308
3309     if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith(QLatin1String("wince"))) {
3310         sout << "Using c runtime detection..." << dictionary[ "CE_CRT" ] << endl;
3311         sout << "Cetest support.............." << dictionary[ "CETEST" ] << endl;
3312         sout << "Signature..................." << dictionary[ "CE_SIGNATURE"] << endl << endl;
3313     }
3314
3315     if (checkAvailability("INCREDIBUILD_XGE"))
3316         sout << "Using IncrediBuild XGE......" << dictionary["INCREDIBUILD_XGE"] << endl;
3317     if (!qmakeDefines.isEmpty()) {
3318         sout << "Defines.....................";
3319         for (QStringList::Iterator defs = qmakeDefines.begin(); defs != qmakeDefines.end(); ++defs)
3320             sout << (*defs) << " ";
3321         sout << endl;
3322     }
3323     if (!qmakeIncludes.isEmpty()) {
3324         sout << "Include paths...............";
3325         for (QStringList::Iterator incs = qmakeIncludes.begin(); incs != qmakeIncludes.end(); ++incs)
3326             sout << (*incs) << " ";
3327         sout << endl;
3328     }
3329     if (!qmakeLibs.isEmpty()) {
3330         sout << "Additional libraries........";
3331         for (QStringList::Iterator libs = qmakeLibs.begin(); libs != qmakeLibs.end(); ++libs)
3332             sout << (*libs) << " ";
3333         sout << endl;
3334     }
3335     if (dictionary[ "QMAKE_INTERNAL" ] == "yes") {
3336         sout << "Using internal configuration." << endl;
3337     }
3338     if (dictionary[ "SHARED" ] == "no") {
3339         sout << "WARNING: Using static linking will disable the use of plugins." << endl;
3340         sout << "         Make sure you compile ALL needed modules into the library." << endl;
3341     }
3342     if (dictionary[ "OPENSSL" ] == "linked" && opensslLibs.isEmpty()) {
3343         sout << "NOTE: When linking against OpenSSL, you can override the default" << endl;
3344         sout << "library names through OPENSSL_LIBS." << endl;
3345         sout << "For example:" << endl;
3346         sout << "    configure -openssl-linked OPENSSL_LIBS=\"-lssleay32 -llibeay32\"" << endl;
3347     }
3348     if (dictionary[ "ZLIB_FORCED" ] == "yes") {
3349         QString which_zlib = "supplied";
3350         if (dictionary[ "ZLIB" ] == "system")
3351             which_zlib = "system";
3352
3353         sout << "NOTE: The -no-zlib option was supplied but is no longer supported." << endl
3354              << endl
3355              << "Qt now requires zlib support in all builds, so the -no-zlib" << endl
3356              << "option was ignored. Qt will be built using the " << which_zlib
3357              << "zlib" << endl;
3358     }
3359     if (dictionary["OBSOLETE_ARCH_ARG"] == "yes") {
3360         sout << endl
3361              << "NOTE: The -arch option is obsolete." << endl
3362              << endl
3363              << "Qt now detects the target and host architectures based on compiler" << endl
3364              << "output. Qt will be built using " << dictionary["QT_ARCH"] << " for the target architecture" << endl
3365              << "and " << dictionary["QT_HOST_ARCH"] << " for the host architecture (note that these two" << endl
3366              << "will be the same unless you are cross-compiling)." << endl
3367              << endl;
3368     }
3369
3370     // display config.summary
3371     sout.seekg(0, ios::beg);
3372     while (sout) {
3373         string str;
3374         getline(sout, str);
3375         cout << str << endl;
3376     }
3377 }
3378 #endif
3379
3380 #if !defined(EVAL)
3381 void Configure::generateHeaders()
3382 {
3383     if (dictionary["SYNCQT"] == "yes") {
3384         if (findFile("perl.exe")) {
3385             cout << "Running syncqt..." << endl;
3386             QStringList args;
3387             args += buildPath + "/bin/syncqt.bat";
3388             args += sourcePath;
3389             QStringList env;
3390             env += QString("QTDIR=" + sourcePath);
3391             env += QString("PATH=" + buildPath + "/bin/;" + qgetenv("PATH"));
3392             int retc = Environment::execute(args, env, QStringList());
3393             if (retc) {
3394                 cout << "syncqt failed, return code " << retc << endl << endl;
3395                 dictionary["DONE"] = "error";
3396             }
3397         } else {
3398             cout << "Perl not found in environment - cannot run syncqt." << endl;
3399             dictionary["DONE"] = "error";
3400         }
3401     }
3402 }
3403
3404 void Configure::buildQmake()
3405 {
3406     if (dictionary[ "BUILD_QMAKE" ] == "yes") {
3407         QStringList args;
3408
3409         // Build qmake
3410         QString pwd = QDir::currentPath();
3411         if (!QDir(buildPath).mkpath("qmake")) {
3412             cout << "Cannot create qmake build dir." << endl;
3413             dictionary[ "DONE" ] = "error";
3414             return;
3415         }
3416         if (!QDir::setCurrent(buildPath + "/qmake")) {
3417             cout << "Cannot enter qmake build dir." << endl;
3418             dictionary[ "DONE" ] = "error";
3419             return;
3420         }
3421
3422         QString makefile = "Makefile";
3423         {
3424             QFile out(makefile);
3425             if (out.open(QFile::WriteOnly | QFile::Text)) {
3426                 QTextStream stream(&out);
3427                 stream << "#AutoGenerated by configure.exe" << endl
3428                     << "BUILD_PATH = " << QDir::toNativeSeparators(buildPath) << endl
3429                     << "SOURCE_PATH = " << QDir::toNativeSeparators(sourcePath) << endl;
3430                 stream << "QMAKESPEC = " << dictionary["QMAKESPEC"] << endl
3431                        << "QT_VERSION = " << dictionary["VERSION"] << endl;
3432
3433                 if (dictionary["EDITION"] == "OpenSource" ||
3434                     dictionary["QT_EDITION"].contains("OPENSOURCE"))
3435                     stream << "QMAKE_OPENSOURCE_EDITION = yes" << endl;
3436                 stream << "\n\n";
3437
3438                 QFile in(sourcePath + "/qmake/" + dictionary["QMAKEMAKEFILE"]);
3439                 if (in.open(QFile::ReadOnly | QFile::Text)) {
3440                     QString d = in.readAll();
3441                     //### need replaces (like configure.sh)? --Sam
3442                     stream << d << endl;
3443                 }
3444                 stream.flush();
3445                 out.close();
3446             }
3447         }
3448
3449         args += dictionary[ "MAKE" ];
3450         args += "-f";
3451         args += makefile;
3452
3453         cout << "Creating qmake..." << endl;
3454         int exitCode = Environment::execute(args, QStringList(), QStringList());
3455         if (exitCode) {
3456             args.clear();
3457             args += dictionary[ "MAKE" ];
3458             args += "-f";
3459             args += makefile;
3460             args += "clean";
3461             exitCode = Environment::execute(args, QStringList(), QStringList());
3462             if (exitCode) {
3463                 cout << "Cleaning qmake failed, return code " << exitCode << endl << endl;
3464                 dictionary[ "DONE" ] = "error";
3465             } else {
3466                 args.clear();
3467                 args += dictionary[ "MAKE" ];
3468                 args += "-f";
3469                 args += makefile;
3470                 exitCode = Environment::execute(args, QStringList(), QStringList());
3471                 if (exitCode) {
3472                     cout << "Building qmake failed, return code " << exitCode << endl << endl;
3473                     dictionary[ "DONE" ] = "error";
3474                 }
3475             }
3476         }
3477         QDir::setCurrent(pwd);
3478     }
3479
3480     // Generate qt.conf
3481     QFile confFile(buildPath + "/bin/qt.conf");
3482     if (confFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
3483         QTextStream confStream(&confFile);
3484         confStream << "[EffectivePaths]" << endl
3485                    << "Prefix=.." << endl;
3486
3487         confStream.flush();
3488         confFile.close();
3489     }
3490 }
3491 #endif
3492
3493 void Configure::buildHostTools()
3494 {
3495     if (dictionary[ "NOPROCESS" ] == "yes")
3496         dictionary[ "DONE" ] = "yes";
3497
3498     if (!dictionary.contains("XQMAKESPEC"))
3499         return;
3500
3501     QString pwd = QDir::currentPath();
3502     QStringList hostToolsDirs;
3503     hostToolsDirs
3504         << "src/tools";
3505
3506     for (int i = 0; i < hostToolsDirs.count(); ++i) {
3507         cout << "Creating " << hostToolsDirs.at(i) << " ..." << endl;
3508         QString toolBuildPath = buildPath + "/" + hostToolsDirs.at(i);
3509         QString toolSourcePath = sourcePath + "/" + hostToolsDirs.at(i);
3510
3511         // generate Makefile
3512         QStringList args;
3513         args << QDir::toNativeSeparators(buildPath + "/bin/qmake");
3514         // override .qmake.cache because we are not cross-building these.
3515         // we need a full path so that a build with -prefix will still find it.
3516         args << "-spec" << QDir::toNativeSeparators(buildPath + "/mkspecs/" + dictionary["QMAKESPEC"]);
3517         args << "-r";
3518         args << "-o" << QDir::toNativeSeparators(toolBuildPath + "/Makefile");
3519
3520         QDir().mkpath(toolBuildPath);
3521         QDir::setCurrent(toolSourcePath);
3522         int exitCode = Environment::execute(args, QStringList(), QStringList());
3523         if (exitCode) {
3524             cout << "qmake failed, return code " << exitCode << endl << endl;
3525             dictionary["DONE"] = "error";
3526             break;
3527         }
3528
3529         // build app
3530         args.clear();
3531         args += dictionary["MAKE"];
3532         QDir::setCurrent(toolBuildPath);
3533         exitCode = Environment::execute(args, QStringList(), QStringList());
3534         if (exitCode) {
3535             args.clear();
3536             args += dictionary["MAKE"];
3537             args += "clean";
3538             exitCode = Environment::execute(args, QStringList(), QStringList());
3539             if (exitCode) {
3540                 cout << "Cleaning " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl;
3541                 dictionary["DONE"] = "error";
3542                 break;
3543             } else {
3544                 args.clear();
3545                 args += dictionary["MAKE"];
3546                 exitCode = Environment::execute(args, QStringList(), QStringList());
3547                 if (exitCode) {
3548                     cout << "Building " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl;
3549                     dictionary["DONE"] = "error";
3550                     break;
3551                 }
3552             }
3553         }
3554     }
3555     QDir::setCurrent(pwd);
3556 }
3557
3558 void Configure::findProjects(const QString& dirName)
3559 {
3560     if (dictionary[ "NOPROCESS" ] == "no") {
3561         QDir dir(dirName);
3562         QString entryName;
3563         int makeListNumber;
3564         ProjectType qmakeTemplate;
3565         const QFileInfoList &list = dir.entryInfoList(QStringList(QLatin1String("*.pro")),
3566                                                       QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
3567         for (int i = 0; i < list.size(); ++i) {
3568             const QFileInfo &fi = list.at(i);
3569             if (fi.fileName() != "qmake.pro") {
3570                 entryName = dirName + "/" + fi.fileName();
3571                 if (fi.isDir()) {
3572                     findProjects(entryName);
3573                 } else {
3574                     qmakeTemplate = projectType(fi.absoluteFilePath());
3575                     switch (qmakeTemplate) {
3576                     case Lib:
3577                     case Subdirs:
3578                         makeListNumber = 1;
3579                         break;
3580                     default:
3581                         makeListNumber = 2;
3582                         break;
3583                     }
3584                     makeList[makeListNumber].append(new MakeItem(sourceDir.relativeFilePath(fi.absolutePath()),
3585                                                     fi.fileName(),
3586                                                     "Makefile",
3587                                                     qmakeTemplate));
3588                 }
3589             }
3590
3591         }
3592     }
3593 }
3594
3595 void Configure::appendMakeItem(int inList, const QString &item)
3596 {
3597     QString dir;
3598     if (item != "src")
3599         dir = "/" + item;
3600     dir.prepend("/src");
3601     makeList[inList].append(new MakeItem(sourcePath + dir,
3602         item + ".pro", buildPath + dir + "/Makefile", Lib));
3603     if (dictionary[ "DSPFILES" ] == "yes") {
3604         makeList[inList].append(new MakeItem(sourcePath + dir,
3605             item + ".pro", buildPath + dir + "/" + item + ".dsp", Lib));
3606     }
3607     if (dictionary[ "VCPFILES" ] == "yes") {
3608         makeList[inList].append(new MakeItem(sourcePath + dir,
3609             item + ".pro", buildPath + dir + "/" + item + ".vcp", Lib));
3610     }
3611     if (dictionary[ "VCPROJFILES" ] == "yes") {
3612         makeList[inList].append(new MakeItem(sourcePath + dir,
3613             item + ".pro", buildPath + dir + "/" + item + ".vcproj", Lib));
3614     }
3615 }
3616
3617 void Configure::generateMakefiles()
3618 {
3619     if (dictionary[ "NOPROCESS" ] == "no") {
3620 #if !defined(EVAL)
3621         cout << "Creating makefiles in src..." << endl;
3622 #endif
3623
3624         QString spec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
3625         if (spec != "win32-msvc")
3626             dictionary[ "DSPFILES" ] = "no";
3627
3628         if (spec != "win32-msvc.net" && !spec.startsWith("win32-msvc2") && !spec.startsWith(QLatin1String("wince")))
3629             dictionary[ "VCPROJFILES" ] = "no";
3630
3631         int i = 0;
3632         QString pwd = QDir::currentPath();
3633         if (dictionary["FAST"] != "yes") {
3634             QString dirName;
3635             bool generate = true;
3636             bool doDsp = (dictionary["DSPFILES"] == "yes" || dictionary["VCPFILES"] == "yes"
3637                           || dictionary["VCPROJFILES"] == "yes");
3638             while (generate) {
3639                 QString pwd = QDir::currentPath();
3640                 QString dirPath = buildPath + dirName;
3641                 QStringList args;
3642
3643                 args << buildPath + "/bin/qmake";
3644
3645                 if (doDsp) {
3646                     if (dictionary[ "DEPENDENCIES" ] == "no")
3647                         args << "-nodepend";
3648                     args << "-tp" <<  "vc";
3649                     doDsp = false; // DSP files will be done
3650                     printf("Generating Visual Studio project files...\n");
3651                 } else {
3652                     printf("Generating Makefiles...\n");
3653                     generate = false; // Now Makefiles will be done
3654                 }
3655                 args << "-r";
3656                 args << (sourcePath + "/qtbase.pro");
3657                 args << "-o";
3658                 args << buildPath;
3659                 if (!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
3660                     args << dictionary[ "QMAKEADDITIONALARGS" ];
3661
3662                 QDir::setCurrent(dirPath);
3663                 if (int exitCode = Environment::execute(args, QStringList(), QStringList())) {
3664                     cout << "Qmake failed, return code " << exitCode  << endl << endl;
3665                     dictionary[ "DONE" ] = "error";
3666                 }
3667             }
3668         } else {
3669             findProjects(sourcePath);
3670             for (i=0; i<3; i++) {
3671                 for (int j=0; j<makeList[i].size(); ++j) {
3672                     MakeItem *it=makeList[i][j];
3673                     if (it->directory == "tools/configure")
3674                         continue; // don't overwrite our own Makefile
3675
3676                     QString dirPath = it->directory + '/';
3677                     QString projectName = it->proFile;
3678                     QString makefileName = buildPath + "/" + dirPath + it->target;
3679
3680                     // For shadowbuilds, we need to create the path first
3681                     QDir buildPathDir(buildPath);
3682                     if (sourcePath != buildPath && !buildPathDir.exists(dirPath))
3683                         buildPathDir.mkpath(dirPath);
3684
3685                     QStringList args;
3686
3687                     args << QDir::toNativeSeparators(buildPath + "/bin/qmake.exe");
3688                     args << sourcePath + "/" + dirPath + projectName;
3689                     args << dictionary[ "QMAKE_ALL_ARGS" ];
3690
3691                     cout << "For " << qPrintable(QDir::toNativeSeparators(dirPath + projectName)) << endl;
3692                     args << "-o";
3693                     args << it->target;
3694                     if (!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
3695                         args << dictionary[ "QMAKEADDITIONALARGS" ];
3696
3697                     QDir::setCurrent(dirPath);
3698
3699                     QFile file(makefileName);
3700                     if (!file.open(QFile::WriteOnly | QFile::Text)) {
3701                         printf("failed on dirPath=%s, makefile=%s\n",
3702                                qPrintable(QDir::toNativeSeparators(dirPath)),
3703                                qPrintable(QDir::toNativeSeparators(makefileName)));
3704                         continue;
3705                     }
3706                     QTextStream txt(&file);
3707                     txt << "all:\n";
3708                     txt << "\t" << args.join(" ") << "\n";
3709                     txt << "\t$(MAKE) -$(MAKEFLAGS) -f " << it->target << "\n";
3710                     txt << "first: all\n";
3711                     txt << "qmake:\n";
3712                     txt << "\t" << args.join(" ") << "\n";
3713                 }
3714             }
3715         }
3716         QDir::setCurrent(pwd);
3717     } else {
3718         cout << "Processing of project files have been disabled." << endl;
3719         cout << "Only use this option if you really know what you're doing." << endl << endl;
3720         return;
3721     }
3722 }
3723
3724 void Configure::showSummary()
3725 {
3726     QString make = dictionary[ "MAKE" ];
3727     if (!dictionary.contains("XQMAKESPEC")) {
3728         cout << endl << endl << "Qt is now configured for building. Just run " << qPrintable(make) << "." << endl;
3729         cout << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl;
3730     } else if (dictionary.value("QMAKESPEC").startsWith("wince")) {
3731         // we are cross compiling for Windows CE
3732         cout << endl << endl << "Qt is now configured for building. To start the build run:" << endl
3733              << "\tsetcepaths " << dictionary.value("XQMAKESPEC") << endl
3734              << "\t" << qPrintable(make) << endl
3735              << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl;
3736     }
3737 }
3738
3739 Configure::ProjectType Configure::projectType(const QString& proFileName)
3740 {
3741     QFile proFile(proFileName);
3742     if (proFile.open(QFile::ReadOnly)) {
3743         QString buffer = proFile.readLine(1024);
3744         while (!buffer.isEmpty()) {
3745             QStringList segments = buffer.split(QRegExp("\\s"));
3746             QStringList::Iterator it = segments.begin();
3747
3748             if (segments.size() >= 3) {
3749                 QString keyword = (*it++);
3750                 QString operation = (*it++);
3751                 QString value = (*it++);
3752
3753                 if (keyword == "TEMPLATE") {
3754                     if (value == "lib")
3755                         return Lib;
3756                     else if (value == "subdirs")
3757                         return Subdirs;
3758                 }
3759             }
3760             // read next line
3761             buffer = proFile.readLine(1024);
3762         }
3763         proFile.close();
3764     }
3765     // Default to app handling
3766     return App;
3767 }
3768
3769 #if !defined(EVAL)
3770
3771 bool Configure::showLicense(QString orgLicenseFile)
3772 {
3773     if (dictionary["LICENSE_CONFIRMED"] == "yes") {
3774         cout << "You have already accepted the terms of the license." << endl << endl;
3775         return true;
3776     }
3777
3778     bool haveGpl3 = false;
3779     QString licenseFile = orgLicenseFile;
3780     QString theLicense;
3781     if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3782         haveGpl3 = QFile::exists(orgLicenseFile + "/LICENSE.GPL3");
3783         theLicense = "GNU Lesser General Public License (LGPL) version 2.1";
3784         if (haveGpl3)
3785             theLicense += "\nor the GNU General Public License (GPL) version 3";
3786     } else {
3787         // the first line of the license file tells us which license it is
3788         QFile file(licenseFile);
3789         if (!file.open(QFile::ReadOnly)) {
3790             cout << "Failed to load LICENSE file" << endl;
3791             return false;
3792         }
3793         theLicense = file.readLine().trimmed();
3794     }
3795
3796     forever {
3797         char accept = '?';
3798         cout << "You are licensed to use this software under the terms of" << endl
3799              << "the " << theLicense << "." << endl
3800              << endl;
3801         if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3802             if (haveGpl3)
3803                 cout << "Type '3' to view the GNU General Public License version 3 (GPLv3)." << endl;
3804             cout << "Type 'L' to view the Lesser GNU General Public License version 2.1 (LGPLv2.1)." << endl;
3805         } else {
3806             cout << "Type '?' to view the " << theLicense << "." << endl;
3807         }
3808         cout << "Type 'y' to accept this license offer." << endl
3809              << "Type 'n' to decline this license offer." << endl
3810              << endl
3811              << "Do you accept the terms of the license?" << endl;
3812         cin >> accept;
3813         accept = tolower(accept);
3814
3815         if (accept == 'y') {
3816             return true;
3817         } else if (accept == 'n') {
3818             return false;
3819         } else {
3820             if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3821                 if (accept == '3')
3822                     licenseFile = orgLicenseFile + "/LICENSE.GPL3";
3823                 else
3824                     licenseFile = orgLicenseFile + "/LICENSE.LGPL";
3825             }
3826             // Get console line height, to fill the screen properly
3827             int i = 0, screenHeight = 25; // default
3828             CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
3829             HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
3830             if (GetConsoleScreenBufferInfo(stdOut, &consoleInfo))
3831                 screenHeight = consoleInfo.srWindow.Bottom
3832                              - consoleInfo.srWindow.Top
3833                              - 1; // Some overlap for context
3834
3835             // Prompt the license content to the user
3836             QFile file(licenseFile);
3837             if (!file.open(QFile::ReadOnly)) {
3838                 cout << "Failed to load LICENSE file" << licenseFile << endl;
3839                 return false;
3840             }
3841             QStringList licenseContent = QString(file.readAll()).split('\n');
3842             while (i < licenseContent.size()) {
3843                 cout << licenseContent.at(i) << endl;
3844                 if (++i % screenHeight == 0) {
3845                     cout << "(Press any key for more..)";
3846                     if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
3847                         exit(0);      // Exit cleanly for Ctrl+C
3848                     cout << "\r";     // Overwrite text above
3849                 }
3850             }
3851         }
3852     }
3853 }
3854
3855 void Configure::readLicense()
3856 {
3857     dictionary["PLATFORM NAME"] = platformName();
3858     dictionary["LICENSE FILE"] = sourcePath;
3859
3860     bool openSource = false;
3861     bool hasOpenSource = QFile::exists(dictionary["LICENSE FILE"] + "/LICENSE.GPL3") || QFile::exists(dictionary["LICENSE FILE"] + "/LICENSE.LGPL");
3862     if (dictionary["BUILDTYPE"] == "commercial") {
3863         openSource = false;
3864     } else if (dictionary["BUILDTYPE"] == "opensource") {
3865         openSource = true;
3866     } else if (hasOpenSource) { // No Open Source? Just display the commercial license right away
3867         forever {
3868             char accept = '?';
3869             cout << "Which edition of Qt do you want to use ?" << endl;
3870             cout << "Type 'c' if you want to use the Commercial Edition." << endl;
3871             cout << "Type 'o' if you want to use the Open Source Edition." << endl;
3872             cin >> accept;
3873             accept = tolower(accept);
3874
3875             if (accept == 'c') {
3876                 openSource = false;
3877                 break;
3878             } else if (accept == 'o') {
3879                 openSource = true;
3880                 break;
3881             }
3882         }
3883     }
3884     if (hasOpenSource && openSource) {
3885         cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " Open Source Edition." << endl;
3886         licenseInfo["LICENSEE"] = "Open Source";
3887         dictionary["EDITION"] = "OpenSource";
3888         dictionary["QT_EDITION"] = "QT_EDITION_OPENSOURCE";
3889         cout << endl;
3890         if (!showLicense(dictionary["LICENSE FILE"])) {
3891             cout << "Configuration aborted since license was not accepted";
3892             dictionary["DONE"] = "error";
3893             return;
3894         }
3895     } else if (openSource) {
3896         cout << endl << "Cannot find the GPL license files! Please download the Open Source version of the library." << endl;
3897         dictionary["DONE"] = "error";
3898     }
3899 #ifdef COMMERCIAL_VERSION
3900     else {
3901         Tools::checkLicense(dictionary, licenseInfo, firstLicensePath());
3902         if (dictionary["DONE"] != "error") {
3903             // give the user some feedback, and prompt for license acceptance
3904             cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl;
3905             if (!showLicense(dictionary["LICENSE FILE"])) {
3906                 cout << "Configuration aborted since license was not accepted";
3907                 dictionary["DONE"] = "error";
3908                 return;
3909             }
3910         }
3911     }
3912 #else // !COMMERCIAL_VERSION
3913     else {
3914         cout << endl << "Cannot build commercial edition from the open source version of the library." << endl;
3915         dictionary["DONE"] = "error";
3916     }
3917 #endif
3918 }
3919
3920 void Configure::reloadCmdLine()
3921 {
3922     if (dictionary[ "REDO" ] == "yes") {
3923         QFile inFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
3924         if (inFile.open(QFile::ReadOnly)) {
3925             QTextStream inStream(&inFile);
3926             QString buffer;
3927             inStream >> buffer;
3928             while (buffer.length()) {
3929                 configCmdLine += buffer;
3930                 inStream >> buffer;
3931             }
3932             inFile.close();
3933         }
3934     }
3935 }
3936
3937 void Configure::saveCmdLine()
3938 {
3939     if (dictionary[ "REDO" ] != "yes") {
3940         QFile outFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
3941         if (outFile.open(QFile::WriteOnly | QFile::Text)) {
3942             QTextStream outStream(&outFile);
3943             for (QStringList::Iterator it = configCmdLine.begin(); it != configCmdLine.end(); ++it) {
3944                 outStream << (*it) << " " << endl;
3945             }
3946             outStream.flush();
3947             outFile.close();
3948         }
3949     }
3950 }
3951 #endif // !EVAL
3952
3953 bool Configure::isDone()
3954 {
3955     return !dictionary["DONE"].isEmpty();
3956 }
3957
3958 bool Configure::isOk()
3959 {
3960     return (dictionary[ "DONE" ] != "error");
3961 }
3962
3963 QString Configure::platformName() const
3964 {
3965     switch (platform()) {
3966     default:
3967     case WINDOWS:
3968         return QStringLiteral("Qt for Windows");
3969     case WINDOWS_CE:
3970         return QStringLiteral("Qt for Windows CE");
3971     case QNX:
3972         return QStringLiteral("Qt for QNX");
3973     case BLACKBERRY:
3974         return QStringLiteral("Qt for Blackberry");
3975     }
3976 }
3977
3978 QString Configure::qpaPlatformName() const
3979 {
3980     switch (platform()) {
3981     default:
3982     case WINDOWS:
3983     case WINDOWS_CE:
3984         return QStringLiteral("windows");
3985     case QNX:
3986         return QStringLiteral("qnx");
3987     case BLACKBERRY:
3988         return QStringLiteral("blackberry");
3989     }
3990 }
3991
3992 int Configure::platform() const
3993 {
3994     const QString qMakeSpec = dictionary.value("QMAKESPEC");
3995     const QString xQMakeSpec = dictionary.value("XQMAKESPEC");
3996
3997     if ((qMakeSpec.startsWith("wince") || xQMakeSpec.startsWith("wince")))
3998         return WINDOWS_CE;
3999
4000     if (xQMakeSpec.contains("qnx"))
4001         return QNX;
4002
4003     if (xQMakeSpec.contains("blackberry"))
4004         return BLACKBERRY;
4005
4006     return WINDOWS;
4007 }
4008
4009 bool
4010 Configure::filesDiffer(const QString &fn1, const QString &fn2)
4011 {
4012     QFile file1(fn1), file2(fn2);
4013     if (!file1.open(QFile::ReadOnly) || !file2.open(QFile::ReadOnly))
4014         return true;
4015     const int chunk = 2048;
4016     int used1 = 0, used2 = 0;
4017     char b1[chunk], b2[chunk];
4018     while (!file1.atEnd() && !file2.atEnd()) {
4019         if (!used1)
4020             used1 = file1.read(b1, chunk);
4021         if (!used2)
4022             used2 = file2.read(b2, chunk);
4023         if (used1 > 0 && used2 > 0) {
4024             const int cmp = qMin(used1, used2);
4025             if (memcmp(b1, b2, cmp))
4026                 return true;
4027             if ((used1 -= cmp))
4028                 memcpy(b1, b1+cmp, used1);
4029             if ((used2 -= cmp))
4030                 memcpy(b2, b2+cmp, used2);
4031         }
4032     }
4033     return !file1.atEnd() || !file2.atEnd();
4034 }
4035
4036 QT_END_NAMESPACE