Qt4Project: Do a build_pass evaluation

Some projects set TARGET or DESTDIR only in the build_pass

Task-number: QTCREATORBUG-4273

Change-Id: I3673dd93b37b10102a0c1f1ce053e1aef8aaf53f
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
This commit is contained in:
Daniel Teske
2012-10-23 17:40:10 +02:00
parent 0b9ce52904
commit 95169eb8e3
7 changed files with 78 additions and 45 deletions

View File

@@ -2112,24 +2112,65 @@ TargetInformation Qt4ProFileNode::targetInformation(QtSupport::ProFileReader *re
if (!reader) if (!reader)
return result; return result;
QtSupport::ProFileReader *readerBP = 0;
QStringList builds = reader->values("BUILDS");
QString buildTarget;
if (!builds.isEmpty()) {
QString build = builds.first();
buildTarget = reader->value(build + ".target");
QHash<QString, QStringList> basevars;
QStringList basecfgs = reader->values(build + QLatin1String(".CONFIG"));
basecfgs += build;
basecfgs += "build_pass";
basevars["BUILD_PASS"] = QStringList(build);
QStringList buildname = reader->values(build + QLatin1String(".name"));
basevars["BUILD_NAME"] = (buildname.isEmpty() ? QStringList(build) : buildname);
readerBP = m_project->createProFileReader(this);
readerBP->setExtraVars(basevars);
readerBP->setExtraConfigs(basecfgs);
EvalResult evalResult = EvalOk;
if (ProFile *pro = readerBP->parsedProFile(m_projectFilePath)) {
if (!readerBP->accept(pro, QMakeEvaluator::LoadAll))
evalResult = EvalPartial;
pro->deref();
} else {
evalResult = EvalFail;
}
if (evalResult != EvalOk)
return result;
reader = readerBP;
}
// BUILD DIR
result.buildDir = buildDir(); result.buildDir = buildDir();
const QString baseDir = result.buildDir; const QString baseDir = result.buildDir;
// qDebug() << "base build dir is:"<<baseDir; // qDebug() << "base build dir is:"<<baseDir;
// Working Directory QString destDir;
const QString destDir = QLatin1String("DESTDIR"); if (reader->contains(QLatin1String("DESTDIR"))) {
if (reader->contains(destDir)) { destDir = reader->value(QLatin1String("DESTDIR"));
//qDebug() << "reader contains destdir:" << reader->value("DESTDIR"); bool workingDirIsBaseDir = false;
result.workingDir = reader->value(destDir); if (destDir == buildTarget) // special case for "debug" or "release"
if (QDir::isRelativePath(result.workingDir)) { workingDirIsBaseDir = true;
result.workingDir = baseDir + QLatin1Char('/') + result.workingDir;
//qDebug() << "was relative and expanded to" << result.workingDir; if (QDir::isRelativePath(destDir))
} destDir = baseDir + QLatin1Char('/') + destDir;
if (workingDirIsBaseDir)
result.workingDir = baseDir;
else
result.workingDir = destDir;
} else { } else {
//qDebug() << "reader didn't contain DESTDIR, setting to " << baseDir; destDir = baseDir;
result.workingDir = baseDir; result.workingDir = baseDir;
} }
// Target
result.target = reader->value(QLatin1String("TARGET")); result.target = reader->value(QLatin1String("TARGET"));
if (result.target.isEmpty()) if (result.target.isEmpty())
result.target = QFileInfo(m_projectFilePath).baseName(); result.target = QFileInfo(m_projectFilePath).baseName();
@@ -2143,31 +2184,16 @@ TargetInformation Qt4ProFileNode::targetInformation(QtSupport::ProFileReader *re
result.workingDir = QDir::cleanPath(result.workingDir); result.workingDir = QDir::cleanPath(result.workingDir);
QString wd = result.workingDir; /// should this really be in this method?
if ( (!reader->contains(destDir) || reader->value(destDir) == QLatin1String("."))) { result.executable = QDir::cleanPath(destDir + QLatin1Char('/') + result.target);
const QStringList configValues = reader->values(QLatin1String("CONFIG"));
if (configValues.contains(QLatin1String("debug_and_release"))
&& configValues.contains(QLatin1String("debug_and_release_target"))) {
// If we don't have a destdir and debug and release is set
// then the executable is in a debug/release folder
//qDebug() << "reader has debug_and_release_target";
// Hmm can we find out whether it's debug or release in a saner way?
// Theoretically it's in CONFIG
QString qmakeBuildConfig = QLatin1String("release");
ProjectExplorer::Target *target = m_project->activeTarget();
Qt4BuildConfiguration *bc = target ? qobject_cast<Qt4BuildConfiguration *>(target->activeBuildConfiguration()) : 0;
if (!target || !bc || bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild)
qmakeBuildConfig = QLatin1String("debug");
wd += QLatin1Char('/') + qmakeBuildConfig;
}
}
result.executable = QDir::cleanPath(wd + QLatin1Char('/') + result.target);
//qDebug() << "##### updateTarget sets:" << result.workingDir << result.executable; //qDebug() << "##### updateTarget sets:" << result.workingDir << result.executable;
Utils::HostOsInfo::appendExecutableSuffix(result.executable); Utils::HostOsInfo::appendExecutableSuffix(result.executable);
result.valid = true; result.valid = true;
if (readerBP)
m_project->destroyProFileReader(readerBP);
return result; return result;
} }

View File

@@ -959,7 +959,7 @@ void Qt4Project::proFileParseError(const QString &errorMessage)
Core::ICore::messageManager()->printToOutputPanePopup(errorMessage); Core::ICore::messageManager()->printToOutputPanePopup(errorMessage);
} }
QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc) QtSupport::ProFileReader *Qt4Project::createProFileReader(const Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc)
{ {
if (!m_qmakeGlobals) { if (!m_qmakeGlobals) {
m_qmakeGlobals = new ProFileGlobals; m_qmakeGlobals = new ProFileGlobals;

View File

@@ -102,7 +102,7 @@ public:
void notifyChanged(const QString &name); void notifyChanged(const QString &name);
/// \internal /// \internal
QtSupport::ProFileReader *createProFileReader(Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc = 0); QtSupport::ProFileReader *createProFileReader(const Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc = 0);
/// \internal /// \internal
ProFileGlobals *qmakeGlobals(); ProFileGlobals *qmakeGlobals();
/// \internal /// \internal

View File

@@ -215,6 +215,21 @@ void ProFileEvaluator::setCumulative(bool on)
} }
#endif #endif
void ProFileEvaluator::setExtraVars(const QHash<QString, QStringList> &extraVars)
{
ProValueMap map;
QHash<QString, QStringList>::const_iterator it = extraVars.constBegin();
QHash<QString, QStringList>::const_iterator end = extraVars.constEnd();
for ( ; it != end; ++it)
map.insert(ProKey(it.key()), ProStringList(it.value()));
d->setExtraVars(map);
}
void ProFileEvaluator::setExtraConfigs(const QStringList &extraConfigs)
{
d->setExtraConfigs(ProStringList(extraConfigs));
}
void ProFileEvaluator::setOutputDir(const QString &dir) void ProFileEvaluator::setOutputDir(const QString &dir)
{ {
d->m_outputDir = dir; d->m_outputDir = dir;

View File

@@ -72,6 +72,8 @@ public:
#ifdef PROEVALUATOR_CUMULATIVE #ifdef PROEVALUATOR_CUMULATIVE
void setCumulative(bool on); // Default is false void setCumulative(bool on); // Default is false
#endif #endif
void setExtraVars(const QHash<QString, QStringList> &extraVars);
void setExtraConfigs(const QStringList &extraConfigs);
void setOutputDir(const QString &dir); // Default is empty void setOutputDir(const QString &dir); // Default is empty
bool loadNamedSpec(const QString &specDir, bool hostSpec); bool loadNamedSpec(const QString &specDir, bool hostSpec);

View File

@@ -1316,11 +1316,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
loadDefaults(); loadDefaults();
} }
#ifdef QT_BUILD_QMAKE
for (ProValueMap::ConstIterator it = m_extraVars.constBegin(); for (ProValueMap::ConstIterator it = m_extraVars.constBegin();
it != m_extraVars.constEnd(); ++it) it != m_extraVars.constEnd(); ++it)
m_valuemapStack.first().insert(it.key(), it.value()); m_valuemapStack.first().insert(it.key(), it.value());
#endif
m_handler->aboutToEval(currentProFile(), pro, type); m_handler->aboutToEval(currentProFile(), pro, type);
m_profileStack.push(pro); m_profileStack.push(pro);
@@ -1332,11 +1330,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
evaluateCommand(m_option->precmds, fL1S("(command line)")); evaluateCommand(m_option->precmds, fL1S("(command line)"));
#ifdef QT_BUILD_QMAKE
// After user configs, to override them // After user configs, to override them
if (!m_extraConfigs.isEmpty()) if (!m_extraConfigs.isEmpty())
evaluateCommand("CONFIG += " + m_extraConfigs.join(" "), fL1S("(extra configs)")); evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(fL1S(" ")), fL1S("(extra configs)"));
#endif
} }
debugMsg(1, "visiting file %s", qPrintable(pro->fileName())); debugMsg(1, "visiting file %s", qPrintable(pro->fileName()));
@@ -1346,13 +1342,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
if (flags & LoadPostFiles) { if (flags & LoadPostFiles) {
evaluateCommand(m_option->postcmds, fL1S("(command line -after)")); evaluateCommand(m_option->postcmds, fL1S("(command line -after)"));
#ifdef QT_BUILD_QMAKE
// Again, to ensure the project does not mess with us. // Again, to ensure the project does not mess with us.
// Specifically, do not allow a project to override debug/release within a // Specifically, do not allow a project to override debug/release within a
// debug_and_release build pass - it's too late for that at this point anyway. // debug_and_release build pass - it's too late for that at this point anyway.
if (!m_extraConfigs.isEmpty()) if (!m_extraConfigs.isEmpty())
evaluateCommand("CONFIG += " + m_extraConfigs.join(" "), fL1S("(extra configs)")); evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(fL1S(" ")), fL1S("(extra configs)"));
#endif
evaluateFeatureFile(QLatin1String("default_post.prf")); evaluateFeatureFile(QLatin1String("default_post.prf"));

View File

@@ -100,10 +100,8 @@ public:
QMakeHandler *handler); QMakeHandler *handler);
~QMakeEvaluator(); ~QMakeEvaluator();
#ifdef QT_BUILD_QMAKE
void setExtraVars(const ProValueMap &extraVars) { m_extraVars = extraVars; } void setExtraVars(const ProValueMap &extraVars) { m_extraVars = extraVars; }
void setExtraConfigs(const ProStringList &extraConfigs) { m_extraConfigs = extraConfigs; } void setExtraConfigs(const ProStringList &extraConfigs) { m_extraConfigs = extraConfigs; }
#endif
void setOutputDir(const QString &outputDir) { m_outputDir = outputDir; } void setOutputDir(const QString &outputDir) { m_outputDir = outputDir; }
ProStringList values(const ProKey &variableName) const; ProStringList values(const ProKey &variableName) const;
@@ -256,10 +254,8 @@ public:
QStack<Location> m_locationStack; // All execution location changes QStack<Location> m_locationStack; // All execution location changes
QStack<ProFile *> m_profileStack; // Includes only QStack<ProFile *> m_profileStack; // Includes only
#ifdef QT_BUILD_QMAKE
ProValueMap m_extraVars; ProValueMap m_extraVars;
ProStringList m_extraConfigs; ProStringList m_extraConfigs;
#endif
QString m_outputDir; QString m_outputDir;
int m_listCount; int m_listCount;