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