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