summaryrefslogtreecommitdiffstats
path: root/qmake
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-11-04 20:18:14 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2015-11-04 20:18:14 +0100
commit4159ee840549df11287294f0928e90f35f3e06ff (patch)
tree4a3947e37d54bdb78b4042e9ced20dbf181b5a2c /qmake
parent59dbf1786f22ec4ac88d8f9d38cac5cfb82acaea (diff)
parentc8c39ecc37c156ac2677de09a26548dfc274b564 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: config.tests/unix/ptrsize.test configure src/corelib/global/qnamespace.h src/network/socket/qabstractsocket.cpp tests/auto/other/networkselftest/networkselftest.pro Change-Id: Ic78abb4a34f9068567cea876861d4220f5a07672
Diffstat (limited to 'qmake')
-rw-r--r--qmake/doc/src/qmake-manual.qdoc22
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp2
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp13
-rw-r--r--qmake/library/ioutils.cpp4
-rw-r--r--qmake/library/proitems.cpp4
-rw-r--r--qmake/library/proitems.h1
-rw-r--r--qmake/library/qmakebuiltins.cpp10
-rw-r--r--qmake/library/qmakeevaluator.cpp37
-rw-r--r--qmake/library/qmakeglobals.cpp50
-rw-r--r--qmake/library/qmakeparser.cpp25
10 files changed, 103 insertions, 65 deletions
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index a37f19718b..ff7b7fe1da 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -3965,25 +3965,27 @@
\list 1
\li In a directory listed in the \c QMAKEFEATURES environment variable that
- contains a colon-separated list of directories.
+ contains a list of directories delimited by the platform's path list separator
+ (colon for Unix, semicolon for Windows).
\li In a directory listed in the \c QMAKEFEATURES property variable that
- contains a colon-spearated list of directories.
+ contains a list of directories delimited by the platform's path list separator.
\omit
\li In a features directory beneath the project's root directory (where
- the \c{.qmake.cache} file is generated).
+ the \c{.qmake.cache} file is generated).
\endomit
\li In a features directory residing within a \c mkspecs directory.
- \c mkspecs directories can be located beneath any of the directories
- listed in the \c QMAKEPATH environment variable that contains a
- colon-separated list of directories. For example:
+ \c mkspecs directories can be located beneath any of the directories
+ listed in the \c QMAKEPATH environment variable that contains a
+ list of directories delimited by the platform's path list separator.
+ For example:
\c{$QMAKEPATH/mkspecs/<features>}.
\li In a features directory residing beneath the directory provided by the
- \l{QMAKESPEC} environment variable. For example: \c{$QMAKESPEC/<features>}.
+ \l{QMAKESPEC} environment variable. For example: \c{$QMAKESPEC/<features>}.
\li In a features directory residing in the \c data_install/mkspecs directory.
- For example: \c{data_install/mkspecs/<features>}.
+ For example: \c{data_install/mkspecs/<features>}.
\li In a features directory that exists as a sibling of the directory
- specified by the \c QMAKESPEC environment variable.
- For example: \c{$QMAKESPEC/../<features>}.
+ specified by the \c QMAKESPEC environment variable.
+ For example: \c{$QMAKESPEC/../<features>}.
\endlist
The following features directories are searched for features files:
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 11e93e54c2..339dae953a 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -922,6 +922,8 @@ bool VCCLCompilerTool::parseOption(const char* option)
TreatWChar_tAsBuiltInType = ((*c) == '-' ? _False : _True);
else if (config->CompilerVersion >= NET2013 && strncmp(option + 4, "strictStrings", 13) == 0)
AdditionalOptions += option;
+ else if (config->CompilerVersion >= NET2015 && strncmp(option + 4, "throwingNew", 11) == 0)
+ AdditionalOptions += option;
else
found = false;
} else {
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index b1e0745e03..47f99a5c8e 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -1207,12 +1207,13 @@ void VcprojGenerator::initLinkerTool()
if (!project->values("DEF_FILE").isEmpty())
conf.linker.ModuleDefinitionFile = project->first("DEF_FILE").toQString();
- foreach (const ProString &libs, project->values("QMAKE_LIBS") + project->values("QMAKE_LIBS_PRIVATE")) {
- if (libs.left(9).toQString().toUpper() == "/LIBPATH:") {
- ProStringList l = ProStringList(libs);
- conf.linker.parseOptions(l);
- } else {
- conf.linker.AdditionalDependencies << escapeFilePath(libs.toQString());
+ static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
+ for (int i = 0; lflags[i]; i++) {
+ foreach (const ProString &lib, fixLibFlags(lflags[i])) {
+ if (lib.startsWith("/LIBPATH:"))
+ conf.linker.AdditionalLibraryDirectories << lib.mid(9).toQString();
+ else
+ conf.linker.AdditionalDependencies << lib.toQString();
}
}
diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp
index 04be215246..a2f3e8ec3d 100644
--- a/qmake/library/ioutils.cpp
+++ b/qmake/library/ioutils.cpp
@@ -68,6 +68,10 @@ bool IoUtils::isRelativePath(const QString &path)
{
if (path.startsWith(QLatin1Char('/')))
return false;
+#ifdef QMAKE_BUILTIN_PRFS
+ if (path.startsWith(QLatin1String(":/")))
+ return false;
+#endif
#ifdef Q_OS_WIN
if (path.startsWith(QLatin1Char('\\')))
return false;
diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp
index a610da6b69..5fb70df3b1 100644
--- a/qmake/library/proitems.cpp
+++ b/qmake/library/proitems.cpp
@@ -212,11 +212,7 @@ ProString &ProString::prepend(const ProString &other)
ProString &ProString::append(const QLatin1String other)
{
const char *latin1 = other.latin1();
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
int size = other.size();
-#else
- int size = strlen(latin1);
-#endif
if (size) {
QChar *ptr = prepareExtend(size, 0, m_length);
for (int i = 0; i < size; i++)
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 9430d28521..e4ef1d1586 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -342,6 +342,7 @@ public:
const QString &items() const { return m_proitems; }
QString *itemsRef() { return &m_proitems; }
const ushort *tokPtr() const { return (const ushort *)m_proitems.constData(); }
+ const ushort *tokPtrEnd() const { return (const ushort *)m_proitems.constData() + m_proitems.size(); }
void ref() { m_refCount.ref(); }
void deref() { if (!m_refCount.deref()) delete this; }
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 02d5d5dd31..f57d9c89a7 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -514,7 +514,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
QString tmp = args.at(0).toQString(m_tmp1);
for (int i = 1; i < args.count(); ++i)
tmp = tmp.arg(args.at(i).toQString(m_tmp2));
- ret << ProString(tmp);
+ ret << (tmp.isSharedWith(m_tmp1) ? args.at(0) : ProString(tmp).setSource(args.at(0)));
}
break;
case E_FORMAT_NUMBER:
@@ -1387,6 +1387,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
QString parseInto;
LoadFlags flags = 0;
+ if (m_cumulative)
+ flags = LoadSilent;
if (args.count() >= 2) {
parseInto = args.at(1).toQString(m_tmp2);
if (args.count() >= 3 && isTrue(args.at(2), m_tmp3))
@@ -1549,12 +1551,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (args.count() >= 2) {
const ProStringList &vals = values(args.at(1).toKey());
if (!vals.isEmpty())
- contents = vals.join(fL1S("\n")) + QLatin1Char('\n');
+ contents = vals.join(QLatin1Char('\n')) + QLatin1Char('\n');
if (args.count() >= 3)
if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive))
mode = QIODevice::Append;
}
- return writeFile(QString(), resolvePath(args.at(0).toQString(m_tmp1)), mode, contents);
+ QString path = resolvePath(args.at(0).toQString(m_tmp1));
+ path.detach(); // make sure to not leak m_tmp1 into the map of written files.
+ return writeFile(QString(), path, mode, contents);
}
case T_TOUCH: {
if (args.count() != 2) {
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 31be44eda7..d7fba6b227 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -452,7 +452,7 @@ void QMakeEvaluator::evaluateExpression(
break; }
case TokEnvVar: {
const ProString &var = pro->getStr(tokPtr);
- const ProString &val = ProString(m_option->getEnv(var.toQString(m_tmp1)));
+ const ProString &val = ProString(m_option->getEnv(var.toQString()));
debugMsg(2, "env var %s => %s", dbgStr(var), dbgStr(val));
addStr(val, ret, pending, joined);
break; }
@@ -575,13 +575,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
okey = true, or_op = false; // force next evaluation
break;
case TokForLoop:
- if (m_cumulative) { // This is a no-win situation, so just pretend it's no loop
- skipHashStr(tokPtr);
- uint exprLen = getBlockLen(tokPtr);
- tokPtr += exprLen;
- blockLen = getBlockLen(tokPtr);
- ret = visitProBlock(tokPtr);
- } else if (okey != or_op) {
+ if (m_cumulative || okey != or_op) {
const ProKey &variable = pro->getHashStr(tokPtr);
uint exprLen = getBlockLen(tokPtr);
const ushort *exprPtr = tokPtr;
@@ -751,6 +745,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
ProStringList list = values(it_list.toKey());
if (list.isEmpty()) {
if (it_list == statics.strforever) {
+ if (m_cumulative) {
+ // The termination conditions wouldn't be evaluated, so we must skip it.
+ traceMsg("skipping forever loop in cumulative mode");
+ return ReturnFalse;
+ }
infinite = true;
} else {
const QString &itl = it_list.toQString(m_tmp1);
@@ -761,6 +760,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
if (ok) {
int end = itl.mid(dotdot+2).toInt(&ok);
if (ok) {
+ if (m_cumulative && qAbs(end - start) > 100) {
+ // Such a loop is unlikely to contribute something useful to the
+ // file collection, and may cause considerable delay.
+ traceMsg("skipping excessive loop in cumulative mode");
+ return ReturnFalse;
+ }
if (start < end) {
for (int i = start; i <= end; i++)
list << ProString(QString::number(i));
@@ -907,8 +912,11 @@ void QMakeEvaluator::visitProVariable(
m_featureRoots = 0;
else if (varName == statics.strQMAKESPEC) {
if (!values(varName).isEmpty()) {
- m_qmakespec = values(varName).first().toQString();
- m_featureRoots = 0;
+ QString spec = values(varName).first().toQString();
+ if (IoUtils::isAbsolutePath(spec)) {
+ m_qmakespec = spec;
+ m_featureRoots = 0;
+ }
}
}
#ifdef PROEVALUATOR_FULL
@@ -1156,8 +1164,11 @@ bool QMakeEvaluator::loadSpecInternal()
// the source of the qmake.conf at the end of the default/qmake.conf in
// the QMAKESPEC_ORIGINAL variable.
const ProString &orig_spec = first(ProKey("QMAKESPEC_ORIGINAL"));
- if (!orig_spec.isEmpty())
- m_qmakespec = orig_spec.toQString();
+ if (!orig_spec.isEmpty()) {
+ QString spec = orig_spec.toQString();
+ if (IoUtils::isAbsolutePath(spec))
+ m_qmakespec = spec;
+ }
# endif
#endif
valuesRef(ProKey("QMAKESPEC")) = ProString(m_qmakespec);
@@ -1912,7 +1923,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
}
#ifdef QMAKE_BUILTIN_PRFS
fn.prepend(QLatin1String(":/qmake/features/"));
- if (QFileInfo(fn).exists())
+ if (QFileInfo::exists(fn))
goto cool;
#endif
fn = QLatin1String(""); // Indicate failed lookup. See comment above.
diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp
index 4f1a9d2a55..ff59bdb303 100644
--- a/qmake/library/qmakeglobals.cpp
+++ b/qmake/library/qmakeglobals.cpp
@@ -74,27 +74,8 @@ 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
@@ -202,11 +183,11 @@ QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments(
void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state)
{
if (!state.preconfigs.isEmpty())
- state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(fL1S(" ")));
- precmds = state.precmds.join(fL1S("\n"));
+ state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(QLatin1Char(' ')));
+ precmds = state.precmds.join(QLatin1Char('\n'));
if (!state.postconfigs.isEmpty())
- state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(fL1S(" ")));
- postcmds = state.postcmds.join(fL1S("\n"));
+ state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(QLatin1Char(' ')));
+ postcmds = state.postcmds.join(QLatin1Char('\n'));
if (xqmakespec.isEmpty())
xqmakespec = qmakespec;
@@ -297,11 +278,24 @@ QStringList QMakeGlobals::getPathListEnv(const QString &var) const
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)));
+ int startIndex = 0;
+ forever {
+ startIndex = string.indexOf(QLatin1Char('$'), startIndex);
+ if (startIndex < 0)
+ break;
+ if (string.length() < startIndex + 3)
+ break;
+ if (string.at(startIndex + 1) != QLatin1Char('(')) {
+ startIndex++;
+ continue;
+ }
+ int endIndex = string.indexOf(QLatin1Char(')'), startIndex + 2);
+ if (endIndex < 0)
+ break;
+ QString value = getEnv(string.mid(startIndex + 2, endIndex - startIndex - 2));
+ string.replace(startIndex, endIndex - startIndex + 1, value);
+ startIndex += value.length();
+ }
return string;
}
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 3fd7957bc0..95a072392e 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -64,6 +64,18 @@ void ProFileCache::discardFile(const QString &fileName)
#endif
QHash<QString, Entry>::Iterator it = parsed_files.find(fileName);
if (it != parsed_files.end()) {
+#ifdef PROPARSER_THREAD_SAFE
+ if (it->locker) {
+ if (!it->locker->done) {
+ ++it->locker->waiters;
+ it->locker->cond.wait(&mutex);
+ if (!--it->locker->waiters) {
+ delete it->locker;
+ it->locker = 0;
+ }
+ }
+ }
+#endif
if (it->pro)
it->pro->deref();
parsed_files.erase(it);
@@ -80,6 +92,18 @@ void ProFileCache::discardFiles(const QString &prefix)
end = parsed_files.end();
while (it != end)
if (it.key().startsWith(prefix)) {
+#ifdef PROPARSER_THREAD_SAFE
+ if (it->locker) {
+ if (!it->locker->done) {
+ ++it->locker->waiters;
+ it->locker->cond.wait(&mutex);
+ if (!--it->locker->waiters) {
+ delete it->locker;
+ it->locker = 0;
+ }
+ }
+ }
+#endif
if (it->pro)
it->pro->deref();
it = parsed_files.erase(it);
@@ -88,7 +112,6 @@ void ProFileCache::discardFiles(const QString &prefix)
}
}
-
////////// Parser ///////////
#define fL1S(s) QString::fromLatin1(s)