forked from qt-creator/qt-creator
add cache() function
follow suit with qmake ... Change-Id: I8be9b0ecdc45c6358fe00d03ea5d9e77c631c3bb Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
This commit is contained in:
@@ -90,7 +90,7 @@ enum TestFunc {
|
||||
T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
|
||||
T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE,
|
||||
T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF,
|
||||
T_MKPATH, T_WRITE_FILE, T_TOUCH
|
||||
T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE
|
||||
};
|
||||
|
||||
void QMakeEvaluator::initFunctionStatics()
|
||||
@@ -178,6 +178,7 @@ void QMakeEvaluator::initFunctionStatics()
|
||||
{ "mkpath", T_MKPATH },
|
||||
{ "write_file", T_WRITE_FILE },
|
||||
{ "touch", T_TOUCH },
|
||||
{ "cache", T_CACHE },
|
||||
};
|
||||
for (unsigned i = 0; i < sizeof(testInits)/sizeof(testInits[0]); ++i)
|
||||
statics.functions.insert(ProString(testInits[i].name), testInits[i].func);
|
||||
@@ -1525,6 +1526,137 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
|
||||
#endif
|
||||
return ReturnTrue;
|
||||
}
|
||||
case T_CACHE: {
|
||||
if (args.count() > 3) {
|
||||
evalError(fL1S("cache(var, [set|add|sub] [transient] [super], [srcvar]) requires one to three arguments."));
|
||||
return ReturnFalse;
|
||||
}
|
||||
bool persist = true;
|
||||
bool super = false;
|
||||
enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet;
|
||||
ProString srcvar;
|
||||
if (args.count() >= 2) {
|
||||
foreach (const ProString &opt, split_value_list(args.at(1).toQString(m_tmp2))) {
|
||||
opt.toQString(m_tmp3);
|
||||
if (m_tmp3 == QLatin1String("transient")) {
|
||||
persist = false;
|
||||
} else if (m_tmp3 == QLatin1String("super")) {
|
||||
super = true;
|
||||
} else if (m_tmp3 == QLatin1String("set")) {
|
||||
mode = CacheSet;
|
||||
} else if (m_tmp3 == QLatin1String("add")) {
|
||||
mode = CacheAdd;
|
||||
} else if (m_tmp3 == QLatin1String("sub")) {
|
||||
mode = CacheSub;
|
||||
} else {
|
||||
evalError(fL1S("cache(): invalid flag %1.").arg(m_tmp3));
|
||||
return ReturnFalse;
|
||||
}
|
||||
}
|
||||
if (args.count() >= 3) {
|
||||
srcvar = args.at(2);
|
||||
} else if (mode != CacheSet) {
|
||||
evalError(fL1S("cache(): modes other than 'set' require a source variable."));
|
||||
return ReturnFalse;
|
||||
}
|
||||
}
|
||||
QString varstr;
|
||||
ProString dstvar = args.at(0);
|
||||
if (!dstvar.isEmpty()) {
|
||||
if (srcvar.isEmpty())
|
||||
srcvar = dstvar;
|
||||
ProValueMap::Iterator srcvarIt;
|
||||
if (!findValues(srcvar, &srcvarIt)) {
|
||||
evalError(fL1S("Variable %1 is not defined.").arg(srcvar.toQString(m_tmp1)));
|
||||
return ReturnFalse;
|
||||
}
|
||||
// The caches for the host and target may differ (e.g., when we are manipulating
|
||||
// CONFIG), so we cannot compute a common new value for both.
|
||||
const ProStringList &diffval = *srcvarIt;
|
||||
ProStringList newval;
|
||||
bool changed = false;
|
||||
for (bool hostBuild = false; ; hostBuild = true) {
|
||||
if (QMakeBaseEnv *baseEnv = m_option->baseEnvs.value(
|
||||
QMakeBaseKey(m_buildRoot, hostBuild))) {
|
||||
QMakeEvaluator *baseEval = baseEnv->evaluator;
|
||||
const ProStringList &oldval = baseEval->values(dstvar);
|
||||
if (mode == CacheSet) {
|
||||
newval = diffval;
|
||||
} else {
|
||||
newval = oldval;
|
||||
if (mode == CacheAdd)
|
||||
newval += diffval;
|
||||
else
|
||||
removeEach(&newval, diffval);
|
||||
}
|
||||
if (oldval != newval) {
|
||||
baseEval->valuesRef(dstvar) = newval;
|
||||
if (super) {
|
||||
do {
|
||||
if (dstvar == QLatin1String("QMAKEPATH")) {
|
||||
baseEval->m_qmakepath = newval.toQStringList();
|
||||
baseEval->updateMkspecPaths();
|
||||
} else if (dstvar == QLatin1String("QMAKEFEATURES")) {
|
||||
baseEval->m_qmakefeatures = newval.toQStringList();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
baseEval->updateFeaturePaths();
|
||||
if (hostBuild == m_hostBuild)
|
||||
m_featureRoots = baseEval->m_featureRoots;
|
||||
} while (false);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (hostBuild)
|
||||
break;
|
||||
}
|
||||
// We assume that whatever got the cached value to be what it is now will do so
|
||||
// the next time as well, so we just skip the persisting if nothing changed.
|
||||
if (!persist || !changed)
|
||||
return ReturnTrue;
|
||||
varstr = dstvar.toQString();
|
||||
if (mode == CacheAdd)
|
||||
varstr += QLatin1String(" +=");
|
||||
else if (mode == CacheSub)
|
||||
varstr += QLatin1String(" -=");
|
||||
else
|
||||
varstr += QLatin1String(" =");
|
||||
if (diffval.count() == 1) {
|
||||
varstr += QLatin1Char(' ');
|
||||
varstr += quoteValue(diffval.at(0));
|
||||
} else if (!diffval.isEmpty()) {
|
||||
foreach (const ProString &vval, diffval) {
|
||||
varstr += QLatin1String(" \\\n ");
|
||||
varstr += quoteValue(vval);
|
||||
}
|
||||
}
|
||||
varstr += QLatin1Char('\n');
|
||||
}
|
||||
QString fn;
|
||||
if (super) {
|
||||
if (m_superfile.isEmpty()) {
|
||||
m_superfile = m_outputDir + QLatin1String("/.qmake.super");
|
||||
printf("Info: creating super cache file %s\n", qPrintable(m_superfile));
|
||||
valuesRef(ProString("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile, NoHash);
|
||||
}
|
||||
fn = m_superfile;
|
||||
} else {
|
||||
if (m_cachefile.isEmpty()) {
|
||||
m_cachefile = m_outputDir + QLatin1String("/.qmake.cache");
|
||||
printf("Info: creating cache file %s\n", qPrintable(m_cachefile));
|
||||
valuesRef(ProString("_QMAKE_CACHE_")) << ProString(m_cachefile, NoHash);
|
||||
// We could update m_{source,build}Root and m_featureRoots here, or even
|
||||
// "re-home" our rootEnv, but this doesn't sound too useful - if somebody
|
||||
// wanted qmake to find something in the build directory, he could have
|
||||
// done so "from the outside".
|
||||
// The sub-projects will find the new cache all by themselves.
|
||||
}
|
||||
fn = m_cachefile;
|
||||
}
|
||||
return writeFile(fL1S("cache "), fn, QIODevice::Append, varstr);
|
||||
}
|
||||
#endif
|
||||
case T_INVALID:
|
||||
evalError(fL1S("'%1' is not a recognized test function.")
|
||||
|
||||
Reference in New Issue
Block a user