summaryrefslogtreecommitdiffstats
path: root/qmake/library/qmakeevaluator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/library/qmakeevaluator.cpp')
-rw-r--r--qmake/library/qmakeevaluator.cpp83
1 files changed, 56 insertions, 27 deletions
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 09ea231684..0cb053e566 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -936,7 +936,7 @@ void QMakeEvaluator::visitProVariable(
if (varName == statics.strTEMPLATE)
setTemplate();
else if (varName == statics.strQMAKE_PLATFORM)
- updateFeaturePaths();
+ m_featureRoots = 0;
#ifdef PROEVALUATOR_FULL
else if (varName == statics.strREQUIRES)
checkRequirements(values(varName));
@@ -1160,6 +1160,7 @@ bool QMakeEvaluator::loadSpecInternal()
#endif
valuesRef(ProKey("QMAKESPEC")) << ProString(m_qmakespec);
m_qmakespecName = IoUtils::fileName(m_qmakespec).toString();
+ // This also ensures that m_featureRoots is valid.
if (evaluateFeatureFile(QLatin1String("spec_post.prf")) != ReturnTrue)
return false;
// The MinGW and x-build specs may change the separator; $$shell_{path,quote}() need it
@@ -1174,6 +1175,8 @@ bool QMakeEvaluator::loadSpec()
{
QMakeEvaluator evaluator(m_option, m_parser, m_handler);
+ evaluator.m_sourceRoot = m_sourceRoot;
+ evaluator.m_buildRoot = m_buildRoot;
if (!m_superfile.isEmpty()) {
valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
if (evaluator.evaluateFile(
@@ -1429,6 +1432,7 @@ void QMakeEvaluator::updateMkspecPaths()
ret << m_sourceRoot + concat;
ret << m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + concat;
+ ret << m_option->propertyValue(ProKey("QT_HOST_DATA/src")) + concat;
ret.removeDuplicates();
m_mkspecPaths = ret;
@@ -1450,10 +1454,14 @@ void QMakeEvaluator::updateFeaturePaths()
m_option->dirlist_sep, QString::SkipEmptyParts);
QStringList feature_bases;
- if (!m_buildRoot.isEmpty())
+ if (!m_buildRoot.isEmpty()) {
+ feature_bases << m_buildRoot + mkspecs_concat;
feature_bases << m_buildRoot;
- if (!m_sourceRoot.isEmpty())
+ }
+ if (!m_sourceRoot.isEmpty()) {
+ feature_bases << m_sourceRoot + mkspecs_concat;
feature_bases << m_sourceRoot;
+ }
foreach (const QString &item, m_option->getPathListEnv(QLatin1String("QMAKEPATH")))
feature_bases << (item + mkspecs_concat);
@@ -1477,8 +1485,8 @@ void QMakeEvaluator::updateFeaturePaths()
}
}
- feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/get")).toQString(m_mtmp)
- + mkspecs_concat);
+ feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + mkspecs_concat);
+ feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/src")) + mkspecs_concat);
foreach (const QString &fb, feature_bases) {
foreach (const ProString &sfx, values(ProKey("QMAKE_PLATFORM")))
@@ -1496,7 +1504,7 @@ void QMakeEvaluator::updateFeaturePaths()
foreach (const QString &root, feature_roots)
if (IoUtils::exists(root))
ret << root;
- m_featureRoots = ret;
+ m_featureRoots = new QMakeFeatureRoots(ret);
}
ProString QMakeEvaluator::propertyValue(const ProKey &name) const
@@ -1854,34 +1862,55 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
if (!fn.endsWith(QLatin1String(".prf")))
fn += QLatin1String(".prf");
- if (m_featureRoots.isEmpty())
+ if (!m_featureRoots)
updateFeaturePaths();
- int start_root = 0;
+#ifdef PROEVALUATOR_THREAD_SAFE
+ m_featureRoots->mutex.lock();
+#endif
QString currFn = currentFileName();
- if (IoUtils::fileName(currFn) == IoUtils::fileName(fn)) {
- for (int root = 0; root < m_featureRoots.size(); ++root)
- if (currFn == m_featureRoots.at(root) + fn) {
- start_root = root + 1;
- break;
+ if (IoUtils::fileName(currFn) != IoUtils::fileName(fn))
+ currFn.clear();
+ // Null values cannot regularly exist in the hash, so they indicate that the value still
+ // needs to be determined. Failed lookups are represented via non-null empty strings.
+ QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)];
+ if (fnp->isNull()) {
+ int start_root = 0;
+ const QStringList &paths = m_featureRoots->paths;
+ if (!currFn.isEmpty()) {
+ QStringRef currPath = IoUtils::pathName(currFn);
+ for (int root = 0; root < paths.size(); ++root)
+ if (currPath == paths.at(root)) {
+ start_root = root + 1;
+ break;
+ }
+ }
+ for (int root = start_root; root < paths.size(); ++root) {
+ QString fname = paths.at(root) + fn;
+ if (IoUtils::exists(fname)) {
+ fn = fname;
+ goto cool;
}
- }
- for (int root = start_root; root < m_featureRoots.size(); ++root) {
- QString fname = m_featureRoots.at(root) + fn;
- if (IoUtils::exists(fname)) {
- fn = fname;
- goto cool;
}
- }
#ifdef QMAKE_BUILTIN_PRFS
- fn.prepend(QLatin1String(":/qmake/features/"));
- if (QFileInfo(fn).exists())
- goto cool;
+ fn.prepend(QLatin1String(":/qmake/features/"));
+ if (QFileInfo(fn).exists())
+ goto cool;
#endif
- if (!silent)
- evalError(fL1S("Cannot find feature %1").arg(fileName));
- return ReturnFalse;
+ fn = QLatin1String(""); // Indicate failed lookup. See comment above.
- cool:
+ cool:
+ *fnp = fn;
+ } else {
+ fn = *fnp;
+ }
+#ifdef PROEVALUATOR_THREAD_SAFE
+ m_featureRoots->mutex.unlock();
+#endif
+ if (fn.isEmpty()) {
+ if (!silent)
+ evalError(fL1S("Cannot find feature %1").arg(fileName));
+ return ReturnFalse;
+ }
ProStringList &already = valuesRef(ProKey("QMAKE_INTERNAL_INCLUDED_FEATURES"));
ProString afn(fn);
if (already.contains(afn)) {