1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the qmake application of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** 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);
167 if(!project.read(fn)) {
168 fprintf(stderr, "Error processing project file: %s\n",
169 fn == QLatin1String("-") ?
170 "(stdin)" : QDir::toNativeSeparators(*pfile).toLatin1().constData());
174 if(Option::mkfile::do_preprocess) //no need to create makefile
179 MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success);
183 if(mkfile && !mkfile->write(oldpwd)) {
184 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
185 fprintf(stderr, "Unable to generate project file.\n");
187 fprintf(stderr, "Unable to generate makefile for: %s\n",
188 QDir::toNativeSeparators(*pfile).toLatin1().constData());
200 int main(int argc, char **argv)
202 return QT_PREPEND_NAMESPACE(runQMake)(argc, argv);