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