diff options
Diffstat (limited to 'qmake/library/qmakeevaluator.cpp')
-rw-r--r-- | qmake/library/qmakeevaluator.cpp | 83 |
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)) { |