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