/**************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, 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, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ #include "qmakeglobals.h" #include "qmakeevaluator.h" #include "ioutils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PROEVALUATOR_THREAD_SAFE # include #endif #ifdef Q_OS_UNIX #include #include #else #include #endif #include #include #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 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); } void QMakeGlobals::setCommandLineArguments(const QStringList &args) { QStringList _precmds, _preconfigs, _postcmds, _postconfigs; bool after = false; bool isConf = false; foreach (const QString &arg, args) { if (isConf) { isConf = false; if (after) _postconfigs << arg; else _preconfigs << arg; } else if (arg.startsWith(QLatin1Char('-'))) { if (arg == QLatin1String("-after")) { after = true; } else if (arg == QLatin1String("-config")) { isConf = true; } else if (arg == QLatin1String("-win32")) { dir_sep = QLatin1Char('\\'); } else if (arg == QLatin1String("-unix")) { dir_sep = QLatin1Char('/'); } } else if (arg.contains(QLatin1Char('='))) { if (after) _postcmds << arg; else _precmds << arg; } } if (!_preconfigs.isEmpty()) _precmds << (fL1S("CONFIG += ") + _preconfigs.join(fL1S(" "))); precmds = _precmds.join(fL1S("\n")); if (!_postconfigs.isEmpty()) _postcmds << (fL1S("CONFIG += ") + _postconfigs.join(fL1S(" "))); postcmds = _postcmds.join(fL1S("\n")); } 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::getEnv(const QString &var) const { #ifndef QT_BOOTSTRAPPED if (!environment.isEmpty()) return environment.value(var); #endif return QString::fromLocal8Bit(qgetenv(var.toLocal8Bit().constData())); } 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; } #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')) { 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); } } } return true; } #else void QMakeGlobals::setProperties(const QHash &props) { QHash::ConstIterator it = props.constBegin(), eit = props.constEnd(); for (; it != eit; ++it) properties.insert(ProKey(it.key()), ProString(it.value())); } #endif QT_END_NAMESPACE