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