source: trunk/qmake/main.cpp@ 500

Last change on this file since 500 was 407, checked in by Dmitry A. Kuminov, 15 years ago

qmake: Create application instance so that QLibraryInfo will pick up a qt.conf file if there is any in the qmake executable's directory.

File size: 7.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the qmake application of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
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.
22**
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
26** package.
27**
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.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "project.h"
43#include "property.h"
44#include "option.h"
45#include "cachekeys.h"
46#include "metamakefile.h"
47#include <qnamespace.h>
48#include <qdebug.h>
49#include <qregexp.h>
50#include <qdir.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <ctype.h>
54#include <fcntl.h>
55#include <sys/types.h>
56#include <sys/stat.h>
57
58#ifndef QT_BUILD_QMAKE
59#include <qcoreapplication.h>
60#endif
61
62QT_BEGIN_NAMESPACE
63
64// for Borland, main is defined to qMain which breaks qmake
65#undef main
66#ifdef Q_OS_MAC
67#endif
68
69/* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function
70 is much too slow, and called much too often inside of Qt (every fileFixify). With this we use a locally
71 cached copy because I can control all the times it is set (because Qt never sets the pwd under me).
72*/
73static QString pwd;
74QString qmake_getpwd()
75{
76 if(pwd.isNull())
77 pwd = QDir::currentPath();
78 return pwd;
79}
80bool qmake_setpwd(const QString &p)
81{
82 if(QDir::setCurrent(p)) {
83 pwd = QDir::currentPath();
84 return true;
85 }
86 return false;
87}
88
89int runQMake(int argc, char **argv)
90{
91#ifndef QT_BUILD_QMAKE
92 // create application instance so that QLibraryInfo will pick up a qt.conf
93 // file if there is any in the executable's directory
94 QCoreApplication coreApp(argc, argv);
95#endif
96
97 // parse command line
98 int ret = Option::init(argc, argv);
99 if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
100 if ((ret & Option::QMAKE_CMDLINE_ERROR) != 0)
101 return 1;
102 return 0;
103 }
104
105 // report Qt usage for commercial customers with a "metered license" (currently experimental)
106#if QT_EDITION != QT_EDITION_OPENSOURCE
107 QString reporterPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator()
108 + "qtusagereporter";
109#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
110 reporterPath += ".exe";
111#endif
112 if (QFile::exists(reporterPath))
113 system(qPrintable(reporterPath + " qmake"));
114#endif
115
116 QString oldpwd = qmake_getpwd();
117#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
118 if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/")))
119#endif
120 {
121 if(oldpwd.right(1) != QString(QChar(QDir::separator())))
122 oldpwd += QDir::separator();
123 }
124 Option::output_dir = oldpwd; //for now this is the output dir
125
126 if(Option::output.fileName() != "-") {
127 QFileInfo fi(Option::output);
128 QString dir;
129 if(fi.isDir()) {
130 dir = fi.filePath();
131 } else {
132 QString tmp_dir = fi.path();
133 if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir))
134 dir = tmp_dir;
135 }
136 if(!dir.isNull() && dir != ".")
137 Option::output_dir = dir;
138 if(QDir::isRelativePath(Option::output_dir))
139 Option::output_dir.prepend(oldpwd);
140 Option::output_dir = QDir::cleanPath(Option::output_dir);
141 }
142
143 QMakeProperty prop;
144 if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY || Option::qmake_mode == Option::QMAKE_SET_PROPERTY)
145 return prop.exec() ? 0 : 101;
146
147 QMakeProject project(&prop);
148 int exit_val = 0;
149 QStringList files;
150 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
151 files << "(*hack*)"; //we don't even use files, but we do the for() body once
152 else
153 files = Option::mkfile::project_files;
154 for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) {
155 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
156 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
157 QString fn = Option::fixPathToLocalOS((*pfile));
158 if(!QFile::exists(fn)) {
159 fprintf(stderr, "Cannot find file: %s.\n", fn.toLatin1().constData());
160 exit_val = 2;
161 continue;
162 }
163
164 //setup pwd properly
165 debug_msg(1, "Resetting dir to: %s", oldpwd.toLatin1().constData());
166 qmake_setpwd(oldpwd); //reset the old pwd
167 int di = fn.lastIndexOf(Option::dir_sep);
168 if(di != -1) {
169 debug_msg(1, "Changing dir to: %s", fn.left(di).toLatin1().constData());
170 if(!qmake_setpwd(fn.left(di)))
171 fprintf(stderr, "Cannot find directory: %s\n", fn.left(di).toLatin1().constData());
172 fn = fn.right(fn.length() - di - 1);
173 }
174
175 // read project..
176 if(!project.read(fn)) {
177 fprintf(stderr, "Error processing project file: %s\n",
178 fn == "-" ? "(stdin)" : (*pfile).toLatin1().constData());
179 exit_val = 3;
180 continue;
181 }
182 if(Option::mkfile::do_preprocess) //no need to create makefile
183 continue;
184 }
185
186 MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false);
187 if(mkfile && !mkfile->write(oldpwd)) {
188 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
189 fprintf(stderr, "Unable to generate project file.\n");
190 else
191 fprintf(stderr, "Unable to generate makefile for: %s\n", (*pfile).toLatin1().constData());
192 exit_val = 5;
193 }
194 delete mkfile;
195 mkfile = NULL;
196 }
197 qmakeClearCaches();
198 return exit_val;
199}
200
201QT_END_NAMESPACE
202
203int main(int argc, char **argv)
204{
205 return QT_PREPEND_NAMESPACE(runQMake)(argc, argv);
206}
Note: See TracBrowser for help on using the repository browser.