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