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