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