Record the sub-architecture (CPU features enabled in the compiler)
[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 struct ArchData {
2535     const char *qmakespec;
2536     const char *key;
2537     const char *subarchKey;
2538     const char *type;
2539     ArchData() {}
2540     ArchData(const char *t, const char *qm, const char *k, const char *sak)
2541         : qmakespec(qm), key(k), subarchKey(sak), type(t)
2542     {}
2543 };
2544
2545 /*
2546     Runs qmake on config.tests/arch/arch.pro, which will detect the target arch
2547     for the compiler we are using
2548 */
2549 void Configure::detectArch()
2550 {
2551     QString oldpwd = QDir::currentPath();
2552
2553     QString newpwd = fixSeparators(QString("%1/config.tests/arch").arg(buildPath));
2554     if (!QDir().exists(newpwd) && !QDir().mkpath(newpwd)) {
2555         cout << "Failed to create directory " << qPrintable(newpwd) << endl;
2556         dictionary["DONE"] = "error";
2557         return;
2558     }
2559     if (!QDir::setCurrent(newpwd)) {
2560         cout << "Failed to change working directory to " << qPrintable(newpwd) << endl;
2561         dictionary["DONE"] = "error";
2562         return;
2563     }
2564
2565     QVector<ArchData> qmakespecs;
2566     if (dictionary.contains("XQMAKESPEC"))
2567         qmakespecs << ArchData("target", "XQMAKESPEC", "QT_ARCH", "QT_CPU_FEATURES");
2568     qmakespecs << ArchData("host", "QMAKESPEC", "QT_HOST_ARCH", "QT_HOST_CPU_FEATURES");
2569
2570     for (int i = 0; i < qmakespecs.count(); ++i) {
2571         const ArchData &data = qmakespecs.at(i);
2572         QString qmakespec = dictionary.value(data.qmakespec);
2573         QString key = data.key;
2574         QString subarchKey = data.subarchKey;
2575
2576         // run qmake
2577         QString command =
2578                 fixSeparators(QString("%1/bin/qmake.exe -spec %2 %3/config.tests/arch/arch.pro 2>&1")
2579                               .arg(buildPath, qmakespec, sourcePath));
2580         Environment::execute(command);
2581
2582         // compile
2583         command = dictionary[ "MAKE" ];
2584         if (command.contains("nmake"))
2585             command += " /NOLOGO";
2586         command += " -s";
2587         Environment::execute(command);
2588
2589         // find the executable that was generated
2590         QFile exe("arch.exe");
2591         if (!exe.open(QFile::ReadOnly)) { // no Text, this is binary
2592             cout << "Could not find output file: " << qPrintable(exe.errorString()) << endl;
2593             dictionary["DONE"] = "error";
2594             return;
2595         }
2596         QByteArray exeContents = exe.readAll();
2597         exe.close();
2598
2599         static const char archMagic[] = "==Qt=magic=Qt== Architecture:";
2600         int magicPos = exeContents.indexOf(archMagic);
2601         if (magicPos == -1) {
2602             cout << "Internal error, could not find the architecture of the "
2603                  << data.type << " executable" << endl;
2604             dictionary["DONE"] = "error";
2605             return;
2606         }
2607         //cout << "Found magic at offset 0x" << hex << magicPos << endl;
2608
2609         // the conversion from QByteArray will stop at the ending NUL anyway
2610         QString arch = QString::fromLatin1(exeContents.constData() + magicPos
2611                                            + sizeof(archMagic) - 1);
2612         dictionary[key] = arch;
2613
2614         static const char subarchMagic[] = "==Qt=magic=Qt== Sub-architecture:";
2615         magicPos = exeContents.indexOf(subarchMagic);
2616         if (magicPos == -1) {
2617             cout << "Internal error, could not find the sub-architecture of the "
2618                  << data.type << " executable" << endl;
2619             dictionary["DONE"] = "error";
2620             return;
2621         }
2622
2623         QString subarch = QString::fromLatin1(exeContents.constData() + magicPos
2624                                               + sizeof(subarchMagic) - 1);
2625         dictionary[subarchKey] = subarch;
2626
2627         //cout << "Detected arch '" << qPrintable(arch) << "'\n";
2628         //cout << "Detected sub-arch '" << qPrintable(subarch) << "'\n";
2629
2630         // clean up
2631         Environment::execute(command + " distclean");
2632     }
2633
2634     if (!dictionary.contains("QT_HOST_ARCH"))
2635         dictionary["QT_HOST_ARCH"] = "unknown";
2636     if (!dictionary.contains("QT_ARCH")) {
2637         dictionary["QT_ARCH"] = dictionary["QT_HOST_ARCH"];
2638         dictionary["QT_CPU_FEATURES"] = dictionary["QT_HOST_CPU_FEATURES"];
2639     }
2640
2641     QDir::setCurrent(oldpwd);
2642 }
2643
2644 void Configure::generateQConfigPri()
2645 {
2646     // Generate qconfig.pri
2647     QFile configFile(dictionary[ "QT_BUILD_TREE" ] + "/mkspecs/qconfig.pri");
2648     if (configFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
2649         QTextStream configStream(&configFile);
2650
2651         configStream << "CONFIG+= ";
2652         configStream << dictionary[ "BUILD" ];
2653         if (dictionary[ "SHARED" ] == "yes")
2654             configStream << " shared";
2655         else
2656             configStream << " static";
2657
2658         if (dictionary[ "LTCG" ] == "yes")
2659             configStream << " ltcg";
2660         if (dictionary[ "RTTI" ] == "yes")
2661             configStream << " rtti";
2662         if (dictionary[ "SSE2" ] == "yes")
2663             configStream << " sse2";
2664         if (dictionary[ "IWMMXT" ] == "yes")
2665             configStream << " iwmmxt";
2666         if (dictionary["INCREDIBUILD_XGE"] == "yes")
2667             configStream << " incredibuild_xge";
2668         if (dictionary["PLUGIN_MANIFESTS"] == "no")
2669             configStream << " no_plugin_manifest";
2670         if (dictionary["CROSS_COMPILE"] == "yes")
2671             configStream << " cross_compile";
2672
2673         if (dictionary["DIRECTWRITE"] == "yes")
2674             configStream << "directwrite";
2675
2676         // ### For compatibility only, should be removed later.
2677         configStream << " qpa";
2678
2679         configStream << endl;
2680         configStream << "QT_ARCH = " << dictionary["QT_ARCH"] << endl;
2681         configStream << "QT_HOST_ARCH = " << dictionary["QT_HOST_ARCH"] << endl;
2682         configStream << "QT_CPU_FEATURES = " << dictionary["QT_CPU_FEATURES"] << endl;
2683         configStream << "QT_HOST_CPU_FEATURES = " << dictionary["QT_HOST_CPU_FEATURES"] << endl;
2684         if (dictionary["QT_EDITION"].contains("OPENSOURCE"))
2685             configStream << "QT_EDITION = " << QLatin1String("OpenSource") << endl;
2686         else
2687             configStream << "QT_EDITION = " << dictionary["EDITION"] << endl;
2688         configStream << "QT_CONFIG += " << qtConfig.join(" ") << endl;
2689
2690         configStream << "#versioning " << endl
2691                      << "QT_VERSION = " << dictionary["VERSION"] << endl
2692                      << "QT_MAJOR_VERSION = " << dictionary["VERSION_MAJOR"] << endl
2693                      << "QT_MINOR_VERSION = " << dictionary["VERSION_MINOR"] << endl
2694                      << "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl;
2695
2696         if (!dictionary["CFG_SYSROOT"].isEmpty()) {
2697             QString targetSpec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
2698             configStream << endl
2699                          << "# sysroot" << endl
2700                          << targetSpec << " {" << endl
2701                          << "    QMAKE_CFLAGS    += --sysroot=$$[QT_SYSROOT]" << endl
2702                          << "    QMAKE_CXXFLAGS  += --sysroot=$$[QT_SYSROOT]" << endl
2703                          << "    QMAKE_LFLAGS    += --sysroot=$$[QT_SYSROOT]" << endl
2704                          << "}" << endl;
2705         }
2706
2707         if (!dictionary["QMAKE_RPATHDIR"].isEmpty())
2708             configStream << "QMAKE_RPATHDIR += " << dictionary["QMAKE_RPATHDIR"] << endl;
2709
2710         if (!dictionary["QT_LIBINFIX"].isEmpty())
2711             configStream << "QT_LIBINFIX = " << dictionary["QT_LIBINFIX"] << endl;
2712
2713         if (!dictionary["QT_NAMESPACE"].isEmpty())
2714             configStream << "#namespaces" << endl << "QT_NAMESPACE = " << dictionary["QT_NAMESPACE"] << endl;
2715
2716         configStream.flush();
2717         configFile.close();
2718     }
2719 }
2720 #endif
2721
2722 QString Configure::addDefine(QString def)
2723 {
2724     QString result, defNeg, defD = def;
2725
2726     defD.replace(QRegExp("=.*"), "");
2727     def.replace(QRegExp("="), " ");
2728
2729     if (def.startsWith("QT_NO_")) {
2730         defNeg = defD;
2731         defNeg.replace("QT_NO_", "QT_");
2732     } else if (def.startsWith("QT_")) {
2733         defNeg = defD;
2734         defNeg.replace("QT_", "QT_NO_");
2735     }
2736
2737     if (defNeg.isEmpty()) {
2738         result = "#ifndef $DEFD\n"
2739                  "# define $DEF\n"
2740                  "#endif\n\n";
2741     } else {
2742         result = "#if defined($DEFD) && defined($DEFNEG)\n"
2743                  "# undef $DEFD\n"
2744                  "#elif !defined($DEFD)\n"
2745                  "# define $DEF\n"
2746                  "#endif\n\n";
2747     }
2748     result.replace("$DEFNEG", defNeg);
2749     result.replace("$DEFD", defD);
2750     result.replace("$DEF", def);
2751     return result;
2752 }
2753
2754 #if !defined(EVAL)
2755 bool Configure::copySpec(const char *name, const char *pfx, const QString &spec)
2756 {
2757     // Copy configured mkspec to default directory, but remove the old one first, if there is any
2758     QString defSpec = buildPath + "/mkspecs/" + name;
2759     QFileInfo defSpecInfo(defSpec);
2760     if (defSpecInfo.exists()) {
2761         if (!Environment::rmdir(defSpec)) {
2762             cout << "Couldn't update default " << pfx << "mkspec! Are files in " << qPrintable(defSpec) << " read-only?" << endl;
2763             dictionary["DONE"] = "error";
2764             return false;
2765         }
2766     }
2767
2768     QString pltSpec = sourcePath + "/mkspecs/" + spec;
2769     QString includeSpec = buildPath + "/mkspecs/" + spec;
2770     if (!Environment::cpdir(pltSpec, defSpec, includeSpec)) {
2771         cout << "Couldn't update default " << pfx << "mkspec! Does " << qPrintable(pltSpec) << " exist?" << endl;
2772         dictionary["DONE"] = "error";
2773         return false;
2774     }
2775     return true;
2776 }
2777
2778 void Configure::generateConfigfiles()
2779 {
2780     QDir(buildPath).mkpath("src/corelib/global");
2781     QString outName(buildPath + "/src/corelib/global/qconfig.h");
2782     QTemporaryFile tmpFile;
2783     QTextStream tmpStream;
2784
2785     if (tmpFile.open()) {
2786         tmpStream.setDevice(&tmpFile);
2787
2788         if (dictionary[ "QCONFIG" ] == "full") {
2789             tmpStream << "/* Everything */" << endl;
2790         } else {
2791             QString configName("qconfig-" + dictionary[ "QCONFIG" ] + ".h");
2792             tmpStream << "/* Copied from " << configName << "*/" << endl;
2793             tmpStream << "#ifndef QT_BOOTSTRAPPED" << endl;
2794             QFile inFile(sourcePath + "/src/corelib/global/" + configName);
2795             if (inFile.open(QFile::ReadOnly)) {
2796                 QByteArray buffer = inFile.readAll();
2797                 tmpFile.write(buffer.constData(), buffer.size());
2798                 inFile.close();
2799             }
2800             tmpStream << "#endif // QT_BOOTSTRAPPED" << endl;
2801         }
2802         tmpStream << endl;
2803
2804         if (dictionary[ "SHARED" ] == "yes") {
2805             tmpStream << "#ifndef QT_DLL" << endl;
2806             tmpStream << "#define QT_DLL" << endl;
2807             tmpStream << "#endif" << endl;
2808         }
2809         tmpStream << endl;
2810         tmpStream << "/* License information */" << endl;
2811         tmpStream << "#define QT_PRODUCT_LICENSEE \"" << licenseInfo[ "LICENSEE" ] << "\"" << endl;
2812         tmpStream << "#define QT_PRODUCT_LICENSE \"" << dictionary[ "EDITION" ] << "\"" << endl;
2813         tmpStream << endl;
2814         tmpStream << "// Qt Edition" << endl;
2815         tmpStream << "#ifndef QT_EDITION" << endl;
2816         tmpStream << "#  define QT_EDITION " << dictionary["QT_EDITION"] << endl;
2817         tmpStream << "#endif" << endl;
2818         tmpStream << endl;
2819         if (dictionary["BUILDDEV"] == "yes") {
2820             dictionary["QMAKE_INTERNAL"] = "yes";
2821             tmpStream << "/* Used for example to export symbols for the certain autotests*/" << endl;
2822             tmpStream << "#define QT_BUILD_INTERNAL" << endl;
2823             tmpStream << endl;
2824         }
2825
2826         // ### For compatibility only, should be removed later.
2827         tmpStream << endl << "#define Q_WS_QPA" << endl;
2828
2829         tmpStream << endl << "// Compile time features" << endl;
2830
2831         QStringList qconfigList;
2832         if (dictionary["STYLE_WINDOWS"] != "yes")     qconfigList += "QT_NO_STYLE_WINDOWS";
2833         if (dictionary["STYLE_PLASTIQUE"] != "yes")   qconfigList += "QT_NO_STYLE_PLASTIQUE";
2834         if (dictionary["STYLE_CLEANLOOKS"] != "yes")   qconfigList += "QT_NO_STYLE_CLEANLOOKS";
2835         if (dictionary["STYLE_WINDOWSXP"] != "yes" && dictionary["STYLE_WINDOWSVISTA"] != "yes")
2836             qconfigList += "QT_NO_STYLE_WINDOWSXP";
2837         if (dictionary["STYLE_WINDOWSVISTA"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSVISTA";
2838         if (dictionary["STYLE_MOTIF"] != "yes")       qconfigList += "QT_NO_STYLE_MOTIF";
2839         if (dictionary["STYLE_CDE"] != "yes")         qconfigList += "QT_NO_STYLE_CDE";
2840
2841         // ### We still need the QT_NO_STYLE_S60 define for compiling Qt. Remove later!
2842         qconfigList += "QT_NO_STYLE_S60";
2843
2844         if (dictionary["STYLE_WINDOWSCE"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSCE";
2845         if (dictionary["STYLE_WINDOWSMOBILE"] != "yes")   qconfigList += "QT_NO_STYLE_WINDOWSMOBILE";
2846         if (dictionary["STYLE_GTK"] != "yes")         qconfigList += "QT_NO_STYLE_GTK";
2847
2848         if (dictionary["GIF"] == "yes")              qconfigList += "QT_BUILTIN_GIF_READER=1";
2849         if (dictionary["PNG"] != "yes")              qconfigList += "QT_NO_IMAGEFORMAT_PNG";
2850         if (dictionary["JPEG"] != "yes")             qconfigList += "QT_NO_IMAGEFORMAT_JPEG";
2851         if (dictionary["ZLIB"] == "no") {
2852             qconfigList += "QT_NO_ZLIB";
2853             qconfigList += "QT_NO_COMPRESS";
2854         }
2855
2856         if (dictionary["ACCESSIBILITY"] == "no")     qconfigList += "QT_NO_ACCESSIBILITY";
2857         if (dictionary["WIDGETS"] == "no")           qconfigList += "QT_NO_WIDGETS";
2858         if (dictionary["OPENGL"] == "no")            qconfigList += "QT_NO_OPENGL";
2859         if (dictionary["OPENVG"] == "no")            qconfigList += "QT_NO_OPENVG";
2860         if (dictionary["OPENSSL"] == "no") {
2861             qconfigList += "QT_NO_OPENSSL";
2862             qconfigList += "QT_NO_SSL";
2863         }
2864         if (dictionary["OPENSSL"] == "linked")       qconfigList += "QT_LINKED_OPENSSL";
2865         if (dictionary["DBUS"] == "no")              qconfigList += "QT_NO_DBUS";
2866         if (dictionary["QML_DEBUG"] == "no")         qconfigList += "QT_QML_NO_DEBUGGER";
2867         if (dictionary["FREETYPE"] == "no")          qconfigList += "QT_NO_FREETYPE";
2868         if (dictionary["NATIVE_GESTURES"] == "no")   qconfigList += "QT_NO_NATIVE_GESTURES";
2869
2870         if (dictionary["OPENGL_ES_CM"] == "yes" ||
2871            dictionary["OPENGL_ES_2"]  == "yes")     qconfigList += "QT_OPENGL_ES";
2872
2873         if (dictionary["OPENGL_ES_CM"] == "yes")     qconfigList += "QT_OPENGL_ES_1";
2874         if (dictionary["OPENGL_ES_2"]  == "yes")     qconfigList += "QT_OPENGL_ES_2";
2875         if (dictionary["SQL_MYSQL"] == "yes")        qconfigList += "QT_SQL_MYSQL";
2876         if (dictionary["SQL_ODBC"] == "yes")         qconfigList += "QT_SQL_ODBC";
2877         if (dictionary["SQL_OCI"] == "yes")          qconfigList += "QT_SQL_OCI";
2878         if (dictionary["SQL_PSQL"] == "yes")         qconfigList += "QT_SQL_PSQL";
2879         if (dictionary["SQL_TDS"] == "yes")          qconfigList += "QT_SQL_TDS";
2880         if (dictionary["SQL_DB2"] == "yes")          qconfigList += "QT_SQL_DB2";
2881         if (dictionary["SQL_SQLITE"] == "yes")       qconfigList += "QT_SQL_SQLITE";
2882         if (dictionary["SQL_SQLITE2"] == "yes")      qconfigList += "QT_SQL_SQLITE2";
2883         if (dictionary["SQL_IBASE"] == "yes")        qconfigList += "QT_SQL_IBASE";
2884
2885         qconfigList.sort();
2886         for (int i = 0; i < qconfigList.count(); ++i)
2887             tmpStream << addDefine(qconfigList.at(i));
2888
2889         if (dictionary["EMBEDDED"] == "yes")
2890         {
2891             // Check for keyboard, mouse, gfx.
2892             QStringList kbdDrivers = dictionary["KBD_DRIVERS"].split(" ");;
2893             QStringList allKbdDrivers;
2894             allKbdDrivers<<"tty"<<"usb"<<"sl5000"<<"yopy"<<"vr41xx"<<"qvfb"<<"um";
2895             foreach (const QString &kbd, allKbdDrivers) {
2896                 if (!kbdDrivers.contains(kbd))
2897                     tmpStream<<"#define QT_NO_QWS_KBD_"<<kbd.toUpper()<<endl;
2898             }
2899
2900             QStringList mouseDrivers = dictionary["MOUSE_DRIVERS"].split(" ");
2901             QStringList allMouseDrivers;
2902             allMouseDrivers << "pc"<<"bus"<<"linuxtp"<<"yopy"<<"vr41xx"<<"tslib"<<"qvfb";
2903             foreach (const QString &mouse, allMouseDrivers) {
2904                 if (!mouseDrivers.contains(mouse))
2905                     tmpStream<<"#define QT_NO_QWS_MOUSE_"<<mouse.toUpper()<<endl;
2906             }
2907
2908             QStringList gfxDrivers = dictionary["GFX_DRIVERS"].split(" ");
2909             QStringList allGfxDrivers;
2910             allGfxDrivers<<"linuxfb"<<"transformed"<<"qvfb"<<"multiscreen"<<"ahi";
2911             foreach (const QString &gfx, allGfxDrivers) {
2912                 if (!gfxDrivers.contains(gfx))
2913                     tmpStream<<"#define QT_NO_QWS_"<<gfx.toUpper()<<endl;
2914             }
2915
2916             tmpStream<<"#define Q_WS_QWS"<<endl;
2917
2918             QStringList depths = dictionary[ "QT_QWS_DEPTH" ].split(" ");
2919             foreach (const QString &depth, depths)
2920               tmpStream<<"#define QT_QWS_DEPTH_"+depth<<endl;
2921         }
2922
2923         if (dictionary[ "QT_CUPS" ] == "no")
2924           tmpStream<<"#define QT_NO_CUPS"<<endl;
2925
2926         if (dictionary[ "QT_ICONV" ]  == "no")
2927           tmpStream<<"#define QT_NO_ICONV"<<endl;
2928
2929         if (dictionary[ "QT_GLIB" ] == "no")
2930           tmpStream<<"#define QT_NO_GLIB"<<endl;
2931
2932         if (dictionary[ "QT_LPR" ] == "no")
2933           tmpStream<<"#define QT_NO_LPR"<<endl;
2934
2935         if (dictionary[ "QT_INOTIFY" ] == "no")
2936           tmpStream<<"#define QT_NO_INOTIFY"<<endl;
2937
2938         if (dictionary[ "QT_SXE" ] == "no")
2939           tmpStream<<"#define QT_NO_SXE"<<endl;
2940
2941         tmpStream<<"#define QT_QPA_DEFAULT_PLATFORM_NAME \"windows\""<<endl;
2942
2943         tmpStream.flush();
2944         tmpFile.flush();
2945
2946         // Replace old qconfig.h with new one
2947         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
2948         QFile::remove(outName);
2949         tmpFile.copy(outName);
2950         tmpFile.close();
2951     }
2952
2953     QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
2954     if (!copySpec("default", "", spec))
2955         return;
2956
2957     // Generate the new qconfig.cpp file
2958     QDir(buildPath).mkpath("src/corelib/global");
2959     outName = buildPath + "/src/corelib/global/qconfig.cpp";
2960
2961     QTemporaryFile tmpFile2;
2962     if (tmpFile2.open()) {
2963         tmpStream.setDevice(&tmpFile2);
2964         tmpStream << "/* Licensed */" << endl
2965                   << "static const char qt_configure_licensee_str          [512 + 12] = \"qt_lcnsuser=" << licenseInfo["LICENSEE"] << "\";" << endl
2966                   << "static const char qt_configure_licensed_products_str [512 + 12] = \"qt_lcnsprod=" << dictionary["EDITION"] << "\";" << endl
2967                   << endl
2968                   << "/* Build date */" << endl
2969                   << "static const char qt_configure_installation          [11  + 12] = \"qt_instdate=" << QDate::currentDate().toString(Qt::ISODate) << "\";" << endl
2970                   << endl
2971                   << "static const char qt_configure_prefix_path_strs[][12 + 512] = {" << endl
2972                   << "    \"qt_prfxpath=" << escapeSeparators(dictionary["QT_INSTALL_PREFIX"]) << "\"," << endl
2973                   << "    \"qt_docspath=" << escapeSeparators(dictionary["QT_INSTALL_DOCS"]) << "\","  << endl
2974                   << "    \"qt_hdrspath=" << escapeSeparators(dictionary["QT_INSTALL_HEADERS"]) << "\","  << endl
2975                   << "    \"qt_libspath=" << escapeSeparators(dictionary["QT_INSTALL_LIBS"]) << "\","  << endl
2976                   << "    \"qt_binspath=" << escapeSeparators(dictionary["QT_INSTALL_BINS"]) << "\","  << endl
2977                   << "    \"qt_plugpath=" << escapeSeparators(dictionary["QT_INSTALL_PLUGINS"]) << "\","  << endl
2978                   << "    \"qt_impspath=" << escapeSeparators(dictionary["QT_INSTALL_IMPORTS"]) << "\","  << endl
2979                   << "    \"qt_datapath=" << escapeSeparators(dictionary["QT_INSTALL_DATA"]) << "\","  << endl
2980                   << "    \"qt_trnspath=" << escapeSeparators(dictionary["QT_INSTALL_TRANSLATIONS"]) << "\"," << endl
2981                   << "    \"qt_xmplpath=" << escapeSeparators(dictionary["QT_INSTALL_EXAMPLES"]) << "\","  << endl
2982                   << "    \"qt_tstspath=" << escapeSeparators(dictionary["QT_INSTALL_TESTS"]) << "\","  << endl
2983                   << "#ifdef QT_BUILD_QMAKE" << endl
2984                   << "    \"qt_ssrtpath=" << escapeSeparators(dictionary["CFG_SYSROOT"]) << "\"," << endl
2985                   << "    \"qt_hpfxpath=" << escapeSeparators(dictionary["QT_HOST_PREFIX"]) << "\"," << endl
2986                   << "    \"qt_hbinpath=" << escapeSeparators(dictionary["QT_HOST_BINS"]) << "\"," << endl
2987                   << "    \"qt_hdatpath=" << escapeSeparators(dictionary["QT_HOST_DATA"]) << "\"," << endl
2988                   << "#endif" << endl
2989                   << "};" << endl
2990                   //<< "static const char qt_configure_settings_path_str [256] = \"qt_stngpath=" << escapeSeparators(dictionary["QT_INSTALL_SETTINGS"]) << "\";" << endl
2991                   << endl
2992                   << "/* strlen( \"qt_lcnsxxxx\") == 12 */" << endl
2993                   << "#define QT_CONFIGURE_LICENSEE qt_configure_licensee_str + 12;" << endl
2994                   << "#define QT_CONFIGURE_LICENSED_PRODUCTS qt_configure_licensed_products_str + 12;" << endl
2995                   //<< "#define QT_CONFIGURE_SETTINGS_PATH qt_configure_settings_path_str + 12;" << endl
2996                   << endl;
2997
2998         tmpStream.flush();
2999         tmpFile2.flush();
3000
3001         // Replace old qconfig.cpp with new one
3002         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
3003         QFile::remove(outName);
3004         tmpFile2.copy(outName);
3005         tmpFile2.close();
3006     }
3007
3008     QTemporaryFile tmpFile3;
3009     if (tmpFile3.open()) {
3010         tmpStream.setDevice(&tmpFile3);
3011         tmpStream << "/* Evaluation license key */" << endl
3012                   << "static const volatile char qt_eval_key_data              [512 + 12] = \"qt_qevalkey=" << licenseInfo["LICENSEKEYEXT"] << "\";" << endl;
3013
3014         tmpStream.flush();
3015         tmpFile3.flush();
3016
3017         outName = buildPath + "/src/corelib/global/qconfig_eval.cpp";
3018         ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
3019         QFile::remove(outName);
3020
3021         if (dictionary["EDITION"] == "Evaluation" || qmakeDefines.contains("QT_EVAL"))
3022             tmpFile3.copy(outName);
3023         tmpFile3.close();
3024     }
3025 }
3026 #endif
3027
3028 #if !defined(EVAL)
3029 void Configure::displayConfig()
3030 {
3031     fstream sout;
3032     sout.open(QString(buildPath + "/config.summary").toLocal8Bit().constData(),
3033               ios::in | ios::out | ios::trunc);
3034
3035     // Give some feedback
3036     sout << "Environment:" << endl;
3037     QString env = QString::fromLocal8Bit(getenv("INCLUDE")).replace(QRegExp("[;,]"), "\r\n      ");
3038     if (env.isEmpty())
3039         env = "Unset";
3040     sout << "    INCLUDE=\r\n      " << env << endl;
3041     env = QString::fromLocal8Bit(getenv("LIB")).replace(QRegExp("[;,]"), "\r\n      ");
3042     if (env.isEmpty())
3043         env = "Unset";
3044     sout << "    LIB=\r\n      " << env << endl;
3045     env = QString::fromLocal8Bit(getenv("PATH")).replace(QRegExp("[;,]"), "\r\n      ");
3046     if (env.isEmpty())
3047         env = "Unset";
3048     sout << "    PATH=\r\n      " << env << endl;
3049
3050     if (dictionary[QStringLiteral("EDITION")] != QStringLiteral("OpenSource")) {
3051         QString l1 = licenseInfo[ "LICENSEE" ];
3052         QString l2 = licenseInfo[ "LICENSEID" ];
3053         QString l3 = dictionary["EDITION"] + ' ' + "Edition";
3054         QString l4 = licenseInfo[ "EXPIRYDATE" ];
3055         sout << "Licensee...................." << (l1.isNull() ? "" : l1) << endl;
3056         sout << "License ID.................." << (l2.isNull() ? "" : l2) << endl;
3057         sout << "Product license............." << (l3.isNull() ? "" : l3) << endl;
3058         sout << "Expiry Date................." << (l4.isNull() ? "" : l4) << endl << endl;
3059     }
3060
3061     sout << "Configuration:" << endl;
3062     sout << "    " << qmakeConfig.join("\r\n    ") << endl;
3063     sout << "Qt Configuration:" << endl;
3064     sout << "    " << qtConfig.join("\r\n    ") << endl;
3065     sout << endl;
3066
3067     if (dictionary.contains("XQMAKESPEC"))
3068         sout << "QMAKESPEC..................." << dictionary[ "XQMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
3069     else
3070         sout << "QMAKESPEC..................." << dictionary[ "QMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
3071     sout << "Architecture................" << dictionary["QT_ARCH"]
3072          << ", features:" << dictionary["QT_CPU_FEATURES"] << endl;
3073     sout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"]
3074          << ", features:" << dictionary["QT_HOST_CPU_FEATURES"]  << endl;
3075     sout << "Maketool...................." << dictionary[ "MAKE" ] << endl;
3076     sout << "Debug symbols..............." << (dictionary[ "BUILD" ] == "debug" ? "yes" : "no") << endl;
3077     sout << "Link Time Code Generation..." << dictionary[ "LTCG" ] << endl;
3078     sout << "Accessibility support......." << dictionary[ "ACCESSIBILITY" ] << endl;
3079     sout << "RTTI support................" << dictionary[ "RTTI" ] << endl;
3080     sout << "SSE2 support................" << dictionary[ "SSE2" ] << endl;
3081     sout << "IWMMXT support.............." << dictionary[ "IWMMXT" ] << endl;
3082     sout << "OpenGL support.............." << dictionary[ "OPENGL" ] << endl;
3083     sout << "OpenVG support.............." << dictionary[ "OPENVG" ] << endl;
3084     sout << "OpenSSL support............." << dictionary[ "OPENSSL" ] << endl;
3085     sout << "QtDBus support.............." << dictionary[ "DBUS" ] << endl;
3086     sout << "QtWidgets module support...." << dictionary[ "WIDGETS" ] << endl;
3087     sout << "QML debugging..............." << dictionary[ "QML_DEBUG" ] << endl;
3088     sout << "DirectWrite support........." << dictionary[ "DIRECTWRITE" ] << endl << endl;
3089
3090     sout << "Third Party Libraries:" << endl;
3091     sout << "    ZLIB support............" << dictionary[ "ZLIB" ] << endl;
3092     sout << "    GIF support............." << dictionary[ "GIF" ] << endl;
3093     sout << "    JPEG support............" << dictionary[ "JPEG" ] << endl;
3094     sout << "    PNG support............." << dictionary[ "PNG" ] << endl;
3095     sout << "    FreeType support........" << dictionary[ "FREETYPE" ] << endl << endl;
3096     sout << "    PCRE support............" << dictionary[ "PCRE" ] << endl;
3097     sout << "    ICU support............." << dictionary[ "ICU" ] << endl;
3098
3099     sout << "Styles:" << endl;
3100     sout << "    Windows................." << dictionary[ "STYLE_WINDOWS" ] << endl;
3101     sout << "    Windows XP.............." << dictionary[ "STYLE_WINDOWSXP" ] << endl;
3102     sout << "    Windows Vista..........." << dictionary[ "STYLE_WINDOWSVISTA" ] << endl;
3103     sout << "    Plastique..............." << dictionary[ "STYLE_PLASTIQUE" ] << endl;
3104     sout << "    Cleanlooks.............." << dictionary[ "STYLE_CLEANLOOKS" ] << endl;
3105     sout << "    Motif..................." << dictionary[ "STYLE_MOTIF" ] << endl;
3106     sout << "    CDE....................." << dictionary[ "STYLE_CDE" ] << endl;
3107     sout << "    Windows CE.............." << dictionary[ "STYLE_WINDOWSCE" ] << endl;
3108     sout << "    Windows Mobile.........." << dictionary[ "STYLE_WINDOWSMOBILE" ] << endl << endl;
3109
3110     sout << "Sql Drivers:" << endl;
3111     sout << "    ODBC...................." << dictionary[ "SQL_ODBC" ] << endl;
3112     sout << "    MySQL..................." << dictionary[ "SQL_MYSQL" ] << endl;
3113     sout << "    OCI....................." << dictionary[ "SQL_OCI" ] << endl;
3114     sout << "    PostgreSQL.............." << dictionary[ "SQL_PSQL" ] << endl;
3115     sout << "    TDS....................." << dictionary[ "SQL_TDS" ] << endl;
3116     sout << "    DB2....................." << dictionary[ "SQL_DB2" ] << endl;
3117     sout << "    SQLite.................." << dictionary[ "SQL_SQLITE" ] << " (" << dictionary[ "SQL_SQLITE_LIB" ] << ")" << endl;
3118     sout << "    SQLite2................." << dictionary[ "SQL_SQLITE2" ] << endl;
3119     sout << "    InterBase..............." << dictionary[ "SQL_IBASE" ] << endl << endl;
3120
3121     sout << "Sources are in.............." << dictionary[ "QT_SOURCE_TREE" ] << endl;
3122     sout << "Build is done in............" << dictionary[ "QT_BUILD_TREE" ] << endl;
3123     sout << "Install prefix.............." << dictionary[ "QT_INSTALL_PREFIX" ] << endl;
3124     sout << "Headers installed to........" << dictionary[ "QT_INSTALL_HEADERS" ] << endl;
3125     sout << "Libraries installed to......" << dictionary[ "QT_INSTALL_LIBS" ] << endl;
3126     sout << "Plugins installed to........" << dictionary[ "QT_INSTALL_PLUGINS" ] << endl;
3127     sout << "Imports installed to........" << dictionary[ "QT_INSTALL_IMPORTS" ] << endl;
3128     sout << "Binaries installed to......." << dictionary[ "QT_INSTALL_BINS" ] << endl;
3129     sout << "Docs installed to..........." << dictionary[ "QT_INSTALL_DOCS" ] << endl;
3130     sout << "Data installed to..........." << dictionary[ "QT_INSTALL_DATA" ] << endl;
3131     sout << "Translations installed to..." << dictionary[ "QT_INSTALL_TRANSLATIONS" ] << endl;
3132     sout << "Examples installed to......." << dictionary[ "QT_INSTALL_EXAMPLES" ] << endl;
3133     sout << "Tests installed to.........." << dictionary[ "QT_INSTALL_TESTS" ] << endl;
3134
3135     if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith(QLatin1String("wince"))) {
3136         sout << "Using c runtime detection..." << dictionary[ "CE_CRT" ] << endl;
3137         sout << "Cetest support.............." << dictionary[ "CETEST" ] << endl;
3138         sout << "Signature..................." << dictionary[ "CE_SIGNATURE"] << endl << endl;
3139     }
3140
3141     if (checkAvailability("INCREDIBUILD_XGE"))
3142         sout << "Using IncrediBuild XGE......" << dictionary["INCREDIBUILD_XGE"] << endl;
3143     if (!qmakeDefines.isEmpty()) {
3144         sout << "Defines.....................";
3145         for (QStringList::Iterator defs = qmakeDefines.begin(); defs != qmakeDefines.end(); ++defs)
3146             sout << (*defs) << " ";
3147         sout << endl;
3148     }
3149     if (!qmakeIncludes.isEmpty()) {
3150         sout << "Include paths...............";
3151         for (QStringList::Iterator incs = qmakeIncludes.begin(); incs != qmakeIncludes.end(); ++incs)
3152             sout << (*incs) << " ";
3153         sout << endl;
3154     }
3155     if (!qmakeLibs.isEmpty()) {
3156         sout << "Additional libraries........";
3157         for (QStringList::Iterator libs = qmakeLibs.begin(); libs != qmakeLibs.end(); ++libs)
3158             sout << (*libs) << " ";
3159         sout << endl;
3160     }
3161     if (dictionary[ "QMAKE_INTERNAL" ] == "yes") {
3162         sout << "Using internal configuration." << endl;
3163     }
3164     if (dictionary[ "SHARED" ] == "no") {
3165         sout << "WARNING: Using static linking will disable the use of plugins." << endl;
3166         sout << "         Make sure you compile ALL needed modules into the library." << endl;
3167     }
3168     if (dictionary[ "OPENSSL" ] == "linked" && opensslLibs.isEmpty()) {
3169         sout << "NOTE: When linking against OpenSSL, you can override the default" << endl;
3170         sout << "library names through OPENSSL_LIBS." << endl;
3171         sout << "For example:" << endl;
3172         sout << "    configure -openssl-linked OPENSSL_LIBS=\"-lssleay32 -llibeay32\"" << endl;
3173     }
3174     if (dictionary[ "ZLIB_FORCED" ] == "yes") {
3175         QString which_zlib = "supplied";
3176         if (dictionary[ "ZLIB" ] == "system")
3177             which_zlib = "system";
3178
3179         sout << "NOTE: The -no-zlib option was supplied but is no longer supported." << endl
3180              << endl
3181              << "Qt now requires zlib support in all builds, so the -no-zlib" << endl
3182              << "option was ignored. Qt will be built using the " << which_zlib
3183              << "zlib" << endl;
3184     }
3185     if (dictionary["OBSOLETE_ARCH_ARG"] == "yes") {
3186         sout << endl
3187              << "NOTE: The -arch option is obsolete." << endl
3188              << endl
3189              << "Qt now detects the target and host architectures based on compiler" << endl
3190              << "output. Qt will be built using " << dictionary["QT_ARCH"] << " for the target architecture" << endl
3191              << "and " << dictionary["QT_HOST_ARCH"] << " for the host architecture (note that these two" << endl
3192              << "will be the same unless you are cross-compiling)." << endl
3193              << endl;
3194     }
3195
3196     // display config.summary
3197     sout.seekg(0, ios::beg);
3198     while (sout) {
3199         string str;
3200         getline(sout, str);
3201         cout << str << endl;
3202     }
3203 }
3204 #endif
3205
3206 #if !defined(EVAL)
3207 void Configure::generateHeaders()
3208 {
3209     if (dictionary["SYNCQT"] == "yes") {
3210         if (findFile("perl.exe")) {
3211             cout << "Running syncqt..." << endl;
3212             QStringList args;
3213             args += buildPath + "/bin/syncqt.bat";
3214             args += sourcePath;
3215             QStringList env;
3216             env += QString("QTDIR=" + sourcePath);
3217             env += QString("PATH=" + buildPath + "/bin/;" + qgetenv("PATH"));
3218             int retc = Environment::execute(args, env, QStringList());
3219             if (retc) {
3220                 cout << "syncqt failed, return code " << retc << endl << endl;
3221                 dictionary["DONE"] = "error";
3222             }
3223         } else {
3224             cout << "Perl not found in environment - cannot run syncqt." << endl;
3225             dictionary["DONE"] = "error";
3226         }
3227     }
3228 }
3229
3230 void Configure::buildQmake()
3231 {
3232     if (dictionary[ "BUILD_QMAKE" ] == "yes") {
3233         QStringList args;
3234
3235         // Build qmake
3236         QString pwd = QDir::currentPath();
3237         if (!QDir(buildPath).mkpath("qmake")) {
3238             cout << "Cannot create qmake build dir." << endl;
3239             dictionary[ "DONE" ] = "error";
3240             return;
3241         }
3242         if (!QDir::setCurrent(buildPath + "/qmake")) {
3243             cout << "Cannot enter qmake build dir." << endl;
3244             dictionary[ "DONE" ] = "error";
3245             return;
3246         }
3247
3248         QString makefile = "Makefile";
3249         {
3250             QFile out(makefile);
3251             if (out.open(QFile::WriteOnly | QFile::Text)) {
3252                 QTextStream stream(&out);
3253                 stream << "#AutoGenerated by configure.exe" << endl
3254                     << "BUILD_PATH = " << QDir::toNativeSeparators(buildPath) << endl
3255                     << "SOURCE_PATH = " << QDir::toNativeSeparators(sourcePath) << endl;
3256                 stream << "QMAKESPEC = " << dictionary["QMAKESPEC"] << endl
3257                        << "QT_VERSION = " << dictionary["VERSION"] << endl;
3258
3259                 if (dictionary["EDITION"] == "OpenSource" ||
3260                     dictionary["QT_EDITION"].contains("OPENSOURCE"))
3261                     stream << "QMAKE_OPENSOURCE_EDITION = yes" << endl;
3262                 stream << "\n\n";
3263
3264                 QFile in(sourcePath + "/qmake/" + dictionary["QMAKEMAKEFILE"]);
3265                 if (in.open(QFile::ReadOnly | QFile::Text)) {
3266                     QString d = in.readAll();
3267                     //### need replaces (like configure.sh)? --Sam
3268                     stream << d << endl;
3269                 }
3270                 stream.flush();
3271                 out.close();
3272             }
3273         }
3274
3275         args += dictionary[ "MAKE" ];
3276         args += "-f";
3277         args += makefile;
3278
3279         cout << "Creating qmake..." << endl;
3280         int exitCode = Environment::execute(args, QStringList(), QStringList());
3281         if (exitCode) {
3282             args.clear();
3283             args += dictionary[ "MAKE" ];
3284             args += "-f";
3285             args += makefile;
3286             args += "clean";
3287             exitCode = Environment::execute(args, QStringList(), QStringList());
3288             if (exitCode) {
3289                 cout << "Cleaning qmake failed, return code " << exitCode << endl << endl;
3290                 dictionary[ "DONE" ] = "error";
3291             } else {
3292                 args.clear();
3293                 args += dictionary[ "MAKE" ];
3294                 args += "-f";
3295                 args += makefile;
3296                 exitCode = Environment::execute(args, QStringList(), QStringList());
3297                 if (exitCode) {
3298                     cout << "Building qmake failed, return code " << exitCode << endl << endl;
3299                     dictionary[ "DONE" ] = "error";
3300                 }
3301             }
3302         }
3303         QDir::setCurrent(pwd);
3304     }
3305 }
3306 #endif
3307
3308 void Configure::buildHostTools()
3309 {
3310     if (dictionary[ "NOPROCESS" ] == "yes")
3311         dictionary[ "DONE" ] = "yes";
3312
3313     if (!dictionary.contains("XQMAKESPEC"))
3314         return;
3315
3316     QString pwd = QDir::currentPath();
3317     QStringList hostToolsDirs;
3318     hostToolsDirs
3319         << "src/tools";
3320
3321     for (int i = 0; i < hostToolsDirs.count(); ++i) {
3322         cout << "Creating " << hostToolsDirs.at(i) << " ..." << endl;
3323         QString toolBuildPath = buildPath + "/" + hostToolsDirs.at(i);
3324         QString toolSourcePath = sourcePath + "/" + hostToolsDirs.at(i);
3325
3326         // generate Makefile
3327         QStringList args;
3328         args << QDir::toNativeSeparators(buildPath + "/bin/qmake");
3329         // override .qmake.cache because we are not cross-building these.
3330         // we need a full path so that a build with -prefix will still find it.
3331         args << "-spec" << QDir::toNativeSeparators(buildPath + "/mkspecs/" + dictionary["QMAKESPEC"]);
3332         args << "-r";
3333         args << "-o" << QDir::toNativeSeparators(toolBuildPath + "/Makefile");
3334
3335         QDir().mkpath(toolBuildPath);
3336         QDir::setCurrent(toolSourcePath);
3337         int exitCode = Environment::execute(args, QStringList(), QStringList());
3338         if (exitCode) {
3339             cout << "qmake failed, return code " << exitCode << endl << endl;
3340             dictionary["DONE"] = "error";
3341             break;
3342         }
3343
3344         // build app
3345         args.clear();
3346         args += dictionary["MAKE"];
3347         QDir::setCurrent(toolBuildPath);
3348         exitCode = Environment::execute(args, QStringList(), QStringList());
3349         if (exitCode) {
3350             args.clear();
3351             args += dictionary["MAKE"];
3352             args += "clean";
3353             exitCode = Environment::execute(args, QStringList(), QStringList());
3354             if (exitCode) {
3355                 cout << "Cleaning " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl;
3356                 dictionary["DONE"] = "error";
3357                 break;
3358             } else {
3359                 args.clear();
3360                 args += dictionary["MAKE"];
3361                 exitCode = Environment::execute(args, QStringList(), QStringList());
3362                 if (exitCode) {
3363                     cout << "Building " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl;
3364                     dictionary["DONE"] = "error";
3365                     break;
3366                 }
3367             }
3368         }
3369     }
3370     QDir::setCurrent(pwd);
3371 }
3372
3373 void Configure::findProjects(const QString& dirName)
3374 {
3375     if (dictionary[ "NOPROCESS" ] == "no") {
3376         QDir dir(dirName);
3377         QString entryName;
3378         int makeListNumber;
3379         ProjectType qmakeTemplate;
3380         const QFileInfoList &list = dir.entryInfoList(QStringList(QLatin1String("*.pro")),
3381                                                       QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
3382         for (int i = 0; i < list.size(); ++i) {
3383             const QFileInfo &fi = list.at(i);
3384             if (fi.fileName() != "qmake.pro") {
3385                 entryName = dirName + "/" + fi.fileName();
3386                 if (fi.isDir()) {
3387                     findProjects(entryName);
3388                 } else {
3389                     qmakeTemplate = projectType(fi.absoluteFilePath());
3390                     switch (qmakeTemplate) {
3391                     case Lib:
3392                     case Subdirs:
3393                         makeListNumber = 1;
3394                         break;
3395                     default:
3396                         makeListNumber = 2;
3397                         break;
3398                     }
3399                     makeList[makeListNumber].append(new MakeItem(sourceDir.relativeFilePath(fi.absolutePath()),
3400                                                     fi.fileName(),
3401                                                     "Makefile",
3402                                                     qmakeTemplate));
3403                 }
3404             }
3405
3406         }
3407     }
3408 }
3409
3410 void Configure::appendMakeItem(int inList, const QString &item)
3411 {
3412     QString dir;
3413     if (item != "src")
3414         dir = "/" + item;
3415     dir.prepend("/src");
3416     makeList[inList].append(new MakeItem(sourcePath + dir,
3417         item + ".pro", buildPath + dir + "/Makefile", Lib));
3418     if (dictionary[ "DSPFILES" ] == "yes") {
3419         makeList[inList].append(new MakeItem(sourcePath + dir,
3420             item + ".pro", buildPath + dir + "/" + item + ".dsp", Lib));
3421     }
3422     if (dictionary[ "VCPFILES" ] == "yes") {
3423         makeList[inList].append(new MakeItem(sourcePath + dir,
3424             item + ".pro", buildPath + dir + "/" + item + ".vcp", Lib));
3425     }
3426     if (dictionary[ "VCPROJFILES" ] == "yes") {
3427         makeList[inList].append(new MakeItem(sourcePath + dir,
3428             item + ".pro", buildPath + dir + "/" + item + ".vcproj", Lib));
3429     }
3430 }
3431
3432 void Configure::generateMakefiles()
3433 {
3434     if (dictionary[ "NOPROCESS" ] == "no") {
3435 #if !defined(EVAL)
3436         cout << "Creating makefiles in src..." << endl;
3437 #endif
3438
3439         QString spec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
3440         if (spec != "win32-msvc")
3441             dictionary[ "DSPFILES" ] = "no";
3442
3443         if (spec != "win32-msvc.net" && !spec.startsWith("win32-msvc2") && !spec.startsWith(QLatin1String("wince")))
3444             dictionary[ "VCPROJFILES" ] = "no";
3445
3446         int i = 0;
3447         QString pwd = QDir::currentPath();
3448         if (dictionary["FAST"] != "yes") {
3449             QString dirName;
3450             bool generate = true;
3451             bool doDsp = (dictionary["DSPFILES"] == "yes" || dictionary["VCPFILES"] == "yes"
3452                           || dictionary["VCPROJFILES"] == "yes");
3453             while (generate) {
3454                 QString pwd = QDir::currentPath();
3455                 QString dirPath = fixSeparators(buildPath + dirName);
3456                 QStringList args;
3457
3458                 args << fixSeparators(buildPath + "/bin/qmake");
3459
3460                 if (doDsp) {
3461                     if (dictionary[ "DEPENDENCIES" ] == "no")
3462                         args << "-nodepend";
3463                     args << "-tp" <<  "vc";
3464                     doDsp = false; // DSP files will be done
3465                     printf("Generating Visual Studio project files...\n");
3466                 } else {
3467                     printf("Generating Makefiles...\n");
3468                     generate = false; // Now Makefiles will be done
3469                 }
3470                 // don't pass -spec - .qmake.cache has it already
3471                 args << "-r";
3472                 args << (sourcePath + "/qtbase.pro");
3473                 args << "-o";
3474                 args << buildPath;
3475                 if (!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
3476                     args << dictionary[ "QMAKEADDITIONALARGS" ];
3477
3478                 QDir::setCurrent(fixSeparators(dirPath));
3479                 if (int exitCode = Environment::execute(args, QStringList(), QStringList())) {
3480                     cout << "Qmake failed, return code " << exitCode  << endl << endl;
3481                     dictionary[ "DONE" ] = "error";
3482                 }
3483             }
3484         } else {
3485             findProjects(sourcePath);
3486             for (i=0; i<3; i++) {
3487                 for (int j=0; j<makeList[i].size(); ++j) {
3488                     MakeItem *it=makeList[i][j];
3489                     if (it->directory == "tools/configure")
3490                         continue; // don't overwrite our own Makefile
3491
3492                     QString dirPath = fixSeparators(it->directory + "/");
3493                     QString projectName = it->proFile;
3494                     QString makefileName = buildPath + "/" + dirPath + it->target;
3495
3496                     // For shadowbuilds, we need to create the path first
3497                     QDir buildPathDir(buildPath);
3498                     if (sourcePath != buildPath && !buildPathDir.exists(dirPath))
3499                         buildPathDir.mkpath(dirPath);
3500
3501                     QStringList args;
3502
3503                     args << fixSeparators(buildPath + "/bin/qmake");
3504                     args << sourcePath + "/" + dirPath + projectName;
3505                     args << dictionary[ "QMAKE_ALL_ARGS" ];
3506
3507                     cout << "For " << qPrintable(dirPath + projectName) << endl;
3508                     args << "-o";
3509                     args << it->target;
3510                     args << "-spec";
3511                     args << spec;
3512                     if (!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
3513                         args << dictionary[ "QMAKEADDITIONALARGS" ];
3514
3515                     QDir::setCurrent(fixSeparators(dirPath));
3516
3517                     QFile file(makefileName);
3518                     if (!file.open(QFile::WriteOnly | QFile::Text)) {
3519                         printf("failed on dirPath=%s, makefile=%s\n",
3520                             qPrintable(dirPath), qPrintable(makefileName));
3521                         continue;
3522                     }
3523                     QTextStream txt(&file);
3524                     txt << "all:\n";
3525                     txt << "\t" << args.join(" ") << "\n";
3526                     txt << "\t\"$(MAKE)\" -$(MAKEFLAGS) -f " << it->target << "\n";
3527                     txt << "first: all\n";
3528                     txt << "qmake:\n";
3529                     txt << "\t" << args.join(" ") << "\n";
3530                 }
3531             }
3532         }
3533         QDir::setCurrent(pwd);
3534     } else {
3535         cout << "Processing of project files have been disabled." << endl;
3536         cout << "Only use this option if you really know what you're doing." << endl << endl;
3537         return;
3538     }
3539 }
3540
3541 void Configure::showSummary()
3542 {
3543     QString make = dictionary[ "MAKE" ];
3544     if (!dictionary.contains("XQMAKESPEC")) {
3545         cout << endl << endl << "Qt is now configured for building. Just run " << qPrintable(make) << "." << endl;
3546         cout << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl;
3547     } else if (dictionary.value("QMAKESPEC").startsWith("wince")) {
3548         // we are cross compiling for Windows CE
3549         cout << endl << endl << "Qt is now configured for building. To start the build run:" << endl
3550              << "\tsetcepaths " << dictionary.value("XQMAKESPEC") << endl
3551              << "\t" << qPrintable(make) << endl
3552              << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl;
3553     }
3554 }
3555
3556 Configure::ProjectType Configure::projectType(const QString& proFileName)
3557 {
3558     QFile proFile(proFileName);
3559     if (proFile.open(QFile::ReadOnly)) {
3560         QString buffer = proFile.readLine(1024);
3561         while (!buffer.isEmpty()) {
3562             QStringList segments = buffer.split(QRegExp("\\s"));
3563             QStringList::Iterator it = segments.begin();
3564
3565             if (segments.size() >= 3) {
3566                 QString keyword = (*it++);
3567                 QString operation = (*it++);
3568                 QString value = (*it++);
3569
3570                 if (keyword == "TEMPLATE") {
3571                     if (value == "lib")
3572                         return Lib;
3573                     else if (value == "subdirs")
3574                         return Subdirs;
3575                 }
3576             }
3577             // read next line
3578             buffer = proFile.readLine(1024);
3579         }
3580         proFile.close();
3581     }
3582     // Default to app handling
3583     return App;
3584 }
3585
3586 #if !defined(EVAL)
3587
3588 bool Configure::showLicense(QString orgLicenseFile)
3589 {
3590     if (dictionary["LICENSE_CONFIRMED"] == "yes") {
3591         cout << "You have already accepted the terms of the license." << endl << endl;
3592         return true;
3593     }
3594
3595     bool haveGpl3 = false;
3596     QString licenseFile = orgLicenseFile;
3597     QString theLicense;
3598     if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3599         haveGpl3 = QFile::exists(orgLicenseFile + "/LICENSE.GPL3");
3600         theLicense = "GNU Lesser General Public License (LGPL) version 2.1";
3601         if (haveGpl3)
3602             theLicense += "\nor the GNU General Public License (GPL) version 3";
3603     } else {
3604         // the first line of the license file tells us which license it is
3605         QFile file(licenseFile);
3606         if (!file.open(QFile::ReadOnly)) {
3607             cout << "Failed to load LICENSE file" << endl;
3608             return false;
3609         }
3610         theLicense = file.readLine().trimmed();
3611     }
3612
3613     forever {
3614         char accept = '?';
3615         cout << "You are licensed to use this software under the terms of" << endl
3616              << "the " << theLicense << "." << endl
3617              << endl;
3618         if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3619             if (haveGpl3)
3620                 cout << "Type '3' to view the GNU General Public License version 3 (GPLv3)." << endl;
3621             cout << "Type 'L' to view the Lesser GNU General Public License version 2.1 (LGPLv2.1)." << endl;
3622         } else {
3623             cout << "Type '?' to view the " << theLicense << "." << endl;
3624         }
3625         cout << "Type 'y' to accept this license offer." << endl
3626              << "Type 'n' to decline this license offer." << endl
3627              << endl
3628              << "Do you accept the terms of the license?" << endl;
3629         cin >> accept;
3630         accept = tolower(accept);
3631
3632         if (accept == 'y') {
3633             return true;
3634         } else if (accept == 'n') {
3635             return false;
3636         } else {
3637             if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") {
3638                 if (accept == '3')
3639                     licenseFile = orgLicenseFile + "/LICENSE.GPL3";
3640                 else
3641                     licenseFile = orgLicenseFile + "/LICENSE.LGPL";
3642             }
3643             // Get console line height, to fill the screen properly
3644             int i = 0, screenHeight = 25; // default
3645             CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
3646             HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
3647             if (GetConsoleScreenBufferInfo(stdOut, &consoleInfo))
3648                 screenHeight = consoleInfo.srWindow.Bottom
3649                              - consoleInfo.srWindow.Top
3650                              - 1; // Some overlap for context
3651
3652             // Prompt the license content to the user
3653             QFile file(licenseFile);
3654             if (!file.open(QFile::ReadOnly)) {
3655                 cout << "Failed to load LICENSE file" << licenseFile << endl;
3656                 return false;
3657             }
3658             QStringList licenseContent = QString(file.readAll()).split('\n');
3659             while (i < licenseContent.size()) {
3660                 cout << licenseContent.at(i) << endl;
3661                 if (++i % screenHeight == 0) {
3662                     cout << "(Press any key for more..)";
3663                     if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
3664                         exit(0);      // Exit cleanly for Ctrl+C
3665                     cout << "\r";     // Overwrite text above
3666                 }
3667             }
3668         }
3669     }
3670 }
3671
3672 void Configure::readLicense()
3673 {
3674    if (QFile::exists(dictionary["QT_SOURCE_TREE"] + "/src/corelib/kernel/qfunctions_wince.h") &&
3675        (dictionary.value("QMAKESPEC").startsWith("wince") || dictionary.value("XQMAKESPEC").startsWith("wince")))
3676         dictionary["PLATFORM NAME"] = "Qt for Windows CE";
3677     else
3678         dictionary["PLATFORM NAME"] = "Qt for Windows";
3679     dictionary["LICENSE FILE"] = sourcePath;
3680
3681     bool openSource = false;
3682     bool hasOpenSource = QFile::exists(dictionary["LICENSE FILE"] + "/LICENSE.GPL3") || QFile::exists(dictionary["LICENSE FILE"] + "/LICENSE.LGPL");
3683     if (dictionary["BUILDTYPE"] == "commercial") {
3684         openSource = false;
3685     } else if (dictionary["BUILDTYPE"] == "opensource") {
3686         openSource = true;
3687     } else if (hasOpenSource) { // No Open Source? Just display the commercial license right away
3688         forever {
3689             char accept = '?';
3690             cout << "Which edition of Qt do you want to use ?" << endl;
3691             cout << "Type 'c' if you want to use the Commercial Edition." << endl;
3692             cout << "Type 'o' if you want to use the Open Source Edition." << endl;
3693             cin >> accept;
3694             accept = tolower(accept);
3695
3696             if (accept == 'c') {
3697                 openSource = false;
3698                 break;
3699             } else if (accept == 'o') {
3700                 openSource = true;
3701                 break;
3702             }
3703         }
3704     }
3705     if (hasOpenSource && openSource) {
3706         cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " Open Source Edition." << endl;
3707         licenseInfo["LICENSEE"] = "Open Source";
3708         dictionary["EDITION"] = "OpenSource";
3709         dictionary["QT_EDITION"] = "QT_EDITION_OPENSOURCE";
3710         cout << endl;
3711         if (!showLicense(dictionary["LICENSE FILE"])) {
3712             cout << "Configuration aborted since license was not accepted";
3713             dictionary["DONE"] = "error";
3714             return;
3715         }
3716     } else if (openSource) {
3717         cout << endl << "Cannot find the GPL license files! Please download the Open Source version of the library." << endl;
3718         dictionary["DONE"] = "error";
3719     }
3720 #ifdef COMMERCIAL_VERSION
3721     else {
3722         Tools::checkLicense(dictionary, licenseInfo, firstLicensePath());
3723         if (dictionary["DONE"] != "error") {
3724             // give the user some feedback, and prompt for license acceptance
3725             cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl;
3726             if (!showLicense(dictionary["LICENSE FILE"])) {
3727                 cout << "Configuration aborted since license was not accepted";
3728                 dictionary["DONE"] = "error";
3729                 return;
3730             }
3731         }
3732     }
3733 #else // !COMMERCIAL_VERSION
3734     else {
3735         cout << endl << "Cannot build commercial edition from the open source version of the library." << endl;
3736         dictionary["DONE"] = "error";
3737     }
3738 #endif
3739 }
3740
3741 void Configure::reloadCmdLine()
3742 {
3743     if (dictionary[ "REDO" ] == "yes") {
3744         QFile inFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
3745         if (inFile.open(QFile::ReadOnly)) {
3746             QTextStream inStream(&inFile);
3747             QString buffer;
3748             inStream >> buffer;
3749             while (buffer.length()) {
3750                 configCmdLine += buffer;
3751                 inStream >> buffer;
3752             }
3753             inFile.close();
3754         }
3755     }
3756 }
3757
3758 void Configure::saveCmdLine()
3759 {
3760     if (dictionary[ "REDO" ] != "yes") {
3761         QFile outFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
3762         if (outFile.open(QFile::WriteOnly | QFile::Text)) {
3763             QTextStream outStream(&outFile);
3764             for (QStringList::Iterator it = configCmdLine.begin(); it != configCmdLine.end(); ++it) {
3765                 outStream << (*it) << " " << endl;
3766             }
3767             outStream.flush();
3768             outFile.close();
3769         }
3770     }
3771 }
3772 #endif // !EVAL
3773
3774 bool Configure::isDone()
3775 {
3776     return !dictionary["DONE"].isEmpty();
3777 }
3778
3779 bool Configure::isOk()
3780 {
3781     return (dictionary[ "DONE" ] != "error");
3782 }
3783
3784 bool
3785 Configure::filesDiffer(const QString &fn1, const QString &fn2)
3786 {
3787     QFile file1(fn1), file2(fn2);
3788     if (!file1.open(QFile::ReadOnly) || !file2.open(QFile::ReadOnly))
3789         return true;
3790     const int chunk = 2048;
3791     int used1 = 0, used2 = 0;
3792     char b1[chunk], b2[chunk];
3793     while (!file1.atEnd() && !file2.atEnd()) {
3794         if (!used1)
3795             used1 = file1.read(b1, chunk);
3796         if (!used2)
3797             used2 = file2.read(b2, chunk);
3798         if (used1 > 0 && used2 > 0) {
3799             const int cmp = qMin(used1, used2);
3800             if (memcmp(b1, b2, cmp))
3801                 return true;
3802             if ((used1 -= cmp))
3803                 memcpy(b1, b1+cmp, used1);
3804             if ((used2 -= cmp))
3805                 memcpy(b2, b2+cmp, used2);
3806         }
3807     }
3808     return !file1.atEnd() || !file2.atEnd();
3809 }
3810
3811 QT_END_NAMESPACE