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 // for Borland, main is defined to qMain which breaks qmake
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).
70 QString qmake_getpwd()
73 pwd = QDir::currentPath();
76 bool qmake_setpwd(const QString &p)
78 if(QDir::setCurrent(p)) {
79 pwd = QDir::currentPath();
85 int runQMake(int argc, char **argv)
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);
94 int ret = Option::init(argc, argv);
95 if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
96 if ((ret & Option::QMAKE_CMDLINE_ERROR) != 0)
101 QString oldpwd = qmake_getpwd();
103 if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/")))
106 if(!oldpwd.endsWith(QLatin1Char('/')))
107 oldpwd += QLatin1Char('/');
109 Option::output_dir = oldpwd; //for now this is the output dir
111 if(Option::output.fileName() != "-") {
112 QFileInfo fi(Option::output);
117 QString tmp_dir = fi.path();
118 if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir))
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);
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;
134 QMakeProject project(&prop);
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
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());
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('/'));
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);
166 if (!Option::prepareProject(fn)) {
172 if(!project.read(fn)) {
173 fprintf(stderr, "Error processing project file: %s\n",
174 fn == QLatin1String("-") ?
175 "(stdin)" : QDir::toNativeSeparators(*pfile).toLatin1().constData());
179 if(Option::mkfile::do_preprocess) //no need to create makefile
184 MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success);
188 if(mkfile && !mkfile->write(oldpwd)) {
189 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
190 fprintf(stderr, "Unable to generate project file.\n");
192 fprintf(stderr, "Unable to generate makefile for: %s\n",
193 QDir::toNativeSeparators(*pfile).toLatin1().constData());
205 int main(int argc, char **argv)
207 return QT_PREPEND_NAMESPACE(runQMake)(argc, argv);