configure: Unify order of options in help
[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("BUILDDEV", "yes", "-developer-build",      "Compile and link Qt with Qt developer options (including auto-tests exporting)\n");
1606
1607         desc("OPENSOURCE", "opensource", "-opensource",   "Compile and link the Open-Source Edition of Qt.");
1608         desc("COMMERCIAL", "commercial", "-commercial",   "Compile and link the Commercial Edition of Qt.\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["XQMAKESPEC"].isEmpty() && !dictionary["XQMAKESPEC"].startsWith("wince")) {
2892             // FIXME: add detection
2893             configStream << "QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib" << endl;
2894             configStream << "QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include" << endl;
2895         }
2896         if (dictionary["QT_EDITION"].contains("OPENSOURCE"))
2897             configStream << "QT_EDITION = " << QLatin1String("OpenSource") << endl;
2898         else
2899             configStream << "QT_EDITION = " << dictionary["EDITION"] << endl;
2900         configStream << "QT_CONFIG += " << qtConfig.join(" ") << endl;
2901
2902         configStream << "#versioning " << endl
2903                      << "QT_VERSION = " << dictionary["VERSION"] << endl
2904                      << "QT_MAJOR_VERSION = " << dictionary["VERSION_MAJOR"] << endl
2905                      << "QT_MINOR_VERSION = " << dictionary["VERSION_MINOR"] << endl
2906                      << "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl;
2907
2908         if (!dictionary["CFG_SYSROOT"].isEmpty() && dictionary["CFG_GCC_SYSROOT"] == "yes") {
2909             configStream << endl
2910                          << "# sysroot" << endl
2911                          << "!host_build {" << endl
2912                          << "    QMAKE_CFLAGS    += --sysroot=$$[QT_SYSROOT]" << endl
2913                          << "    QMAKE_CXXFLAGS  += --sysroot=$$[QT_SYSROOT]" << endl
2914                          << "    QMAKE_LFLAGS    += --sysroot=$$[QT_SYSROOT]" << endl
2915                          << "}" << endl;
2916         }
2917
2918         if (!dictionary["QMAKE_RPATHDIR"].isEmpty())
2919             configStream << "QMAKE_RPATHDIR += " << formatPath(dictionary["QMAKE_RPATHDIR"]) << endl;
2920
2921         if (!dictionary["QT_LIBINFIX"].isEmpty())
2922             configStream << "QT_LIBINFIX = " << dictionary["QT_LIBINFIX"] << endl;
2923
2924         if (!dictionary["QT_NAMESPACE"].isEmpty())
2925             configStream << "#namespaces" << endl << "QT_NAMESPACE = " << dictionary["QT_NAMESPACE"] << endl;
2926
2927         if (dictionary.value(QStringLiteral("OPENGL_ES_2")) == QStringLiteral("yes")) {
2928             const QString angleDir = dictionary.value(QStringLiteral("ANGLE_DIR"));
2929             if (!angleDir.isEmpty()) {
2930                 configStream
2931                     << "QMAKE_INCDIR_OPENGL_ES2 = " << angleDir << "/include\n"
2932                     << "QMAKE_LIBDIR_OPENGL_ES2_DEBUG = " << angleDir << "/lib/Debug\n"
2933                     << "QMAKE_LIBDIR_OPENGL_ES2_RELEASE = " << angleDir << "/lib/Release\n";
2934             }
2935         }
2936
2937         configStream.flush();
2938         configFile.close();
2939     }
2940 }
2941 #endif
2942
2943 QString Configure::addDefine(QString def)
2944 {
2945     QString result, defNeg, defD = def;
2946
2947     defD.replace(QRegExp("=.*"), "");
2948     def.replace(QRegExp("="), " ");
2949
2950     if (def.startsWith("QT_NO_")) {
2951         defNeg = defD;
2952         defNeg.replace("QT_NO_", "QT_");
2953     } else if (def.startsWith("QT_")) {
2954         defNeg = defD;
2955         defNeg.replace("QT_", "QT_NO_");
2956     }
2957
2958     if (defNeg.isEmpty()) {
2959         result = "#ifndef $DEFD\n"
2960                  "# define $DEF\n"
2961                  "#endif\n\n";
2962     } else {
2963         result = "#if defined($DEFD) && defined($DEFNEG)\n"
2964                  "# undef $DEFD\n"
2965                  "#elif !defined($DEFD)\n"
2966                  "# define $DEF\n"
2967                  "#endif\n\n";
2968     }
2969     result.replace("$DEFNEG", defNeg);
2970     result.replace("$DEFD", defD);
2971     result.replace("$DEF", def);
2972     return result;
2973 }
2974
2975 #if !defined(EVAL)
2976 bool Configure::copySpec(const char *name, const char *pfx, const QString &spec)
2977 {
2978     // "Link" configured mkspec to default directory, but remove the old one first, if there is any
2979     QString defSpec = buildPath + "/mkspecs/" + name;
2980     QFileInfo defSpecInfo(defSpec);
2981     if (defSpecInfo.exists()) {
2982         if (!Environment::rmdir(defSpec)) {
2983             cout << "Couldn't update default " << pfx << "mkspec! Are files in " << qPrintable(defSpec) << " read-only?" << endl;
2984             dictionary["DONE"] = "error";
2985             return false;
2986         }
2987     }
2988
2989     QDir::current().mkpath(defSpec);
2990     QFile qfile(defSpec + "/qmake.conf");
2991     if (qfile.open(QFile::WriteOnly | QFile::Text)) {
2992         QTextStream fileStream;
2993         fileStream.setDevice(&qfile);
2994         QString srcSpec = buildPath + "/mkspecs/" + spec; // We copied it to the build dir
2995         fileStream << "QMAKESPEC_ORIGINAL = " << formatPath(srcSpec) << endl;
2996         fileStream << "include(" << formatPath(QDir(defSpec).relativeFilePath(srcSpec + "/qmake.conf")) << ")" << endl;
2997         qfile.close();
2998     }
2999     if (qfile.error() != QFile::NoError) {
3000         cout << "Couldn't update default " << pfx << "mkspec: " << qPrintable(qfile.errorString()) << endl;
3001         dictionary["DONE"] = "error";
3002         return false;
3003     }
3004     return true;
3005 }
3006
3007 void Configure::generateConfigfiles()
3008 {
3009     QDir(buildPath).mkpath("src/corelib/global");
3010     QString outName(buildPath + "/src/corelib/global/qconfig.h");
3011     QTemporaryFile tmpFile;
3012     QTextStream tmpStream;
3013
3014     if (tmpFile.open()) {
3015         tmpStream.setDevice(&tmpFile);
3016
3017         if (dictionary[ "QCONFIG" ] == "full") {
3018             tmpStream << "/* Everything */" << endl;
3019         } else {
3020             QString configName("qconfig-" + dictionary[ "QCONFIG" ] + ".h");
3021             tmpStream << "/* Copied from " << configName << "*/" << endl;
3022             tmpStream << "#ifndef QT_BOOTSTRAPPED" << endl;
3023             QFile inFile(sourcePath + "/src/corelib/global/" + configName);
3024             if (inFile.open(QFile::ReadOnly)) {
3025                 QByteArray buffer = inFile.readAll();
3026                 tmpFile.write(buffer.constData(), buffer.size());
3027                 inFile.close();
3028             }
3029             tmpStream << "#endif // QT_BOOTSTRAPPED" << endl;
3030         }
3031         tmpStream << endl;
3032
3033         if (dictionary[ "SHARED" ] == "no") {
3034             tmpStream << "/* Qt was configured for a static build */" << endl
3035                       << "#if !defined(QT_SHARED) && !defined(QT_STATIC)" << endl
3036                       << "# define QT_STATIC" << endl
3037                       << "#endif" << endl
3038                       << endl;
3039         }
3040         tmpStream << "/* License information */" << endl;
3041         tmpStream << "#define QT_PRODUCT_LICENSEE \"" << licenseInfo[ "LICENSEE" ] << "\"" << endl;
3042         tmpStream << "#define QT_PRODUCT_LICENSE \"" << dictionary[ "EDITION" ] << "\"" << endl;
3043         tmpStream << endl;
3044         tmpStream << "// Qt Edition" << endl;
3045         tmpStream << "#ifndef QT_EDITION" << endl;
3046         tmpStream << "#  define QT_EDITION " << dictionary["QT_EDITION"] << endl;
3047         tmpStream << "#endif" << endl;
3048         tmpStream << endl;
3049         if (dictionary["BUILDDEV"] == "yes") {
3050             dictionary["QMAKE_INTERNAL"] = "yes";
3051             tmpStream << "/* Used for example to export symbols for the certain autotests*/" << endl;
3052             tmpStream << "#define QT_BUILD_INTERNAL" << endl;
3053             tmpStream << endl;
3054         }
3055
3056         tmpStream << endl << "// Compiler sub-arch support" << endl;
3057         if (dictionary[ "SSE2" ] == "yes")
3058             tmpStream << "#define QT_COMPILER_SUPPORTS_SSE2" << endl;
3059         if (dictionary[ "SSE3" ] == "yes")
3060             tmpStream << "#define QT_COMPILER_SUPPORTS_SSE3" << endl;
3061         if (dictionary[ "SSSE3" ] == "yes")
3062             tmpStream << "#define QT_COMPILER_SUPPORTS_SSSE3" << endl;
3063         if (dictionary[ "SSE4_1" ] == "yes")
3064             tmpStream << "#define QT_COMPILER_SUPPORTS_SSE4_1" << endl;
3065         if (dictionary[ "SSE4_2" ] == "yes")
3066             tmpStream << "#define QT_COMPILER_SUPPORTS_SSE4_2" << endl;
3067         if (dictionary[ "AVX" ] == "yes")
3068             tmpStream << "#define QT_COMPILER_SUPPORTS_AVX" << endl;
3069         if (dictionary[ "AVX2" ] == "yes")
3070             tmpStream << "#define QT_COMPILER_SUPPORTS_AVX2" << endl;
3071         if (dictionary[ "IWMMXT" ] == "yes")
3072             tmpStream << "#define QT_COMPILER_SUPPORTS_IWMMXT" << endl;
3073         if (dictionary[ "NEON" ] == "yes")
3074             tmpStream << "#define QT_COMPILER_SUPPORTS_NEON" << endl;
3075
3076
3077         tmpStream << endl << "// Compile time features" << endl;
3078
3079         QStringList qconfigList;
3080         if (dictionary["STYLE_WINDOWS"] != "yes")     qconfigList += "QT_NO_STYLE_WINDOWS";
3081         if (dictionary["STYLE_PLASTIQUE"] != "yes")   qconfigList += "QT_NO_STYLE_PLASTIQUE";
3082         if (dictionary["STYLE_CLEANLOOKS"] != "yes")   qconfigList += "QT_NO_STYLE_CLEANLOOKS";
3083         if (dictionary["STYLE_WINDOWSXP"] != "yes" && dictionary["STYLE_WINDOWSVISTA"] != "yes")
3084             qconfigList += "QT_NO_STYLE_WINDOWSXP";
3085         if (dictionary["STYLE_WINDOWSVISTA"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSVISTA";
3086         if (dictionary["STYLE_MOTIF"] != "yes")       qconfigList += "QT_NO_STYLE_MOTIF";
3087         if (dictionary["STYLE_CDE"] != "yes")         qconfigList += "QT_NO_STYLE_CDE";
3088
3089         // ### We still need the QT_NO_STYLE_S60 define for compiling Qt. Remove later!
3090         qconfigList += "QT_NO_STYLE_S60";
3091
3092         if (dictionary["STYLE_WINDOWSCE"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSCE";
3093         if (dictionary["STYLE_WINDOWSMOBILE"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSMOBILE";
3094         if (dictionary["STYLE_GTK"] != "yes")         qconfigList += "QT_NO_STYLE_GTK";
3095
3096         if (dictionary["GIF"] == "yes")              qconfigList += "QT_BUILTIN_GIF_READER=1";
3097         if (dictionary["PNG"] != "yes")              qconfigList += "QT_NO_IMAGEFORMAT_PNG";
3098         if (dictionary["JPEG"] != "yes")             qconfigList += "QT_NO_IMAGEFORMAT_JPEG";
3099         if (dictionary["ZLIB"] == "no") {
3100             qconfigList += "QT_NO_ZLIB";
3101             qconfigList += "QT_NO_COMPRESS";
3102         }
3103
3104         if (dictionary["ACCESSIBILITY"] == "no")     qconfigList += "QT_NO_ACCESSIBILITY";
3105         if (dictionary["WIDGETS"] == "no")           qconfigList += "QT_NO_WIDGETS";
3106         if (dictionary["OPENGL"] == "no")            qconfigList += "QT_NO_OPENGL";
3107         if (dictionary["OPENVG"] == "no")            qconfigList += "QT_NO_OPENVG";
3108         if (dictionary["OPENSSL"] == "no") {
3109             qconfigList += "QT_NO_OPENSSL";
3110             qconfigList += "QT_NO_SSL";
3111         }
3112         if (dictionary["OPENSSL"] == "linked")       qconfigList += "QT_LINKED_OPENSSL";
3113         if (dictionary["DBUS"] == "no")              qconfigList += "QT_NO_DBUS";
3114         if (dictionary["QML_DEBUG"] == "no")         qconfigList += "QT_QML_NO_DEBUGGER";
3115         if (dictionary["FREETYPE"] == "no")          qconfigList += "QT_NO_FREETYPE";
3116         if (dictionary["NATIVE_GESTURES"] == "no")   qconfigList += "QT_NO_NATIVE_GESTURES";
3117
3118         if (dictionary["OPENGL_ES_CM"] == "yes" ||
3119            dictionary["OPENGL_ES_2"]  == "yes")     qconfigList += "QT_OPENGL_ES";
3120
3121         if (dictionary["OPENGL_ES_CM"] == "yes")     qconfigList += "QT_OPENGL_ES_1";
3122         if (dictionary["OPENGL_ES_2"]  == "yes")     qconfigList += "QT_OPENGL_ES_2";
3123         if (dictionary["SQL_MYSQL"] == "yes")        qconfigList += "QT_SQL_MYSQL";
3124         if (dictionary["SQL_ODBC"] == "yes")         qconfigList += "QT_SQL_ODBC";
3125         if (dictionary["SQL_OCI"] == "yes")          qconfigList += "QT_SQL_OCI";
3126         if (dictionary["SQL_PSQL"] == "yes")         qconfigList += "QT_SQL_PSQL";
3127         if (dictionary["SQL_TDS"] == "yes")          qconfigList += "QT_SQL_TDS";
3128         if (dictionary["SQL_DB2"] == "yes")          qconfigList += "QT_SQL_DB2";
3129         if (dictionary["SQL_SQLITE"] == "yes")       qconfigList += "QT_SQL_SQLITE";
3130         if (dictionary["SQL_SQLITE2"] == "yes")      qconfigList += "QT_SQL_SQLITE2";
3131         if (dictionary["SQL_IBASE"] == "yes")        qconfigList += "QT_SQL_IBASE";
3132
3133         if (dictionary["POSIX_IPC"] == "yes")        qconfigList += "QT_POSIX_IPC";
3134
3135         if (dictionary["FONT_CONFIG"] == "no")       qconfigList += "QT_NO_FONTCONFIG";
3136
3137         if (dictionary["NIS"] == "yes")
3138             qconfigList += "QT_NIS";
3139         else
3140             qconfigList += "QT_NO_NIS";
3141
3142         if (dictionary["LARGE_FILE"] == "yes")       qconfigList += "QT_LARGEFILE_SUPPORT=64";
3143         if (dictionary["QT_CUPS"] == "no")           qconfigList += "QT_NO_CUPS";
3144         if (dictionary["QT_ICONV"] == "no")          qconfigList += "QT_NO_ICONV";
3145         if (dictionary["QT_GLIB"] == "no")           qconfigList += "QT_NO_GLIB";
3146         if (dictionary["QT_INOTIFY"] == "no")        qconfigList += "QT_NO_INOTIFY";
3147
3148         qconfigList.sort();
3149         for (int i = 0; i < qconfigList.count(); ++i)
3150             tmpStream << addDefine(qconfigList.at(i));
3151
3152         tmpStream<<"#define QT_QPA_DEFAULT_PLATFORM_NAME \"" << qpaPlatformName() << "\""<<endl;
3153
3154         tmpStream.flush();
3155         tmpFile.flush();
3156
3157         // Replace old qconfig.h with new one
3158         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
3159         QFile::remove(outName);
3160         tmpFile.copy(outName);
3161         tmpFile.close();
3162     }
3163
3164     QTemporaryFile tmpFile3;
3165     if (tmpFile3.open()) {
3166         tmpStream.setDevice(&tmpFile3);
3167         tmpStream << "/* Evaluation license key */" << endl
3168                   << "static const volatile char qt_eval_key_data              [512 + 12] = \"qt_qevalkey=" << licenseInfo["LICENSEKEYEXT"] << "\";" << endl;
3169
3170         tmpStream.flush();
3171         tmpFile3.flush();
3172
3173         outName = buildPath + "/src/corelib/global/qconfig_eval.cpp";
3174         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
3175         QFile::remove(outName);
3176
3177         if (dictionary["EDITION"] == "Evaluation" || qmakeDefines.contains("QT_EVAL"))
3178             tmpFile3.copy(outName);
3179         tmpFile3.close();
3180     }
3181 }
3182 #endif
3183
3184 #if !defined(EVAL)
3185 void Configure::displayConfig()
3186 {
3187     fstream sout;
3188     sout.open(QString(buildPath + "/config.summary").toLocal8Bit().constData(),
3189               ios::in | ios::out | ios::trunc);
3190
3191     // Give some feedback
3192     sout << "Environment:" << endl;
3193     QString env = QString::fromLocal8Bit(getenv("INCLUDE")).replace(QRegExp("[;,]"), "\r\n      ");
3194     if (env.isEmpty())
3195         env = "Unset";
3196     sout << "    INCLUDE=\r\n      " << env << endl;
3197     env = QString::fromLocal8Bit(getenv("LIB")).replace(QRegExp("[;,]"), "\r\n      ");
3198     if (env.isEmpty())
3199         env = "Unset";
3200     sout << "    LIB=\r\n      " << env << endl;
3201     env = QString::fromLocal8Bit(getenv("PATH")).replace(QRegExp("[;,]"), "\r\n      ");
3202     if (env.isEmpty())
3203         env = "Unset";
3204     sout << "    PATH=\r\n      " << env << endl;
3205
3206     if (dictionary[QStringLiteral("EDITION")] != QStringLiteral("OpenSource")) {
3207         QString l1 = licenseInfo[ "LICENSEE" ];
3208         QString l2 = licenseInfo[ "LICENSEID" ];
3209         QString l3 = dictionary["EDITION"] + ' ' + "Edition";
3210         QString l4 = licenseInfo[ "EXPIRYDATE" ];
3211         sout << "Licensee...................." << (l1.isNull() ? "" : l1) << endl;
3212         sout << "License ID.................." << (l2.isNull() ? "" : l2) << endl;
3213         sout << "Product license............." << (l3.isNull() ? "" : l3) << endl;
3214         sout << "Expiry Date................." << (l4.isNull() ? "" : l4) << endl << endl;
3215     }
3216
3217     sout << "Configuration:" << endl;
3218     sout << "    " << qmakeConfig.join("\r\n    ") << endl;
3219     sout << "Qt Configuration:" << endl;
3220     sout << "    " << qtConfig.join("\r\n    ") << endl;
3221     sout << endl;
3222
3223     if (dictionary.contains("XQMAKESPEC"))
3224         sout << "QMAKESPEC..................." << dictionary[ "XQMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
3225     else
3226         sout << "QMAKESPEC..................." << dictionary[ "QMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
3227     sout << "Architecture................" << dictionary["QT_ARCH"]
3228          << ", features:" << dictionary["QT_CPU_FEATURES"] << endl;
3229     sout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"]
3230          << ", features:" << dictionary["QT_HOST_CPU_FEATURES"]  << endl;
3231     sout << "Maketool...................." << dictionary[ "MAKE" ] << endl;
3232     if (dictionary[ "BUILDALL" ] == "yes") {
3233         sout << "Debug build................." << "yes (combined)" << endl;
3234         sout << "Default build..............." << dictionary[ "BUILD" ] << endl;
3235     } else {
3236         sout << "Debug......................." << (dictionary[ "BUILD" ] == "debug" ? "yes" : "no") << endl;
3237     }
3238     if (dictionary[ "BUILD" ] == "release" || dictionary[ "BUILDALL" ] == "yes")
3239         sout << "Force debug info............" << dictionary[ "FORCEDEBUGINFO" ] << endl;
3240     sout << "Link Time Code Generation..." << dictionary[ "LTCG" ] << endl;
3241     sout << "Accessibility support......." << dictionary[ "ACCESSIBILITY" ] << endl;
3242     sout << "RTTI support................" << dictionary[ "RTTI" ] << endl;
3243     sout << "SSE2 support................" << dictionary[ "SSE2" ] << endl;
3244     sout << "SSE3 support................" << dictionary[ "SSE3" ] << endl;
3245     sout << "SSSE3 support..............." << dictionary[ "SSSE3" ] << endl;
3246     sout << "SSE4.1 support.............." << dictionary[ "SSE4_1" ] << endl;
3247     sout << "SSE4.2 support.............." << dictionary[ "SSE4_2" ] << endl;
3248     sout << "AVX support................." << dictionary[ "AVX" ] << endl;
3249     sout << "AVX2 support................" << dictionary[ "AVX2" ] << endl;
3250     sout << "NEON support................" << dictionary[ "NEON" ] << endl;
3251     sout << "IWMMXT support.............." << dictionary[ "IWMMXT" ] << endl;
3252     sout << "OpenGL support.............." << dictionary[ "OPENGL" ] << endl;
3253     sout << "Large File support.........." << dictionary[ "LARGE_FILE" ] << endl;
3254     sout << "NIS support................." << dictionary[ "NIS" ] << endl;
3255     sout << "Iconv support..............." << dictionary[ "QT_ICONV" ] << endl;
3256     sout << "Glib support................" << dictionary[ "QT_GLIB" ] << endl;
3257     sout << "CUPS support................" << dictionary[ "QT_CUPS" ] << endl;
3258     if (dictionary.value(QStringLiteral("OPENGL_ES_2")) == QStringLiteral("yes")) {
3259         const QString angleDir = dictionary.value(QStringLiteral("ANGLE_DIR"));
3260         if (!angleDir.isEmpty())
3261             sout << "ANGLE......................." << QDir::toNativeSeparators(angleDir) << endl;
3262     }
3263     sout << "OpenVG support.............." << dictionary[ "OPENVG" ] << endl;
3264     sout << "OpenSSL support............." << dictionary[ "OPENSSL" ] << endl;
3265     sout << "QtDBus support.............." << dictionary[ "DBUS" ] << endl;
3266     sout << "QtWidgets module support...." << dictionary[ "WIDGETS" ] << endl;
3267     sout << "QML debugging..............." << dictionary[ "QML_DEBUG" ] << endl;
3268     sout << "DirectWrite support........." << dictionary[ "DIRECTWRITE" ] << endl << endl;
3269
3270     sout << "Third Party Libraries:" << endl;
3271     sout << "    ZLIB support............" << dictionary[ "ZLIB" ] << endl;
3272     sout << "    GIF support............." << dictionary[ "GIF" ] << endl;
3273     sout << "    JPEG support............" << dictionary[ "JPEG" ] << endl;
3274     sout << "    PNG support............." << dictionary[ "PNG" ] << endl;
3275     sout << "    FreeType support........" << dictionary[ "FREETYPE" ] << endl << endl;
3276     sout << "    PCRE support............" << dictionary[ "PCRE" ] << endl;
3277     sout << "    ICU support............." << dictionary[ "ICU" ] << endl;
3278
3279     sout << "Styles:" << endl;
3280     sout << "    Windows................." << dictionary[ "STYLE_WINDOWS" ] << endl;
3281     sout << "    Windows XP.............." << dictionary[ "STYLE_WINDOWSXP" ] << endl;
3282     sout << "    Windows Vista..........." << dictionary[ "STYLE_WINDOWSVISTA" ] << endl;
3283     sout << "    Plastique..............." << dictionary[ "STYLE_PLASTIQUE" ] << endl;
3284     sout << "    Cleanlooks.............." << dictionary[ "STYLE_CLEANLOOKS" ] << endl;
3285     sout << "    Motif..................." << dictionary[ "STYLE_MOTIF" ] << endl;
3286     sout << "    CDE....................." << dictionary[ "STYLE_CDE" ] << endl;
3287     sout << "    Windows CE.............." << dictionary[ "STYLE_WINDOWSCE" ] << endl;
3288     sout << "    Windows Mobile.........." << dictionary[ "STYLE_WINDOWSMOBILE" ] << endl << endl;
3289
3290     sout << "Sql Drivers:" << endl;
3291     sout << "    ODBC...................." << dictionary[ "SQL_ODBC" ] << endl;
3292     sout << "    MySQL..................." << dictionary[ "SQL_MYSQL" ] << endl;
3293     sout << "    OCI....................." << dictionary[ "SQL_OCI" ] << endl;
3294     sout << "    PostgreSQL.............." << dictionary[ "SQL_PSQL" ] << endl;
3295     sout << "    TDS....................." << dictionary[ "SQL_TDS" ] << endl;
3296     sout << "    DB2....................." << dictionary[ "SQL_DB2" ] << endl;
3297     sout << "    SQLite.................." << dictionary[ "SQL_SQLITE" ] << " (" << dictionary[ "SQL_SQLITE_LIB" ] << ")" << endl;
3298     sout << "    SQLite2................." << dictionary[ "SQL_SQLITE2" ] << endl;
3299     sout << "    InterBase..............." << dictionary[ "SQL_IBASE" ] << endl << endl;
3300
3301     sout << "Sources are in.............." << QDir::toNativeSeparators(dictionary["QT_SOURCE_TREE"]) << endl;
3302     sout << "Build is done in............" << QDir::toNativeSeparators(dictionary["QT_BUILD_TREE"]) << endl;
3303     sout << "Install prefix.............." << QDir::toNativeSeparators(dictionary["QT_INSTALL_PREFIX"]) << endl;
3304     sout << "Headers installed to........" << QDir::toNativeSeparators(dictionary["QT_INSTALL_HEADERS"]) << endl;
3305     sout << "Libraries installed to......" << QDir::toNativeSeparators(dictionary["QT_INSTALL_LIBS"]) << endl;
3306     sout << "Plugins installed to........" << QDir::toNativeSeparators(dictionary["QT_INSTALL_PLUGINS"]) << endl;
3307     sout << "Imports installed to........" << QDir::toNativeSeparators(dictionary["QT_INSTALL_IMPORTS"]) << endl;
3308     sout << "Binaries installed to......." << QDir::toNativeSeparators(dictionary["QT_INSTALL_BINS"]) << endl;
3309     sout << "Docs installed to..........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_DOCS"]) << endl;
3310     sout << "Data installed to..........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_DATA"]) << endl;
3311     sout << "Translations installed to..." << QDir::toNativeSeparators(dictionary["QT_INSTALL_TRANSLATIONS"]) << endl;
3312     sout << "Examples installed to......." << QDir::toNativeSeparators(dictionary["QT_INSTALL_EXAMPLES"]) << endl;
3313     sout << "Tests installed to.........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_TESTS"]) << endl;
3314
3315     if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith(QLatin1String("wince"))) {
3316         sout << "Using c runtime detection..." << dictionary[ "CE_CRT" ] << endl;
3317         sout << "Cetest support.............." << dictionary[ "CETEST" ] << endl;
3318         sout << "Signature..................." << dictionary[ "CE_SIGNATURE"] << endl << endl;
3319     }
3320
3321     if (checkAvailability("INCREDIBUILD_XGE"))
3322         sout << "Using IncrediBuild XGE......" << dictionary["INCREDIBUILD_XGE"] << endl;
3323     if (!qmakeDefines.isEmpty()) {
3324         sout << "Defines.....................";
3325         for (QStringList::Iterator defs = qmakeDefines.begin(); defs != qmakeDefines.end(); ++defs)
3326             sout << (*defs) << " ";
3327         sout << endl;
3328     }
3329     if (!qmakeIncludes.isEmpty()) {
3330         sout << "Include paths...............";
3331         for (QStringList::Iterator incs = qmakeIncludes.begin(); incs != qmakeIncludes.end(); ++incs)
3332             sout << (*incs) << " ";
3333         sout << endl;
3334     }
3335     if (!qmakeLibs.isEmpty()) {
3336         sout << "Additional libraries........";
3337         for (QStringList::Iterator libs = qmakeLibs.begin(); libs != qmakeLibs.end(); ++libs)
3338             sout << (*libs) << " ";
3339         sout << endl;
3340     }
3341     if (dictionary[ "QMAKE_INTERNAL" ] == "yes") {
3342         sout << "Using internal configuration." << endl;
3343     }
3344     if (dictionary[ "SHARED" ] == "no") {
3345         sout << "WARNING: Using static linking will disable the use of plugins." << endl;
3346         sout << "         Make sure you compile ALL needed modules into the library." << endl;
3347     }
3348     if (dictionary[ "OPENSSL" ] == "linked") {
3349         if (!opensslLibsDebug.isEmpty() || !opensslLibsRelease.isEmpty()) {
3350             sout << "Using OpenSSL libraries:" << endl;
3351             sout << "   debug  : " << opensslLibsDebug << endl;
3352             sout << "   release: " << opensslLibsRelease << endl;
3353             sout << "   both   : " << opensslLibs << endl;
3354         } else if (opensslLibs.isEmpty()) {
3355             sout << "NOTE: When linking against OpenSSL, you can override the default" << endl;
3356             sout << "library names through OPENSSL_LIBS and optionally OPENSSL_LIBS_DEBUG/OPENSSL_LIBS_RELEASE" << endl;
3357             sout << "For example:" << endl;
3358             sout << "    configure -openssl-linked OPENSSL_LIBS=\"-lssleay32 -llibeay32\"" << endl;
3359         }
3360     }
3361     if (dictionary[ "ZLIB_FORCED" ] == "yes") {
3362         QString which_zlib = "supplied";
3363         if (dictionary[ "ZLIB" ] == "system")
3364             which_zlib = "system";
3365
3366         sout << "NOTE: The -no-zlib option was supplied but is no longer supported." << endl
3367              << endl
3368              << "Qt now requires zlib support in all builds, so the -no-zlib" << endl
3369              << "option was ignored. Qt will be built using the " << which_zlib
3370              << "zlib" << endl;
3371     }
3372     if (dictionary["OBSOLETE_ARCH_ARG"] == "yes") {
3373         sout << endl
3374              << "NOTE: The -arch option is obsolete." << endl
3375              << endl
3376              << "Qt now detects the target and host architectures based on compiler" << endl
3377              << "output. Qt will be built using " << dictionary["QT_ARCH"] << " for the target architecture" << endl
3378              << "and " << dictionary["QT_HOST_ARCH"] << " for the host architecture (note that these two" << endl
3379              << "will be the same unless you are cross-compiling)." << endl
3380              << endl;
3381     }
3382
3383     // display config.summary
3384     sout.seekg(0, ios::beg);
3385     while (sout.good()) {
3386         string str;
3387         getline(sout, str);
3388         cout << str << endl;
3389     }
3390 }
3391 #endif
3392
3393 #if !defined(EVAL)
3394 void Configure::generateHeaders()
3395 {
3396     if (dictionary["SYNCQT"] == "yes") {
3397         if (findFile("perl.exe")) {
3398             cout << "Running syncqt..." << endl;
3399             QStringList args;
3400             args += buildPath + "/bin/syncqt.bat";
3401             args += sourcePath;
3402             QStringList env;
3403             env += QString("QTDIR=" + sourcePath);
3404             env += QString("PATH=" + buildPath + "/bin/;" + qgetenv("PATH"));
3405             int retc = Environment::execute(args, env, QStringList());
3406             if (retc) {
3407                 cout << "syncqt failed, return code " << retc << endl << endl;
3408                 dictionary["DONE"] = "error";
3409             }
3410         } else {
3411             cout << "Perl not found in environment - cannot run syncqt." << endl;
3412             dictionary["DONE"] = "error";
3413         }
3414     }
3415 }
3416
3417 void Configure::generateQConfigCpp()
3418 {
3419     // if QT_INSTALL_* have not been specified on commandline, define them now from QT_INSTALL_PREFIX
3420     // if prefix is empty (WINCE), make all of them empty, if they aren't set
3421     bool qipempty = false;
3422     if (dictionary["QT_INSTALL_PREFIX"].isEmpty())
3423         qipempty = true;
3424
3425     if (!dictionary["QT_INSTALL_DOCS"].size())
3426         dictionary["QT_INSTALL_DOCS"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/doc";
3427     if (!dictionary["QT_INSTALL_HEADERS"].size())
3428         dictionary["QT_INSTALL_HEADERS"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/include";
3429     if (!dictionary["QT_INSTALL_LIBS"].size())
3430         dictionary["QT_INSTALL_LIBS"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/lib";
3431     if (!dictionary["QT_INSTALL_BINS"].size())
3432         dictionary["QT_INSTALL_BINS"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/bin";
3433     if (!dictionary["QT_INSTALL_PLUGINS"].size())
3434         dictionary["QT_INSTALL_PLUGINS"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/plugins";
3435     if (!dictionary["QT_INSTALL_IMPORTS"].size())
3436         dictionary["QT_INSTALL_IMPORTS"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/imports";
3437     if (!dictionary["QT_INSTALL_DATA"].size())
3438         dictionary["QT_INSTALL_DATA"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"];
3439     if (!dictionary["QT_INSTALL_TRANSLATIONS"].size())
3440         dictionary["QT_INSTALL_TRANSLATIONS"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/translations";
3441     if (!dictionary["QT_INSTALL_EXAMPLES"].size())
3442         dictionary["QT_INSTALL_EXAMPLES"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/examples";
3443     if (!dictionary["QT_INSTALL_TESTS"].size())
3444         dictionary["QT_INSTALL_TESTS"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"] + "/tests";
3445
3446     bool haveHpx = false;
3447     if (dictionary["QT_HOST_PREFIX"].isEmpty())
3448         dictionary["QT_HOST_PREFIX"] = dictionary["QT_INSTALL_PREFIX"];
3449     else
3450         haveHpx = true;
3451     if (dictionary["QT_HOST_BINS"].isEmpty())
3452         dictionary["QT_HOST_BINS"] = haveHpx ? dictionary["QT_HOST_PREFIX"] + "/bin" : dictionary["QT_INSTALL_BINS"];
3453     if (dictionary["QT_HOST_DATA"].isEmpty())
3454         dictionary["QT_HOST_DATA"] = haveHpx ? dictionary["QT_HOST_PREFIX"] : dictionary["QT_INSTALL_DATA"];
3455
3456     // Generate the new qconfig.cpp file
3457     QDir(buildPath).mkpath("src/corelib/global");
3458     const QString outName(buildPath + "/src/corelib/global/qconfig.cpp");
3459
3460     QTemporaryFile tmpFile;
3461     if (tmpFile.open()) {
3462         QTextStream tmpStream(&tmpFile);
3463         tmpStream << "/* Licensed */" << endl
3464                   << "static const char qt_configure_licensee_str          [512 + 12] = \"qt_lcnsuser=" << licenseInfo["LICENSEE"] << "\";" << endl
3465                   << "static const char qt_configure_licensed_products_str [512 + 12] = \"qt_lcnsprod=" << dictionary["EDITION"] << "\";" << endl
3466                   << endl
3467                   << "/* Build date */" << endl
3468                   << "static const char qt_configure_installation          [11  + 12] = \"qt_instdate=" << QDate::currentDate().toString(Qt::ISODate) << "\";" << endl
3469                   << endl
3470                   << "static const char qt_configure_prefix_path_strs[][12 + 512] = {" << endl
3471                   << "    \"qt_prfxpath=" << formatPath(dictionary["QT_INSTALL_PREFIX"]) << "\"," << endl
3472                   << "    \"qt_docspath=" << formatPath(dictionary["QT_INSTALL_DOCS"]) << "\","  << endl
3473                   << "    \"qt_hdrspath=" << formatPath(dictionary["QT_INSTALL_HEADERS"]) << "\","  << endl
3474                   << "    \"qt_libspath=" << formatPath(dictionary["QT_INSTALL_LIBS"]) << "\","  << endl
3475                   << "    \"qt_binspath=" << formatPath(dictionary["QT_INSTALL_BINS"]) << "\","  << endl
3476                   << "    \"qt_plugpath=" << formatPath(dictionary["QT_INSTALL_PLUGINS"]) << "\","  << endl
3477                   << "    \"qt_impspath=" << formatPath(dictionary["QT_INSTALL_IMPORTS"]) << "\","  << endl
3478                   << "    \"qt_datapath=" << formatPath(dictionary["QT_INSTALL_DATA"]) << "\","  << endl
3479                   << "    \"qt_trnspath=" << formatPath(dictionary["QT_INSTALL_TRANSLATIONS"]) << "\"," << endl
3480                   << "    \"qt_xmplpath=" << formatPath(dictionary["QT_INSTALL_EXAMPLES"]) << "\","  << endl
3481                   << "    \"qt_tstspath=" << formatPath(dictionary["QT_INSTALL_TESTS"]) << "\","  << endl
3482                   << "#ifdef QT_BUILD_QMAKE" << endl
3483                   << "    \"qt_ssrtpath=" << formatPath(dictionary["CFG_SYSROOT"]) << "\"," << endl
3484                   << "    \"qt_hpfxpath=" << formatPath(dictionary["QT_HOST_PREFIX"]) << "\"," << endl
3485                   << "    \"qt_hbinpath=" << formatPath(dictionary["QT_HOST_BINS"]) << "\"," << endl
3486                   << "    \"qt_hdatpath=" << formatPath(dictionary["QT_HOST_DATA"]) << "\"," << endl
3487                   << "#endif" << endl
3488                   << "};" << endl;
3489
3490         if ((platform() != WINDOWS) && (platform() != WINDOWS_CE))
3491             tmpStream << "static const char qt_configure_settings_path_str [256 + 12] = \"qt_stngpath=" << formatPath(dictionary["QT_INSTALL_SETTINGS"]) << "\";" << endl;
3492
3493         tmpStream << endl
3494                   << "/* strlen( \"qt_lcnsxxxx\") == 12 */" << endl
3495                   << "#define QT_CONFIGURE_LICENSEE qt_configure_licensee_str + 12;" << endl
3496                   << "#define QT_CONFIGURE_LICENSED_PRODUCTS qt_configure_licensed_products_str + 12;" << endl;
3497
3498         if ((platform() != WINDOWS) && (platform() != WINDOWS_CE))
3499             tmpStream << "#define QT_CONFIGURE_SETTINGS_PATH qt_configure_settings_path_str + 12;" << endl;
3500
3501         tmpStream.flush();
3502         tmpFile.flush();
3503
3504         // Replace old qconfig.cpp with new one
3505         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
3506         QFile::remove(outName);
3507         tmpFile.copy(outName);
3508         tmpFile.close();
3509     }
3510 }
3511
3512 void Configure::buildQmake()
3513 {
3514     if (dictionary[ "BUILD_QMAKE" ] == "yes") {
3515         QStringList args;
3516
3517         // Build qmake
3518         QString pwd = QDir::currentPath();
3519         if (!QDir(buildPath).mkpath("qmake")) {
3520             cout << "Cannot create qmake build dir." << endl;
3521             dictionary[ "DONE" ] = "error";
3522             return;
3523         }
3524         if (!QDir::setCurrent(buildPath + "/qmake")) {
3525             cout << "Cannot enter qmake build dir." << endl;
3526             dictionary[ "DONE" ] = "error";
3527             return;
3528         }
3529
3530         QString makefile = "Makefile";
3531         {
3532             QFile out(makefile);
3533             if (out.open(QFile::WriteOnly | QFile::Text)) {
3534                 QTextStream stream(&out);
3535                 stream << "#AutoGenerated by configure.exe" << endl
3536                     << "BUILD_PATH = " << QDir::toNativeSeparators(buildPath) << endl
3537                     << "SOURCE_PATH = " << QDir::toNativeSeparators(sourcePath) << endl;
3538                 stream << "QMAKESPEC = " << dictionary["QMAKESPEC"] << endl
3539                        << "QT_VERSION = " << dictionary["VERSION"] << endl;
3540
3541                 if (dictionary["EDITION"] == "OpenSource" ||
3542                     dictionary["QT_EDITION"].contains("OPENSOURCE"))
3543                     stream << "QMAKE_OPENSOURCE_EDITION = yes" << endl;
3544                 stream << "\n\n";
3545
3546                 QFile in(sourcePath + "/qmake/" + dictionary["QMAKEMAKEFILE"]);
3547                 if (in.open(QFile::ReadOnly | QFile::Text)) {
3548                     QString d = in.readAll();
3549                     //### need replaces (like configure.sh)? --Sam
3550                     stream << d << endl;
3551                 }
3552                 stream.flush();
3553                 out.close();
3554             }
3555         }
3556
3557         args += dictionary[ "MAKE" ];
3558         args += "-f";
3559         args += makefile;
3560
3561         cout << "Creating qmake..." << endl;
3562         int exitCode = Environment::execute(args, QStringList(), QStringList());
3563         if (exitCode) {
3564             args.clear();
3565             args += dictionary[ "MAKE" ];
3566             args += "-f";
3567             args += makefile;
3568             args += "clean";
3569             exitCode = Environment::execute(args, QStringList(), QStringList());
3570             if (exitCode) {
3571                 cout << "Cleaning qmake failed, return code " << exitCode << endl << endl;
3572                 dictionary[ "DONE" ] = "error";
3573             } else {
3574                 args.clear();
3575                 args += dictionary[ "MAKE" ];
3576                 args += "-f";
3577                 args += makefile;
3578                 exitCode = Environment::execute(args, QStringList(), QStringList());
3579                 if (exitCode) {
3580                     cout << "Building qmake failed, return code " << exitCode << endl << endl;
3581                     dictionary[ "DONE" ] = "error";
3582                 }
3583             }
3584         }
3585         QDir::setCurrent(pwd);
3586     }
3587
3588     // Generate qt.conf
3589     QFile confFile(buildPath + "/bin/qt.conf");
3590     if (confFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
3591         QTextStream confStream(&confFile);
3592         confStream << "[EffectivePaths]" << endl
3593                    << "Prefix=.." << endl;
3594
3595         confStream.flush();
3596         confFile.close();
3597     }
3598
3599     //create default mkspecs
3600     QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
3601     if (!copySpec("default", "", spec)
3602         || !copySpec("default-host", "host ", dictionary["QMAKESPEC"])) {
3603         cout << "Error installing default mkspecs" << endl << endl;
3604         exit(EXIT_FAILURE);
3605     }
3606
3607 }
3608 #endif
3609
3610 void Configure::findProjects(const QString& dirName)
3611 {
3612     if (dictionary[ "PROCESS" ] != "no") {
3613         QDir dir(dirName);
3614         QString entryName;
3615         int makeListNumber;
3616         ProjectType qmakeTemplate;
3617         const QFileInfoList &list = dir.entryInfoList(QStringList(QLatin1String("*.pro")),
3618                                                       QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
3619         for (int i = 0; i < list.size(); ++i) {
3620             const QFileInfo &fi = list.at(i);
3621             if (fi.fileName() != "qmake.pro") {
3622                 entryName = dirName + "/" + fi.fileName();
3623                 if (fi.isDir()) {
3624                     findProjects(entryName);
3625                 } else {
3626                     qmakeTemplate = projectType(fi.absoluteFilePath());
3627                     switch (qmakeTemplate) {
3628                     case Lib:
3629                     case Subdirs:
3630                         makeListNumber = 1;
3631                         break;
3632                     default:
3633                         makeListNumber = 2;
3634                         break;
3635                     }
3636                     makeList[makeListNumber].append(new MakeItem(sourceDir.relativeFilePath(fi.absolutePath()),
3637                                                     fi.fileName(),
3638                                                     "Makefile",
3639                                                     qmakeTemplate));
3640                 }
3641             }
3642
3643         }
3644     }
3645 }
3646
3647 void Configure::appendMakeItem(int inList, const QString &item)
3648 {
3649     QString dir;
3650     if (item != "src")
3651         dir = "/" + item;
3652     dir.prepend("/src");
3653     makeList[inList].append(new MakeItem(sourcePath + dir,
3654         item + ".pro", buildPath + dir + "/Makefile", Lib));
3655     if (dictionary[ "VCPROJFILES" ] == "yes") {
3656         makeList[inList].append(new MakeItem(sourcePath + dir,
3657             item + ".pro", buildPath + dir + "/" + item + ".vcproj", Lib));
3658     }
3659 }
3660
3661 void Configure::generateMakefiles()
3662 {
3663     if (dictionary[ "PROCESS" ] != "no") {
3664         QString spec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
3665         if (spec != "win32-msvc.net" && !spec.startsWith("win32-msvc2") && !spec.startsWith(QLatin1String("wince")))
3666             dictionary[ "VCPROJFILES" ] = "no";
3667
3668         int i = 0;
3669         QString pwd = QDir::currentPath();
3670         if (dictionary["FAST"] != "yes") {
3671             QString dirName;
3672             bool generate = true;
3673             bool doDsp = (dictionary["VCPROJFILES"] == "yes");
3674             while (generate) {
3675                 QString pwd = QDir::currentPath();
3676                 QString dirPath = buildPath + dirName;
3677                 QStringList args;
3678
3679                 args << buildPath + "/bin/qmake";
3680
3681                 if (doDsp) {
3682                     if (dictionary[ "DEPENDENCIES" ] == "no")
3683                         args << "-nodepend";
3684                     args << "-tp" <<  "vc";
3685                     doDsp = false; // DSP files will be done
3686                     printf("Generating Visual Studio project files...\n");
3687                 } else {
3688                     printf("Generating Makefiles...\n");
3689                     generate = false; // Now Makefiles will be done
3690                 }
3691                 if (dictionary[ "PROCESS" ] == "full")
3692                     args << "-r";
3693                 args << (sourcePath + "/qtbase.pro");
3694                 args << "-o";
3695                 args << buildPath;
3696
3697                 QDir::setCurrent(dirPath);
3698                 if (int exitCode = Environment::execute(args, QStringList(), QStringList())) {
3699                     cout << "Qmake failed, return code " << exitCode  << endl << endl;
3700                     dictionary[ "DONE" ] = "error";
3701                 }
3702             }
3703         } else {
3704             findProjects(sourcePath);
3705             for (i=0; i<3; i++) {
3706                 for (int j=0; j<makeList[i].size(); ++j) {
3707                     MakeItem *it=makeList[i][j];
3708                     if (it->directory == "tools/configure")
3709                         continue; // don't overwrite our own Makefile
3710
3711                     QString dirPath = it->directory + '/';
3712                     QString projectName = it->proFile;
3713                     QString makefileName = buildPath + "/" + dirPath + it->target;
3714
3715                     // For shadowbuilds, we need to create the path first
3716                     QDir buildPathDir(buildPath);
3717                     if (sourcePath != buildPath && !buildPathDir.exists(dirPath))
3718                         buildPathDir.mkpath(dirPath);
3719
3720                     QStringList args;
3721
3722                     args << QDir::toNativeSeparators(buildPath + "/bin/qmake.exe");
3723                     args << sourcePath + "/" + dirPath + projectName;
3724
3725                     cout << "For " << qPrintable(QDir::toNativeSeparators(dirPath + projectName)) << endl;
3726                     args << "-o";
3727                     args << it->target;
3728
3729                     QDir::setCurrent(dirPath);
3730
3731                     QFile file(makefileName);
3732                     if (!file.open(QFile::WriteOnly | QFile::Text)) {
3733                         printf("failed on dirPath=%s, makefile=%s\n",
3734                                qPrintable(QDir::toNativeSeparators(dirPath)),
3735                                qPrintable(QDir::toNativeSeparators(makefileName)));
3736                         continue;
3737                     }
3738                     QTextStream txt(&file);
3739                     txt << "all:\n";
3740                     txt << "\t" << args.join(" ") << "\n";
3741                     txt << "\t$(MAKE) -$(MAKEFLAGS) -f " << it->target << "\n";
3742                     txt << "first: all\n";
3743                     txt << "qmake: FORCE\n";
3744                     txt << "\t" << args.join(" ") << "\n";
3745                     txt << "FORCE:\n";
3746                 }
3747             }
3748         }
3749         QDir::setCurrent(pwd);
3750     } else {
3751         cout << "Processing of project files have been disabled." << endl;
3752         cout << "Only use this option if you really know what you're doing." << endl << endl;
3753         return;
3754     }
3755 }
3756
3757 void Configure::showSummary()
3758 {
3759     QString make = dictionary[ "MAKE" ];
3760     cout << endl << endl << "Qt is now configured for building. Just run " << qPrintable(make) << "." << endl;
3761     cout << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl;
3762 }
3763
3764 Configure::ProjectType Configure::projectType(const QString& proFileName)
3765 {
3766     QFile proFile(proFileName);
3767     if (proFile.open(QFile::ReadOnly)) {
3768         QString buffer = proFile.readLine(1024);
3769         while (!buffer.isEmpty()) {
3770             QStringList segments = buffer.split(QRegExp("\\s"));
3771             QStringList::Iterator it = segments.begin();
3772
3773             if (segments.size() >= 3) {
3774                 QString keyword = (*it++);
3775                 QString operation = (*it++);
3776                 QString value = (*it++);
3777
3778                 if (keyword == "TEMPLATE") {
3779                     if (value == "lib")
3780                         return Lib;
3781                     else if (value == "subdirs")
3782                         return Subdirs;
3783                 }
3784             }
3785             // read next line
3786             buffer = proFile.readLine(1024);
3787         }
3788         proFile.close();
3789     }
3790     // Default to app handling
3791     return App;
3792 }
3793
3794 #if !defined(EVAL)
3795
3796 bool Configure::showLicense(QString orgLicenseFile)
3797 {
3798     if (dictionary["LICENSE_CONFIRMED"] == "yes") {
3799         cout << "You have already accepted the terms of the license." << endl << endl;
3800         return true;
3801     }
3802
3803     bool haveGpl3 = false;
3804     QString licenseFile = orgLicenseFile;
3805     QString theLicense;
3806     if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3807         haveGpl3 = QFile::exists(orgLicenseFile + "/LICENSE.GPL3");
3808         theLicense = "GNU Lesser General Public License (LGPL) version 2.1";
3809         if (haveGpl3)
3810             theLicense += "\nor the GNU General Public License (GPL) version 3";
3811     } else {
3812         // the first line of the license file tells us which license it is
3813         QFile file(licenseFile);
3814         if (!file.open(QFile::ReadOnly)) {
3815             cout << "Failed to load LICENSE file" << endl;
3816             return false;
3817         }
3818         theLicense = file.readLine().trimmed();
3819     }
3820
3821     forever {
3822         char accept = '?';
3823         cout << "You are licensed to use this software under the terms of" << endl
3824              << "the " << theLicense << "." << endl
3825              << endl;
3826         if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3827             if (haveGpl3)
3828                 cout << "Type '3' to view the GNU General Public License version 3 (GPLv3)." << endl;
3829             cout << "Type 'L' to view the Lesser GNU General Public License version 2.1 (LGPLv2.1)." << endl;
3830         } else {
3831             cout << "Type '?' to view the " << theLicense << "." << endl;
3832         }
3833         cout << "Type 'y' to accept this license offer." << endl
3834              << "Type 'n' to decline this license offer." << endl
3835              << endl
3836              << "Do you accept the terms of the license?" << endl;
3837         cin >> accept;
3838         accept = tolower(accept);
3839
3840         if (accept == 'y') {
3841             return true;
3842         } else if (accept == 'n') {
3843             return false;
3844         } else {
3845             if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3846                 if (accept == '3')
3847                     licenseFile = orgLicenseFile + "/LICENSE.GPL3";
3848                 else
3849                     licenseFile = orgLicenseFile + "/LICENSE.LGPL";
3850             }
3851             // Get console line height, to fill the screen properly
3852             int i = 0, screenHeight = 25; // default
3853             CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
3854             HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
3855             if (GetConsoleScreenBufferInfo(stdOut, &consoleInfo))
3856                 screenHeight = consoleInfo.srWindow.Bottom
3857                              - consoleInfo.srWindow.Top
3858                              - 1; // Some overlap for context
3859
3860             // Prompt the license content to the user
3861             QFile file(licenseFile);
3862             if (!file.open(QFile::ReadOnly)) {
3863                 cout << "Failed to load LICENSE file" << licenseFile << endl;
3864                 return false;
3865             }
3866             QStringList licenseContent = QString(file.readAll()).split('\n');
3867             while (i < licenseContent.size()) {
3868                 cout << licenseContent.at(i) << endl;
3869                 if (++i % screenHeight == 0) {
3870                     cout << "(Press any key for more..)";
3871                     if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
3872                         exit(0);      // Exit cleanly for Ctrl+C
3873                     cout << "\r";     // Overwrite text above
3874                 }
3875             }
3876         }
3877     }
3878 }
3879
3880 void Configure::readLicense()
3881 {
3882     dictionary["PLATFORM NAME"] = platformName();
3883     dictionary["LICENSE FILE"] = sourcePath;
3884
3885     bool openSource = false;
3886     bool hasOpenSource = QFile::exists(dictionary["LICENSE FILE"] + "/LICENSE.GPL3") || QFile::exists(dictionary["LICENSE FILE"] + "/LICENSE.LGPL");
3887     if (dictionary["BUILDTYPE"] == "commercial") {
3888         openSource = false;
3889     } else if (dictionary["BUILDTYPE"] == "opensource") {
3890         openSource = true;
3891     } else if (hasOpenSource) { // No Open Source? Just display the commercial license right away
3892         forever {
3893             char accept = '?';
3894             cout << "Which edition of Qt do you want to use ?" << endl;
3895             cout << "Type 'c' if you want to use the Commercial Edition." << endl;
3896             cout << "Type 'o' if you want to use the Open Source Edition." << endl;
3897             cin >> accept;
3898             accept = tolower(accept);
3899
3900             if (accept == 'c') {
3901                 openSource = false;
3902                 break;
3903             } else if (accept == 'o') {
3904                 openSource = true;
3905                 break;
3906             }
3907         }
3908     }
3909     if (hasOpenSource && openSource) {
3910         cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " Open Source Edition." << endl;
3911         licenseInfo["LICENSEE"] = "Open Source";
3912         dictionary["EDITION"] = "OpenSource";
3913         dictionary["QT_EDITION"] = "QT_EDITION_OPENSOURCE";
3914         cout << endl;
3915         if (!showLicense(dictionary["LICENSE FILE"])) {
3916             cout << "Configuration aborted since license was not accepted";
3917             dictionary["DONE"] = "error";
3918             return;
3919         }
3920     } else if (openSource) {
3921         cout << endl << "Cannot find the GPL license files! Please download the Open Source version of the library." << endl;
3922         dictionary["DONE"] = "error";
3923     }
3924 #ifdef COMMERCIAL_VERSION
3925     else {
3926         Tools::checkLicense(dictionary, licenseInfo, firstLicensePath());
3927         if (dictionary["DONE"] != "error") {
3928             // give the user some feedback, and prompt for license acceptance
3929             cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl;
3930             if (!showLicense(dictionary["LICENSE FILE"])) {
3931                 cout << "Configuration aborted since license was not accepted";
3932                 dictionary["DONE"] = "error";
3933                 return;
3934             }
3935         }
3936     }
3937 #else // !COMMERCIAL_VERSION
3938     else {
3939         cout << endl << "Cannot build commercial edition from the open source version of the library." << endl;
3940         dictionary["DONE"] = "error";
3941     }
3942 #endif
3943 }
3944
3945 void Configure::reloadCmdLine()
3946 {
3947     if (dictionary[ "REDO" ] == "yes") {
3948         QFile inFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
3949         if (inFile.open(QFile::ReadOnly)) {
3950             QTextStream inStream(&inFile);
3951             QString buffer;
3952             inStream >> buffer;
3953             while (buffer.length()) {
3954                 configCmdLine += buffer;
3955                 inStream >> buffer;
3956             }
3957             inFile.close();
3958         }
3959     }
3960 }
3961
3962 void Configure::saveCmdLine()
3963 {
3964     if (dictionary[ "REDO" ] != "yes") {
3965         QFile outFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
3966         if (outFile.open(QFile::WriteOnly | QFile::Text)) {
3967             QTextStream outStream(&outFile);
3968             for (QStringList::Iterator it = configCmdLine.begin(); it != configCmdLine.end(); ++it) {
3969                 outStream << (*it) << " " << endl;
3970             }
3971             outStream.flush();
3972             outFile.close();
3973         }
3974     }
3975 }
3976 #endif // !EVAL
3977
3978 bool Configure::isDone()
3979 {
3980     return !dictionary["DONE"].isEmpty();
3981 }
3982
3983 bool Configure::isOk()
3984 {
3985     return (dictionary[ "DONE" ] != "error");
3986 }
3987
3988 QString Configure::platformName() const
3989 {
3990     switch (platform()) {
3991     default:
3992     case WINDOWS:
3993         return QStringLiteral("Qt for Windows");
3994     case WINDOWS_CE:
3995         return QStringLiteral("Qt for Windows CE");
3996     case QNX:
3997         return QStringLiteral("Qt for QNX");
3998     case BLACKBERRY:
3999         return QStringLiteral("Qt for Blackberry");
4000     }
4001 }
4002
4003 QString Configure::qpaPlatformName() const
4004 {
4005     switch (platform()) {
4006     default:
4007     case WINDOWS:
4008     case WINDOWS_CE:
4009         return QStringLiteral("windows");
4010     case QNX:
4011         return QStringLiteral("qnx");
4012     case BLACKBERRY:
4013         return QStringLiteral("blackberry");
4014     }
4015 }
4016
4017 int Configure::platform() const
4018 {
4019     const QString qMakeSpec = dictionary.value("QMAKESPEC");
4020     const QString xQMakeSpec = dictionary.value("XQMAKESPEC");
4021
4022     if ((qMakeSpec.startsWith("wince") || xQMakeSpec.startsWith("wince")))
4023         return WINDOWS_CE;
4024
4025     if (xQMakeSpec.contains("qnx"))
4026         return QNX;
4027
4028     if (xQMakeSpec.contains("blackberry"))
4029         return BLACKBERRY;
4030
4031     return WINDOWS;
4032 }
4033
4034 bool
4035 Configure::filesDiffer(const QString &fn1, const QString &fn2)
4036 {
4037     QFile file1(fn1), file2(fn2);
4038     if (!file1.open(QFile::ReadOnly) || !file2.open(QFile::ReadOnly))
4039         return true;
4040     const int chunk = 2048;
4041     int used1 = 0, used2 = 0;
4042     char b1[chunk], b2[chunk];
4043     while (!file1.atEnd() && !file2.atEnd()) {
4044         if (!used1)
4045             used1 = file1.read(b1, chunk);
4046         if (!used2)
4047             used2 = file2.read(b2, chunk);
4048         if (used1 > 0 && used2 > 0) {
4049             const int cmp = qMin(used1, used2);
4050             if (memcmp(b1, b2, cmp))
4051                 return true;
4052             if ((used1 -= cmp))
4053                 memcpy(b1, b1+cmp, used1);
4054             if ((used2 -= cmp))
4055                 memcpy(b2, b2+cmp, used2);
4056         }
4057     }
4058     return !file1.atEnd() || !file2.atEnd();
4059 }
4060
4061 QT_END_NAMESPACE