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.right(1) != QString(QChar(QDir::separator())))
107 oldpwd += QDir::separator();
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::fixPathToLocalOS((*pfile));
145 if(!QFile::exists(fn)) {
146 fprintf(stderr, "Cannot find file: %s.\n", fn.toLatin1().constData());
152 debug_msg(1, "Resetting dir to: %s", oldpwd.toLatin1().constData());
153 qmake_setpwd(oldpwd); //reset the old pwd
154 int di = fn.lastIndexOf(QDir::separator());
156 debug_msg(1, "Changing dir to: %s", fn.left(di).toLatin1().constData());
157 if(!qmake_setpwd(fn.left(di)))
158 fprintf(stderr, "Cannot find directory: %s\n", fn.left(di).toLatin1().constData());
159 fn = fn.right(fn.length() - di - 1);
163 if(!project.read(fn)) {
164 fprintf(stderr, "Error processing project file: %s\n",
165 fn == "-" ? "(stdin)" : (*pfile).toLatin1().constData());
169 if(Option::mkfile::do_preprocess) //no need to create makefile
174 MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success);
178 if(mkfile && !mkfile->write(oldpwd)) {
179 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
180 fprintf(stderr, "Unable to generate project file.\n");
182 fprintf(stderr, "Unable to generate makefile for: %s\n", (*pfile).toLatin1().constData());
194 int main(int argc, char **argv)
196 return QT_PREPEND_NAMESPACE(runQMake)(argc, argv);