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