1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 ** This file is part of the qmake application of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the either Technology Preview License Agreement or the
13 ** Beta Release License Agreement.
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
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.
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at http://www.qtsoftware.com/contact.
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 // report Qt usage for commercial customers with a "metered license" (currently experimental)
102 #if QT_EDITION != QT_EDITION_OPENSOURCE
103 QString reporterPath
= QLibraryInfo::location(QLibraryInfo::BinariesPath
) + QDir::separator()
105 #if defined(Q_OS_WIN)
106 reporterPath
+= ".exe";
108 if (QFile::exists(reporterPath
))
109 system(qPrintable(reporterPath
+ " qmake"));
112 QString oldpwd
= qmake_getpwd();
114 if(!(oldpwd
.length() == 3 && oldpwd
[0].isLetter() && oldpwd
.endsWith(":/")))
117 if(oldpwd
.right(1) != QString(QChar(QDir::separator())))
118 oldpwd
+= QDir::separator();
120 Option::output_dir
= oldpwd
; //for now this is the output dir
122 if(Option::output
.fileName() != "-") {
123 QFileInfo
fi(Option::output
);
128 QString tmp_dir
= fi
.path();
129 if(!tmp_dir
.isEmpty() && QFile::exists(tmp_dir
))
132 if(!dir
.isNull() && dir
!= ".")
133 Option::output_dir
= dir
;
134 if(QDir::isRelativePath(Option::output_dir
))
135 Option::output_dir
.prepend(oldpwd
);
136 Option::output_dir
= QDir::cleanPath(Option::output_dir
);
140 if(Option::qmake_mode
== Option::QMAKE_QUERY_PROPERTY
|| Option::qmake_mode
== Option::QMAKE_SET_PROPERTY
)
141 return prop
.exec() ? 0 : 101;
143 QMakeProject
project(&prop
);
146 if(Option::qmake_mode
== Option::QMAKE_GENERATE_PROJECT
)
147 files
<< "(*hack*)"; //we don't even use files, but we do the for() body once
149 files
= Option::mkfile::project_files
;
150 for(QStringList::Iterator pfile
= files
.begin(); pfile
!= files
.end(); pfile
++) {
151 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
152 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
) {
153 QString fn
= Option::fixPathToLocalOS((*pfile
));
154 if(!QFile::exists(fn
)) {
155 fprintf(stderr
, "Cannot find file: %s.\n", fn
.toLatin1().constData());
161 debug_msg(1, "Resetting dir to: %s", oldpwd
.toLatin1().constData());
162 qmake_setpwd(oldpwd
); //reset the old pwd
163 int di
= fn
.lastIndexOf(Option::dir_sep
);
165 debug_msg(1, "Changing dir to: %s", fn
.left(di
).toLatin1().constData());
166 if(!qmake_setpwd(fn
.left(di
)))
167 fprintf(stderr
, "Cannot find directory: %s\n", fn
.left(di
).toLatin1().constData());
168 fn
= fn
.right(fn
.length() - di
- 1);
172 if(!project
.read(fn
)) {
173 fprintf(stderr
, "Error processing project file: %s\n",
174 fn
== "-" ? "(stdin)" : (*pfile
).toLatin1().constData());
178 if(Option::mkfile::do_preprocess
) //no need to create makefile
182 MetaMakefileGenerator
*mkfile
= MetaMakefileGenerator::createMetaGenerator(&project
, QString(), false);
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", (*pfile
).toLatin1().constData());
199 int main(int argc
, char **argv
)
201 return QT_PREPEND_NAMESPACE(runQMake
)(argc
, argv
);