1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the qmake application of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
45 #include "cachekeys.h"
46 #include "metamakefile.h"
47 #include <qnamespace.h>
55 #include <sys/types.h>
60 /* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function
61 is much too slow, and called much too often inside of Qt (every fileFixify). With this we use a locally
62 cached copy because I can control all the times it is set (because Qt never sets the pwd under me).
65 QString qmake_getpwd()
68 pwd = QDir::currentPath();
71 bool qmake_setpwd(const QString &p)
73 if(QDir::setCurrent(p)) {
74 pwd = QDir::currentPath();
80 int runQMake(int argc, char **argv)
82 // stderr is unbuffered by default, but stdout buffering depends on whether
83 // there is a terminal attached. Buffering can make output from stderr and stdout
84 // appear out of sync, so force stdout to be unbuffered as well.
85 // This is particularly important for things like QtCreator and scripted builds.
86 setvbuf(stdout, (char *)NULL, _IONBF, 0);
89 int ret = Option::init(argc, argv);
90 if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
91 if ((ret & Option::QMAKE_CMDLINE_ERROR) != 0)
96 QString oldpwd = qmake_getpwd();
98 if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/")))
101 if(!oldpwd.endsWith(QLatin1Char('/')))
102 oldpwd += QLatin1Char('/');
104 Option::output_dir = oldpwd; //for now this is the output dir
106 if(Option::output.fileName() != "-") {
107 QFileInfo fi(Option::output);
112 QString tmp_dir = fi.path();
113 if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir))
116 if(!dir.isNull() && dir != ".")
117 Option::output_dir = dir;
118 if(QDir::isRelativePath(Option::output_dir))
119 Option::output_dir.prepend(oldpwd);
120 Option::output_dir = QDir::cleanPath(Option::output_dir);
124 if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY ||
125 Option::qmake_mode == Option::QMAKE_SET_PROPERTY ||
126 Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY)
127 return prop.exec() ? 0 : 101;
129 QMakeProject project(&prop);
132 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
133 files << "(*hack*)"; //we don't even use files, but we do the for() body once
135 files = Option::mkfile::project_files;
136 for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) {
137 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
138 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
139 QString fn = Option::normalizePath(*pfile);
140 if(!QFile::exists(fn)) {
141 fprintf(stderr, "Cannot find file: %s.\n",
142 QDir::toNativeSeparators(fn).toLatin1().constData());
148 debug_msg(1, "Resetting dir to: %s",
149 QDir::toNativeSeparators(oldpwd).toLatin1().constData());
150 qmake_setpwd(oldpwd); //reset the old pwd
151 int di = fn.lastIndexOf(QLatin1Char('/'));
153 debug_msg(1, "Changing dir to: %s",
154 QDir::toNativeSeparators(fn.left(di)).toLatin1().constData());
155 if(!qmake_setpwd(fn.left(di)))
156 fprintf(stderr, "Cannot find directory: %s\n",
157 QDir::toNativeSeparators(fn.left(di)).toLatin1().constData());
158 fn = fn.right(fn.length() - di - 1);
161 Option::prepareProject(fn);
164 if(!project.read(fn)) {
165 fprintf(stderr, "Error processing project file: %s\n",
166 fn == QLatin1String("-") ?
167 "(stdin)" : QDir::toNativeSeparators(*pfile).toLatin1().constData());
171 if (Option::mkfile::do_preprocess) {
173 continue; //no need to create makefile
178 MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success);
182 if(mkfile && !mkfile->write(oldpwd)) {
183 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
184 fprintf(stderr, "Unable to generate project file.\n");
186 fprintf(stderr, "Unable to generate makefile for: %s\n",
187 QDir::toNativeSeparators(*pfile).toLatin1().constData());
199 int main(int argc, char **argv)
201 return QT_PREPEND_NAMESPACE(runQMake)(argc, argv);