Got rid of Map / Unmap events in favor of Expose event.
[profile/ivi/qtbase.git] / qmake / main.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 qmake application 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 "project.h"
43 #include "property.h"
44 #include "option.h"
45 #include "cachekeys.h"
46 #include "metamakefile.h"
47 #include <qnamespace.h>
48 #include <qdebug.h>
49 #include <qregexp.h>
50 #include <qdir.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <ctype.h>
54 #include <fcntl.h>
55 #include <sys/types.h>
56 #include <sys/stat.h>
57
58 QT_BEGIN_NAMESPACE
59
60 // for Borland, main is defined to qMain which breaks qmake
61 #undef main
62 #ifdef Q_OS_MAC
63 #endif
64
65 /* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function
66    is much too slow, and called much too often inside of Qt (every fileFixify). With this we use a locally
67    cached copy because I can control all the times it is set (because Qt never sets the pwd under me).
68 */
69 static QString pwd;
70 QString qmake_getpwd()
71 {
72     if(pwd.isNull())
73         pwd = QDir::currentPath();
74     return pwd;
75 }
76 bool qmake_setpwd(const QString &p)
77 {
78     if(QDir::setCurrent(p)) {
79         pwd = QDir::currentPath();
80         return true;
81     }
82     return false;
83 }
84
85 int runQMake(int argc, char **argv)
86 {
87     // stderr is unbuffered by default, but stdout buffering depends on whether
88     // there is a terminal attached. Buffering can make output from stderr and stdout
89     // appear out of sync, so force stdout to be unbuffered as well.
90     // This is particularly important for things like QtCreator and scripted builds.
91     setvbuf(stdout, (char *)NULL, _IONBF, 0);
92
93     // parse command line
94     int ret = Option::init(argc, argv);
95     if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
96         if ((ret & Option::QMAKE_CMDLINE_ERROR) != 0)
97             return 1;
98         return 0;
99     }
100
101     QString oldpwd = qmake_getpwd();
102 #ifdef Q_OS_WIN
103     if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/")))
104 #endif
105     {
106         if(!oldpwd.endsWith(QLatin1Char('/')))
107             oldpwd += QLatin1Char('/');
108     }
109     Option::output_dir = oldpwd; //for now this is the output dir
110
111     if(Option::output.fileName() != "-") {
112         QFileInfo fi(Option::output);
113         QString dir;
114         if(fi.isDir()) {
115             dir = fi.filePath();
116         } else {
117             QString tmp_dir = fi.path();
118             if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir))
119                 dir = tmp_dir;
120         }
121         if(!dir.isNull() && dir != ".")
122             Option::output_dir = dir;
123         if(QDir::isRelativePath(Option::output_dir))
124             Option::output_dir.prepend(oldpwd);
125         Option::output_dir = QDir::cleanPath(Option::output_dir);
126     }
127
128     QMakeProperty prop;
129     if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY ||
130        Option::qmake_mode == Option::QMAKE_SET_PROPERTY ||
131        Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY)
132         return prop.exec() ? 0 : 101;
133
134     QMakeProject project(&prop);
135     int exit_val = 0;
136     QStringList files;
137     if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
138         files << "(*hack*)"; //we don't even use files, but we do the for() body once
139     else
140         files = Option::mkfile::project_files;
141     for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) {
142         if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
143            Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
144             QString fn = Option::normalizePath(*pfile);
145             if(!QFile::exists(fn)) {
146                 fprintf(stderr, "Cannot find file: %s.\n",
147                         QDir::toNativeSeparators(fn).toLatin1().constData());
148                 exit_val = 2;
149                 continue;
150             }
151
152             //setup pwd properly
153             debug_msg(1, "Resetting dir to: %s",
154                       QDir::toNativeSeparators(oldpwd).toLatin1().constData());
155             qmake_setpwd(oldpwd); //reset the old pwd
156             int di = fn.lastIndexOf(QLatin1Char('/'));
157             if(di != -1) {
158                 debug_msg(1, "Changing dir to: %s",
159                           QDir::toNativeSeparators(fn.left(di)).toLatin1().constData());
160                 if(!qmake_setpwd(fn.left(di)))
161                     fprintf(stderr, "Cannot find directory: %s\n",
162                             QDir::toNativeSeparators(fn.left(di)).toLatin1().constData());
163                 fn = fn.right(fn.length() - di - 1);
164             }
165
166             if (!Option::prepareProject(fn)) {
167                 exit_val = 3;
168                 break;
169             }
170
171             // read project..
172             if(!project.read(fn)) {
173                 fprintf(stderr, "Error processing project file: %s\n",
174                         fn == QLatin1String("-") ?
175                             "(stdin)" : QDir::toNativeSeparators(*pfile).toLatin1().constData());
176                 exit_val = 3;
177                 continue;
178             }
179             if(Option::mkfile::do_preprocess) //no need to create makefile
180                 continue;
181         }
182
183         bool success = true;
184         MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success);
185         if (!success)
186             exit_val = 3;
187
188         if(mkfile && !mkfile->write(oldpwd)) {
189             if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
190                 fprintf(stderr, "Unable to generate project file.\n");
191             else
192                 fprintf(stderr, "Unable to generate makefile for: %s\n",
193                         QDir::toNativeSeparators(*pfile).toLatin1().constData());
194             exit_val = 5;
195         }
196         delete mkfile;
197         mkfile = NULL;
198     }
199     qmakeClearCaches();
200     return exit_val;
201 }
202
203 QT_END_NAMESPACE
204
205 int main(int argc, char **argv)
206 {
207     return QT_PREPEND_NAMESPACE(runQMake)(argc, argv);
208 }