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