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