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