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