source: trunk/qmake/main.cpp@ 853

Last change on this file since 853 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the qmake application of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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#ifndef QT_BUILD_QMAKE
59#include <qcoreapplication.h>
60#endif
61
62QT_BEGIN_NAMESPACE
63
64// for Borland, main is defined to qMain which breaks qmake
65#undef main
66#ifdef Q_OS_MAC
67#endif
68
69/* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function
70 is much too slow, and called much too often inside of Qt (every fileFixify). With this we use a locally
71 cached copy because I can control all the times it is set (because Qt never sets the pwd under me).
72*/
73static QString pwd;
74QString qmake_getpwd()
75{
76 if(pwd.isNull())
77 pwd = QDir::currentPath();
78 return pwd;
79}
80bool qmake_setpwd(const QString &p)
81{
82 if(QDir::setCurrent(p)) {
83 pwd = QDir::currentPath();
84 return true;
85 }
86 return false;
87}
88
89int runQMake(int argc, char **argv)
90{
91 // stderr is unbuffered by default, but stdout buffering depends on whether
92 // there is a terminal attached. Buffering can make output from stderr and stdout
93 // appear out of sync, so force stdout to be unbuffered as well.
94 // This is particularly important for things like QtCreator and scripted builds.
95 setvbuf(stdout, (char *)NULL, _IONBF, 0);
96
97 // parse command line
98 int ret = Option::init(argc, argv);
99 if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
100 if ((ret & Option::QMAKE_CMDLINE_ERROR) != 0)
101 return 1;
102 return 0;
103 }
104
105 QString oldpwd = qmake_getpwd();
106#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
107 if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/")))
108#endif
109 {
110 if(oldpwd.right(1) != QString(QChar(QDir::separator())))
111 oldpwd += QDir::separator();
112 }
113 Option::output_dir = oldpwd; //for now this is the output dir
114
115 if(Option::output.fileName() != "-") {
116 QFileInfo fi(Option::output);
117 QString dir;
118 if(fi.isDir()) {
119 dir = fi.filePath();
120 } else {
121 QString tmp_dir = fi.path();
122 if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir))
123 dir = tmp_dir;
124 }
125 if(!dir.isNull() && dir != ".")
126 Option::output_dir = dir;
127 if(QDir::isRelativePath(Option::output_dir))
128 Option::output_dir.prepend(oldpwd);
129 Option::output_dir = QDir::cleanPath(Option::output_dir);
130 }
131
132 QMakeProperty prop;
133 if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY || Option::qmake_mode == Option::QMAKE_SET_PROPERTY)
134 return prop.exec() ? 0 : 101;
135
136 QMakeProject project(&prop);
137 int exit_val = 0;
138 QStringList files;
139 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
140 files << "(*hack*)"; //we don't even use files, but we do the for() body once
141 else
142 files = Option::mkfile::project_files;
143 for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) {
144 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
145 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
146 QString fn = Option::fixPathToLocalOS((*pfile));
147 if(!QFile::exists(fn)) {
148 fprintf(stderr, "Cannot find file: %s.\n", fn.toLatin1().constData());
149 exit_val = 2;
150 continue;
151 }
152
153 //setup pwd properly
154 debug_msg(1, "Resetting dir to: %s", oldpwd.toLatin1().constData());
155 qmake_setpwd(oldpwd); //reset the old pwd
156 int di = fn.lastIndexOf(QDir::separator());
157 if(di != -1) {
158 debug_msg(1, "Changing dir to: %s", fn.left(di).toLatin1().constData());
159 if(!qmake_setpwd(fn.left(di)))
160 fprintf(stderr, "Cannot find directory: %s\n", fn.left(di).toLatin1().constData());
161 fn = fn.right(fn.length() - di - 1);
162 }
163
164 // read project..
165 if(!project.read(fn)) {
166 fprintf(stderr, "Error processing project file: %s\n",
167 fn == "-" ? "(stdin)" : (*pfile).toLatin1().constData());
168 exit_val = 3;
169 continue;
170 }
171 if(Option::mkfile::do_preprocess) //no need to create makefile
172 continue;
173 }
174
175 bool success = true;
176 MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success);
177 if (!success)
178 exit_val = 3;
179
180 if(mkfile && !mkfile->write(oldpwd)) {
181 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
182 fprintf(stderr, "Unable to generate project file.\n");
183 else
184 fprintf(stderr, "Unable to generate makefile for: %s\n", (*pfile).toLatin1().constData());
185 exit_val = 5;
186 }
187 delete mkfile;
188 mkfile = NULL;
189 }
190 qmakeClearCaches();
191 return exit_val;
192}
193
194QT_END_NAMESPACE
195
196int main(int argc, char **argv)
197{
198 return QT_PREPEND_NAMESPACE(runQMake)(argc, argv);
199}
Note: See TracBrowser for help on using the repository browser.