summaryrefslogtreecommitdiffstats
path: root/qmake/library/qmakeglobals.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/library/qmakeglobals.cpp')
-rw-r--r--qmake/library/qmakeglobals.cpp368
1 files changed, 368 insertions, 0 deletions
diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp
new file mode 100644
index 0000000000..65196f2810
--- /dev/null
+++ b/qmake/library/qmakeglobals.cpp
@@ -0,0 +1,368 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the qmake application of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmakeglobals.h"
+
+#include "qmakeevaluator.h"
+#include "ioutils.h"
+
+#include <qbytearray.h>
+#include <qdatetime.h>
+#include <qdebug.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qlist.h>
+#include <qregexp.h>
+#include <qset.h>
+#include <qstack.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qtextstream.h>
+#ifdef PROEVALUATOR_THREAD_SAFE
+# include <qthreadpool.h>
+#endif
+
+#ifdef Q_OS_UNIX
+#include <unistd.h>
+#include <sys/utsname.h>
+#else
+#include <windows.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef Q_OS_WIN32
+#define QT_POPEN _popen
+#define QT_PCLOSE _pclose
+#else
+#define QT_POPEN popen
+#define QT_PCLOSE pclose
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#define fL1S(s) QString::fromLatin1(s)
+
+namespace { // MSVC doesn't seem to know the semantics of "static" ...
+
+static struct {
+ QRegExp reg_variableName;
+} statics;
+
+}
+
+static void initStatics()
+{
+ if (!statics.reg_variableName.isEmpty())
+ return;
+
+ statics.reg_variableName.setPattern(QLatin1String("\\$\\(.*\\)"));
+ statics.reg_variableName.setMinimal(true);
+}
+
+QMakeGlobals::QMakeGlobals()
+{
+ initStatics();
+
+ do_cache = true;
+
+#ifdef PROEVALUATOR_DEBUG
+ debugLevel = 0;
+#endif
+#ifdef Q_OS_WIN
+ dirlist_sep = QLatin1Char(';');
+ dir_sep = QLatin1Char('\\');
+#else
+ dirlist_sep = QLatin1Char(':');
+ dir_sep = QLatin1Char('/');
+#endif
+ qmakespec = getEnv(QLatin1String("QMAKESPEC"));
+}
+
+QMakeGlobals::~QMakeGlobals()
+{
+ qDeleteAll(baseEnvs);
+}
+
+QString QMakeGlobals::cleanSpec(QMakeCmdLineParserState &state, const QString &spec)
+{
+ QString ret = QDir::cleanPath(spec);
+ if (ret.contains(QLatin1Char('/'))) {
+ QString absRet = QDir(state.pwd).absoluteFilePath(ret);
+ if (QFile::exists(absRet))
+ ret = QDir::cleanPath(absRet);
+ }
+ return ret;
+}
+
+QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments(
+ QMakeCmdLineParserState &state, QStringList &args, int *pos)
+{
+ enum { ArgNone, ArgConfig, ArgSpec, ArgXSpec, ArgTmpl, ArgTmplPfx, ArgCache } argState = ArgNone;
+ for (; *pos < args.count(); (*pos)++) {
+ QString arg = args.at(*pos);
+ switch (argState) {
+ case ArgConfig:
+ if (state.after)
+ state.postconfigs << arg;
+ else
+ state.preconfigs << arg;
+ break;
+ case ArgSpec:
+ qmakespec = args[*pos] = cleanSpec(state, arg);
+ break;
+ case ArgXSpec:
+ xqmakespec = args[*pos] = cleanSpec(state, arg);
+ break;
+ case ArgTmpl:
+ user_template = arg;
+ break;
+ case ArgTmplPfx:
+ user_template_prefix = arg;
+ break;
+ case ArgCache:
+ cachefile = args[*pos] = QDir::cleanPath(QDir(state.pwd).absoluteFilePath(arg));
+ break;
+ default:
+ if (arg.startsWith(QLatin1Char('-'))) {
+ if (arg == QLatin1String("-after")) {
+ state.after = true;
+ } else if (arg == QLatin1String("-config")) {
+ argState = ArgConfig;
+ } else if (arg == QLatin1String("-nocache")) {
+ do_cache = false;
+ } else if (arg == QLatin1String("-cache")) {
+ argState = ArgCache;
+ } else if (arg == QLatin1String("-platform") || arg == QLatin1String("-spec")) {
+ argState = ArgSpec;
+ } else if (arg == QLatin1String("-xplatform") || arg == QLatin1String("-xspec")) {
+ argState = ArgXSpec;
+ } else if (arg == QLatin1String("-template") || arg == QLatin1String("-t")) {
+ argState = ArgTmpl;
+ } else if (arg == QLatin1String("-template_prefix") || arg == QLatin1String("-tp")) {
+ argState = ArgTmplPfx;
+ } else if (arg == QLatin1String("-win32")) {
+ dir_sep = QLatin1Char('\\');
+ } else if (arg == QLatin1String("-unix")) {
+ dir_sep = QLatin1Char('/');
+ } else {
+ return ArgumentUnknown;
+ }
+ } else if (arg.contains(QLatin1Char('='))) {
+ if (state.after)
+ state.postcmds << arg;
+ else
+ state.precmds << arg;
+ } else {
+ return ArgumentUnknown;
+ }
+ continue;
+ }
+ argState = ArgNone;
+ }
+ if (argState != ArgNone)
+ return ArgumentMalformed;
+ return ArgumentsOk;
+}
+
+void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state)
+{
+ if (!state.preconfigs.isEmpty())
+ state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(fL1S(" ")));
+ precmds = state.precmds.join(fL1S("\n"));
+ if (!state.postconfigs.isEmpty())
+ state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(fL1S(" ")));
+ postcmds = state.postcmds.join(fL1S("\n"));
+
+ if (xqmakespec.isEmpty())
+ xqmakespec = qmakespec;
+}
+
+void QMakeGlobals::useEnvironment()
+{
+ if (xqmakespec.isEmpty())
+ xqmakespec = getEnv(QLatin1String("XQMAKESPEC"));
+ if (qmakespec.isEmpty()) {
+ qmakespec = getEnv(QLatin1String("QMAKESPEC"));
+ if (xqmakespec.isEmpty())
+ xqmakespec = qmakespec;
+ }
+}
+
+void QMakeGlobals::setCommandLineArguments(const QString &pwd, const QStringList &_args)
+{
+ QStringList args = _args;
+
+ QMakeCmdLineParserState state(pwd);
+ for (int pos = 0; pos < args.size(); pos++)
+ addCommandLineArguments(state, args, &pos);
+ commitCommandLineArguments(state);
+ useEnvironment();
+}
+
+void QMakeGlobals::setDirectories(const QString &input_dir, const QString &output_dir)
+{
+ if (input_dir != output_dir && !output_dir.isEmpty()) {
+ QString srcpath = input_dir;
+ if (!srcpath.endsWith(QLatin1Char('/')))
+ srcpath += QLatin1Char('/');
+ QString dstpath = output_dir;
+ if (!dstpath.endsWith(QLatin1Char('/')))
+ dstpath += QLatin1Char('/');
+ int srcLen = srcpath.length();
+ int dstLen = dstpath.length();
+ int lastSl = -1;
+ while (++lastSl, srcpath.at(--srcLen) == dstpath.at(--dstLen))
+ if (srcpath.at(srcLen) == QLatin1Char('/'))
+ lastSl = 0;
+ source_root = srcpath.left(srcLen + lastSl);
+ build_root = dstpath.left(dstLen + lastSl);
+ }
+}
+
+QString QMakeGlobals::shadowedPath(const QString &fileName) const
+{
+ if (source_root.isEmpty())
+ return fileName;
+ if (fileName.startsWith(source_root)
+ && (fileName.length() == source_root.length()
+ || fileName.at(source_root.length()) == QLatin1Char('/'))) {
+ return build_root + fileName.mid(source_root.length());
+ }
+ return QString();
+}
+
+QString QMakeGlobals::getEnv(const QString &var) const
+{
+#ifdef PROEVALUATOR_SETENV
+ return environment.value(var);
+#else
+ return QString::fromLocal8Bit(qgetenv(var.toLocal8Bit().constData()));
+#endif
+}
+
+QStringList QMakeGlobals::getPathListEnv(const QString &var) const
+{
+ QStringList ret;
+ QString val = getEnv(var);
+ if (!val.isEmpty()) {
+ QDir bdir;
+ QStringList vals = val.split(dirlist_sep);
+ ret.reserve(vals.length());
+ foreach (const QString &it, vals)
+ ret << QDir::cleanPath(bdir.absoluteFilePath(it));
+ }
+ return ret;
+}
+
+QString QMakeGlobals::expandEnvVars(const QString &str) const
+{
+ QString string = str;
+ int rep;
+ QRegExp reg_variableName = statics.reg_variableName; // Copy for thread safety
+ while ((rep = reg_variableName.indexIn(string)) != -1)
+ string.replace(rep, reg_variableName.matchedLength(),
+ getEnv(string.mid(rep + 2, reg_variableName.matchedLength() - 3)));
+ return string;
+}
+
+#ifndef QT_BUILD_QMAKE
+#ifdef PROEVALUATOR_INIT_PROPS
+bool QMakeGlobals::initProperties()
+{
+ QByteArray data;
+#ifndef QT_BOOTSTRAPPED
+ QProcess proc;
+ proc.start(qmake_abslocation, QStringList() << QLatin1String("-query"));
+ if (!proc.waitForFinished())
+ return false;
+ data = proc.readAll();
+#else
+ if (FILE *proc = QT_POPEN(QString(IoUtils::shellQuote(qmake_abslocation) + QLatin1String(" -query"))
+ .toLocal8Bit(), "r")) {
+ char buff[1024];
+ while (!feof(proc))
+ data.append(buff, int(fread(buff, 1, 1023, proc)));
+ QT_PCLOSE(proc);
+ }
+#endif
+ foreach (QByteArray line, data.split('\n'))
+ if (!line.startsWith("QMAKE_")) {
+ int off = line.indexOf(':');
+ if (off < 0) // huh?
+ continue;
+ if (line.endsWith('\r'))
+ line.chop(1);
+ QString name = QString::fromLatin1(line.left(off));
+ ProString value = ProString(QDir::fromNativeSeparators(
+ QString::fromLocal8Bit(line.mid(off + 1))));
+ properties.insert(ProKey(name), value);
+ if (name.startsWith(QLatin1String("QT_")) && !name.contains(QLatin1Char('/'))) {
+ if (name.startsWith(QLatin1String("QT_INSTALL_"))) {
+ properties.insert(ProKey(name + QLatin1String("/raw")), value);
+ properties.insert(ProKey(name + QLatin1String("/get")), value);
+ if (name == QLatin1String("QT_INSTALL_PREFIX")
+ || name == QLatin1String("QT_INSTALL_DATA")
+ || name == QLatin1String("QT_INSTALL_BINS")) {
+ name.replace(3, 7, QLatin1String("HOST"));
+ properties.insert(ProKey(name), value);
+ properties.insert(ProKey(name + QLatin1String("/get")), value);
+ }
+ } else if (name.startsWith(QLatin1String("QT_HOST_"))) {
+ properties.insert(ProKey(name + QLatin1String("/get")), value);
+ }
+ }
+ }
+ properties.insert(ProKey("QMAKE_VERSION"), ProString("2.01a"));
+ return true;
+}
+#else
+void QMakeGlobals::setProperties(const QHash<QString, QString> &props)
+{
+ QHash<QString, QString>::ConstIterator it = props.constBegin(), eit = props.constEnd();
+ for (; it != eit; ++it)
+ properties.insert(ProKey(it.key()), ProString(it.value()));
+}
+#endif
+#endif // QT_BUILD_QMAKE
+
+QT_END_NAMESPACE