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