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