Fixes: Handle debug and release scopes for TARGET and DESTDIR

Task:     247606
Details:  Remove all the magic which build on top of the cumalative
parser. Instead trust the exact parsing to get those variables correct.
This required a bug fix in the profile evaluator, done with ossi.
Hopefully this doesn't break windows/mac. Will check.
This commit is contained in:
dt
2009-03-19 15:04:43 +01:00
parent 532c18d723
commit b3ec859c80
9 changed files with 186 additions and 179 deletions

View File

@@ -234,6 +234,7 @@ void QMakeStepConfigWidget::qmakeArgumentsLineEditTextEdited()
Q_ASSERT(!m_buildConfiguration.isNull()); Q_ASSERT(!m_buildConfiguration.isNull());
m_step->setValue(m_buildConfiguration, "qmakeArgs", ProjectExplorer::Environment::parseCombinedArgString(m_ui.qmakeAdditonalArgumentsLineEdit->text())); m_step->setValue(m_buildConfiguration, "qmakeArgs", ProjectExplorer::Environment::parseCombinedArgString(m_ui.qmakeAdditonalArgumentsLineEdit->text()));
m_ui.qmakeArgumentsEdit->setPlainText(ProjectExplorer::Environment::joinArgumentList(m_step->arguments(m_buildConfiguration))); m_ui.qmakeArgumentsEdit->setPlainText(ProjectExplorer::Environment::joinArgumentList(m_step->arguments(m_buildConfiguration)));
static_cast<Qt4Project *>(m_step->project())->invalidateCachedTargetInformation();
} }
void QMakeStepConfigWidget::buildConfigurationChanged() void QMakeStepConfigWidget::buildConfigurationChanged()
@@ -247,6 +248,7 @@ void QMakeStepConfigWidget::buildConfigurationChanged()
} }
m_step->setValue(m_buildConfiguration, "buildConfiguration", int(buildConfiguration)); m_step->setValue(m_buildConfiguration, "buildConfiguration", int(buildConfiguration));
m_ui.qmakeArgumentsEdit->setPlainText(ProjectExplorer::Environment::joinArgumentList(m_step->arguments(m_buildConfiguration))); m_ui.qmakeArgumentsEdit->setPlainText(ProjectExplorer::Environment::joinArgumentList(m_step->arguments(m_buildConfiguration)));
static_cast<Qt4Project *>(m_step->project())->invalidateCachedTargetInformation();
} }
QString QMakeStepConfigWidget::displayName() const QString QMakeStepConfigWidget::displayName() const

View File

@@ -115,7 +115,7 @@ void Qt4BuildConfigWidget::init(const QString &buildConfiguration)
m_ui->shadowBuildCheckBox->setChecked(shadowBuild); m_ui->shadowBuildCheckBox->setChecked(shadowBuild);
m_ui->shadowBuildDirEdit->setEnabled(shadowBuild); m_ui->shadowBuildDirEdit->setEnabled(shadowBuild);
m_ui->shadowBuildDirEdit->setPath(m_pro->buildDirectory(buildConfiguration)); m_ui->shadowBuildDirEdit->setPath(m_pro->buildDirectory(buildConfiguration));
shadowBuildLineEditTextChanged(); // Update the import label updateImportLabel();
} }
void Qt4BuildConfigWidget::changeConfigName(const QString &newName) void Qt4BuildConfigWidget::changeConfigName(const QString &newName)
@@ -173,12 +173,8 @@ void Qt4BuildConfigWidget::shadowBuildCheckBoxClicked(bool checked)
m_pro->setValue(m_buildConfiguration, "buildDirectory", QVariant(QString::null)); m_pro->setValue(m_buildConfiguration, "buildDirectory", QVariant(QString::null));
} }
void Qt4BuildConfigWidget::shadowBuildLineEditTextChanged() void Qt4BuildConfigWidget::updateImportLabel()
{ {
m_pro->setValue(m_buildConfiguration, "buildDirectory", m_ui->shadowBuildDirEdit->path());
// if the directory already exists
// check if we have a build in there and
// offer to import it
m_ui->importLabel->setVisible(false); m_ui->importLabel->setVisible(false);
if (m_ui->shadowBuildCheckBox->isChecked()) { if (m_ui->shadowBuildCheckBox->isChecked()) {
QString qtPath = m_pro->qt4ProjectManager()->versionManager()->findQtVersionFromMakefile(m_ui->shadowBuildDirEdit->path()); QString qtPath = m_pro->qt4ProjectManager()->versionManager()->findQtVersionFromMakefile(m_ui->shadowBuildDirEdit->path());
@@ -186,6 +182,18 @@ void Qt4BuildConfigWidget::shadowBuildLineEditTextChanged()
m_ui->importLabel->setVisible(true); m_ui->importLabel->setVisible(true);
} }
} }
}
void Qt4BuildConfigWidget::shadowBuildLineEditTextChanged()
{
if (m_pro->value(m_buildConfiguration, "buildDirectory").toString() == m_ui->shadowBuildDirEdit->path())
m_pro->setValue(m_buildConfiguration, "buildDirectory", m_ui->shadowBuildDirEdit->path());
// if the directory already exists
// check if we have a build in there and
// offer to import it
updateImportLabel();
m_pro->invalidateCachedTargetInformation();
// QFileInfo fi(m_ui->shadowBuildDirEdit->path()); // QFileInfo fi(m_ui->shadowBuildDirEdit->path());
// if (fi.exists()) { // if (fi.exists()) {

View File

@@ -63,6 +63,7 @@ private slots:
void manageQtVersions(); void manageQtVersions();
private: private:
void updateImportLabel();
Ui::Qt4BuildConfigWidget *m_ui; Ui::Qt4BuildConfigWidget *m_ui;
Qt4Project *m_pro; Qt4Project *m_pro;
QString m_buildConfiguration; QString m_buildConfiguration;

View File

@@ -952,7 +952,7 @@ void Qt4Project::proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *nod
foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) { foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) { if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) {
if (qt4rc->proFilePath() == node->path()) { if (qt4rc->proFilePath() == node->path()) {
qt4rc->updateCachedValues(); qt4rc->invalidateCachedTargetInformation();
} }
} }
} }
@@ -1011,3 +1011,43 @@ void Qt4Project::notifyChanged(const QString &name)
node->update(); node->update();
} }
} }
void Qt4Project::invalidateCachedTargetInformation()
{
foreach(QSharedPointer<RunConfiguration> rc, runConfigurations()) {
QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>();
if (qt4rc) {
qt4rc->invalidateCachedTargetInformation();
}
}
}
/*!
Handle special case were a subproject of the qt directory is opened, and
qt was configured to be built as a shadow build -> also build in the sub-
project in the correct shadow build directory.
*/
// TODO this function should be called on project first load
// and it should check against all configured qt versions ?
//void Qt4Project::detectQtShadowBuild(const QString &buildConfiguration) const
//{
// if (project()->activeBuildConfiguration() == buildConfiguration)
// return;
//
// const QString currentQtDir = static_cast<Qt4Project *>(project())->qtDir(buildConfiguration);
// const QString qtSourceDir = static_cast<Qt4Project *>(project())->qtVersion(buildConfiguration)->sourcePath();
//
// // if the project is a sub-project of Qt and Qt was shadow-built then automatically
// // adjust the build directory of the sub-project.
// if (project()->file()->fileName().startsWith(qtSourceDir) && qtSourceDir != currentQtDir) {
// project()->setValue(buildConfiguration, "useShadowBuild", true);
// QString buildDir = QFileInfo(project()->file()->fileName()).absolutePath();
// buildDir.replace(qtSourceDir, currentQtDir);
// project()->setValue(buildConfiguration, "buildDirectory", buildDir);
// project()->setValue(buildConfiguration, "autoShadowBuild", true);
// }
//}

View File

@@ -183,6 +183,11 @@ public:
QString makeCommand(const QString &buildConfiguration) const; QString makeCommand(const QString &buildConfiguration) const;
// Is called by qmakestep qt4configurationwidget if the settings change
// Informs all Qt4RunConfigurations that their cached values are now invalid
// the Qt4RunConfigurations will update as soon as asked
void invalidateCachedTargetInformation();
public slots: public slots:
void update(); void update();
void proFileParseError(const QString &errorMessage); void proFileParseError(const QString &errorMessage);

View File

@@ -58,17 +58,16 @@ Qt4RunConfiguration::Qt4RunConfiguration(Qt4Project *pro, QString proFilePath)
m_userSetName(false), m_userSetName(false),
m_configWidget(0), m_configWidget(0),
m_executableLabel(0), m_executableLabel(0),
m_workingDirectoryLabel(0) m_workingDirectoryLabel(0),
m_cachedTargetInformationValid(false)
{ {
setName(tr("Qt4RunConfiguration")); setName(tr("Qt4RunConfiguration"));
if (!m_proFilePath.isEmpty()) { if (!m_proFilePath.isEmpty()) {
updateCachedValues();
setName(QFileInfo(m_proFilePath).baseName()); setName(QFileInfo(m_proFilePath).baseName());
} }
connect(pro, SIGNAL(activeBuildConfigurationChanged()), connect(pro, SIGNAL(activeBuildConfigurationChanged()),
this, SIGNAL(effectiveExecutableChanged())); this, SLOT(invalidateCachedTargetInformation()));
connect(pro, SIGNAL(activeBuildConfigurationChanged()),
this, SIGNAL(effectiveWorkingDirectoryChanged()));
} }
Qt4RunConfiguration::~Qt4RunConfiguration() Qt4RunConfiguration::~Qt4RunConfiguration()
@@ -87,7 +86,7 @@ QString Qt4RunConfiguration::type() const
///// /////
Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4RunConfiguration, QWidget *parent) Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4RunConfiguration, QWidget *parent)
: QWidget(parent), m_qt4RunConfiguration(qt4RunConfiguration), m_ignoreChange(false) : QWidget(parent), m_qt4RunConfiguration(qt4RunConfiguration), m_ignoreChange(false), m_isShown(false)
{ {
QFormLayout *toplayout = new QFormLayout(this); QFormLayout *toplayout = new QFormLayout(this);
toplayout->setMargin(0); toplayout->setMargin(0);
@@ -128,11 +127,8 @@ Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4Run
connect(qt4RunConfiguration, SIGNAL(runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode)), connect(qt4RunConfiguration, SIGNAL(runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode)),
this, SLOT(runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode))); this, SLOT(runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode)));
connect(qt4RunConfiguration, SIGNAL(effectiveExecutableChanged()), connect(qt4RunConfiguration, SIGNAL(effectiveTargetInformationChanged()),
this, SLOT(effectiveExecutableChanged())); this, SLOT(effectiveTargetInformationChanged()), Qt::QueuedConnection);
connect(qt4RunConfiguration, SIGNAL(effectiveWorkingDirectoryChanged()),
this, SLOT(effectiveWorkingDirectoryChanged()));
} }
void Qt4RunConfigurationWidget::setCommandLineArguments(const QString &args) void Qt4RunConfigurationWidget::setCommandLineArguments(const QString &args)
@@ -175,18 +171,28 @@ void Qt4RunConfigurationWidget::runModeChanged(ApplicationRunConfiguration::RunM
m_useTerminalCheck->setChecked(runMode == ApplicationRunConfiguration::Console); m_useTerminalCheck->setChecked(runMode == ApplicationRunConfiguration::Console);
} }
void Qt4RunConfigurationWidget::effectiveExecutableChanged() void Qt4RunConfigurationWidget::effectiveTargetInformationChanged()
{ {
m_executableLabel->setText(m_qt4RunConfiguration->executable()); if (m_isShown) {
m_executableLabel->setText(m_qt4RunConfiguration->executable());
m_workingDirectoryLabel->setText(m_qt4RunConfiguration->workingDirectory());
}
} }
void Qt4RunConfigurationWidget::effectiveWorkingDirectoryChanged() void Qt4RunConfigurationWidget::showEvent(QShowEvent *event)
{ {
m_workingDirectoryLabel->setText(m_qt4RunConfiguration->workingDirectory()); m_isShown = true;
effectiveTargetInformationChanged();
QWidget::showEvent(event);
}
void Qt4RunConfigurationWidget::hideEvent(QHideEvent *event)
{
m_isShown = false;
QWidget::hideEvent(event);
} }
////// TODO c&p above ////// TODO c&p above
QWidget *Qt4RunConfiguration::configurationWidget() QWidget *Qt4RunConfiguration::configurationWidget()
{ {
return new Qt4RunConfigurationWidget(this, 0); return new Qt4RunConfigurationWidget(this, 0);
@@ -209,7 +215,7 @@ void Qt4RunConfiguration::restore(const PersistentSettingsReader &reader)
m_userSetName = reader.restoreValue("UserSetName").toBool(); m_userSetName = reader.restoreValue("UserSetName").toBool();
m_runMode = reader.restoreValue("UseTerminal").toBool() ? Console : Gui; m_runMode = reader.restoreValue("UseTerminal").toBool() ? Console : Gui;
if (!m_proFilePath.isEmpty()) { if (!m_proFilePath.isEmpty()) {
updateCachedValues(); m_cachedTargetInformationValid = false;
if (!m_userSetName) if (!m_userSetName)
setName(QFileInfo(m_proFilePath).baseName()); setName(QFileInfo(m_proFilePath).baseName());
} }
@@ -217,7 +223,8 @@ void Qt4RunConfiguration::restore(const PersistentSettingsReader &reader)
QString Qt4RunConfiguration::executable() const QString Qt4RunConfiguration::executable() const
{ {
return resolveVariables(project()->activeBuildConfiguration(), m_executable); const_cast<Qt4RunConfiguration *>(this)->updateTarget();
return m_executable;
} }
ApplicationRunConfiguration::RunMode Qt4RunConfiguration::runMode() const ApplicationRunConfiguration::RunMode Qt4RunConfiguration::runMode() const
@@ -227,7 +234,8 @@ ApplicationRunConfiguration::RunMode Qt4RunConfiguration::runMode() const
QString Qt4RunConfiguration::workingDirectory() const QString Qt4RunConfiguration::workingDirectory() const
{ {
return resolveVariables(project()->activeBuildConfiguration(), m_workingDir); const_cast<Qt4RunConfiguration *>(this)->updateTarget();
return m_workingDir;
} }
QStringList Qt4RunConfiguration::commandLineArguments() const QStringList Qt4RunConfiguration::commandLineArguments() const
@@ -271,180 +279,99 @@ QString Qt4RunConfiguration::proFilePath() const
return m_proFilePath; return m_proFilePath;
} }
// and needs to be reloaded. void Qt4RunConfiguration::updateTarget()
// Check wheter it is
void Qt4RunConfiguration::updateCachedValues()
{ {
ProFileReader *reader = static_cast<Qt4Project *>(project())->createProFileReader(); if (m_cachedTargetInformationValid)
return;
//qDebug()<<"updateTarget";
Qt4Project *pro = static_cast<Qt4Project *>(project());
ProFileReader *reader = pro->createProFileReader();
reader->setCumulative(false); reader->setCumulative(false);
reader->setQtVersion(pro->qtVersion(pro->activeBuildConfiguration()));
// Find out what flags we pass on to qmake, this code is duplicated in the qmake step
QtVersion::QmakeBuildConfig defaultBuildConfiguration = pro->qtVersion(pro->activeBuildConfiguration())->defaultBuildConfig();
QtVersion::QmakeBuildConfig projectBuildConfiguration = QtVersion::QmakeBuildConfig(pro->qmakeStep()->value(pro->activeBuildConfiguration(), "buildConfiguration").toInt());
QStringList addedUserConfigArguments;
QStringList removedUserConfigArguments;
if ((defaultBuildConfiguration & QtVersion::BuildAll) && !(projectBuildConfiguration & QtVersion::BuildAll))
removedUserConfigArguments << "debug_and_release";
if (!(defaultBuildConfiguration & QtVersion::BuildAll) && (projectBuildConfiguration & QtVersion::BuildAll))
addedUserConfigArguments << "debug_and_release";
if ((defaultBuildConfiguration & QtVersion::DebugBuild) && !(projectBuildConfiguration & QtVersion::DebugBuild))
addedUserConfigArguments << "release";
if (!(defaultBuildConfiguration & QtVersion::DebugBuild) && (projectBuildConfiguration & QtVersion::DebugBuild))
addedUserConfigArguments << "debug";
reader->setUserConfigCmdArgs(addedUserConfigArguments, removedUserConfigArguments);
QHash<QString, QStringList>::const_iterator it;
if (!reader->readProFile(m_proFilePath)) { if (!reader->readProFile(m_proFilePath)) {
delete reader; delete reader;
Core::ICore::instance()->messageManager()->printToOutputPane(QString("Could not parse %1. The Qt4 run configuration %2 can not be started.").arg(m_proFilePath).arg(name())); Core::ICore::instance()->messageManager()->printToOutputPane(QString("Could not parse %1. The Qt4 run configuration %2 can not be started.").arg(m_proFilePath).arg(name()));
return; return;
} }
QString destDir; // Extract data
QString relSubDir = QFileInfo(project()->file()->fileName()).absoluteDir().relativeFilePath(QFileInfo(m_proFilePath).path());
QString baseDir = QDir(project()->buildDirectory(project()->activeBuildConfiguration())).absoluteFilePath(relSubDir);
//qDebug()<<relSubDir<<baseDir;
// Working Directory
if (reader->contains("DESTDIR")) { if (reader->contains("DESTDIR")) {
// TODO Can return different destdirs for different scopes! //qDebug()<<"reader contains destdir:"<<reader->value("DESTDIR");
destDir = reader->value("DESTDIR"); m_workingDir = reader->value("DESTDIR");
if (QDir::isRelativePath(destDir)) { if (QDir::isRelativePath(m_workingDir)) {
destDir = "${BASEDIR}" + QLatin1Char('/') + destDir; m_workingDir = baseDir + QLatin1Char('/') + m_workingDir;
//qDebug()<<"was relative and expanded to"<<m_workingDir;
} }
} else { } else {
destDir = "${BASEDIR}"; //qDebug()<<"reader didn't contain DESTDIR, setting to "<<baseDir;
m_workingDir = baseDir;
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QString qmakeBuildConfig = "release";
if (projectBuildConfiguration & QtVersion::DebugBuild)
qmakeBuildConfig = "debug";
if (!reader->contains("DESTDIR")) if (!reader->contains("DESTDIR"))
destDir += QLatin1Char('/') + "${QMAKE_BUILDCONFIG}"; destDir += QLatin1Char('/') + qmakeBuildConfig;
#endif #endif
} }
#if defined (Q_OS_MAC) #if defined (Q_OS_MAC)
if (reader->values("CONFIG").contains("app_bundle")) { if (reader->values("CONFIG").contains("app_bundle")) {
QString qmakeBuildConfig = "release";
if (projectBuildConfiguration & QtVersion::DebugBuild)
qmakeBuildConfig = "debug";
destDir += QLatin1Char('/') destDir += QLatin1Char('/')
+ "${QMAKE_TARGET}" + qmakeBuildConfig
+ QLatin1String(".app/Contents/MacOS"); + QLatin1String(".app/Contents/MacOS");
} }
#endif #endif
m_workingDir = destDir;
m_executable = destDir + QLatin1Char('/') + "${QMAKE_TARGET}"; m_workingDir = QDir::cleanPath(m_workingDir);
m_executable = QDir::cleanPath(m_workingDir + QLatin1Char('/') + reader->value("TARGET"));
//qDebug()<<"##### updateTarget sets:"<<m_workingDir<<m_executable;
#if defined (Q_OS_WIN) #if defined (Q_OS_WIN)
m_executable += QLatin1String(".exe"); m_executable += QLatin1String(".exe");
#endif #endif
m_targets = reader->values(QLatin1String("TARGET"));
m_srcDir = QFileInfo(m_proFilePath).path();
delete reader; delete reader;
emit effectiveExecutableChanged(); m_cachedTargetInformationValid = true;
emit effectiveWorkingDirectoryChanged();
emit effectiveTargetInformationChanged();
} }
QString Qt4RunConfiguration::resolveVariables(const QString &buildConfiguration, const QString& in) const void Qt4RunConfiguration::invalidateCachedTargetInformation()
{ {
detectQtShadowBuild(buildConfiguration); m_cachedTargetInformationValid = false;
emit effectiveTargetInformationChanged();
QString relSubDir = QFileInfo(project()->file()->fileName()).absoluteDir().relativeFilePath(m_srcDir);
QString baseDir = QDir(project()->buildDirectory(buildConfiguration)).absoluteFilePath(relSubDir);
Core::VariableManager *vm = Core::ICore::instance()->variableManager();
if (!vm)
return QString();
QString dest;
bool found = false;
vm->insert("QMAKE_BUILDCONFIG", qmakeBuildConfigFromBuildConfiguration(buildConfiguration));
vm->insert("BASEDIR", baseDir);
/*
TODO This is a hack to detect correct target (there might be different targets in
different scopes)
*/
// This code also works for workingDirectory,
// since directories are executable.
foreach (const QString &target, m_targets) {
dest = in;
vm->insert("QMAKE_TARGET", target);
dest = QDir::cleanPath(vm->resolve(dest));
vm->remove("QMAKE_TARGET");
QFileInfo fi(dest);
if (fi.exists() && (fi.isExecutable() || dest.endsWith(".js"))) {
found = true;
break;
}
}
vm->remove("BASEDIR");
vm->remove("QMAKE_BUILDCONFIG");
if (found)
return dest;
else
return QString();
} }
/* This function tries to find out wheter qmake/make will put the binary in "/debug/" or in "/release/"
That is this function is strictly only for windows.
We look wheter make gets an explicit parameter "debug" or "release"
That works because if we have either debug or release there then it is surely a
debug_and_release buildconfiguration and thus we are put in a subdirectory.
Now if there is no explicit debug or release parameter, then we need to look at what qmake's CONFIG
value is, if it is not debug_and_release, we don't care and return ""
otherwise we look at wheter the default is debug or not
Note: When fixing this function consider those cases
qmake CONFIG+=debug_and_release CONFIG+=debug
make release
=> we should return release
qmake CONFIG+=debug_and_release CONFIG+=debug
make
=> we should return debug
qmake CONFIG-=debug_and_release CONFIG+=debug
make
=> we should return "", since the executable is not put in a subdirectory
Not a function to be proud of
*/
QString Qt4RunConfiguration::qmakeBuildConfigFromBuildConfiguration(const QString &buildConfigurationName) const
{
MakeStep *ms = qobject_cast<Qt4Project *>(project())->makeStep();
QStringList makeargs = ms->value(buildConfigurationName, "makeargs").toStringList();
if (makeargs.contains("debug"))
return "debug";
else if (makeargs.contains("release"))
return "release";
// Oh we don't have an explicit make argument
QMakeStep *qs = qobject_cast<Qt4Project *>(project())->qmakeStep();
QVariant qmakeBuildConfiguration = qs->value(buildConfigurationName, "buildConfiguration");
if (qmakeBuildConfiguration.isValid()) {
QtVersion::QmakeBuildConfig projectBuildConfiguration = QtVersion::QmakeBuildConfig(qmakeBuildConfiguration.toInt());
if (projectBuildConfiguration & QtVersion::DebugBuild)
return "debug";
else
return "release";
} else {
// Old style always CONFIG+=debug_and_release
if (qobject_cast<Qt4Project *>(project())->qtVersion(buildConfigurationName)->defaultBuildConfig() & QtVersion::DebugBuild)
return "debug";
else
return "release";
}
// enable us to infer the right string
return "";
}
/*!
Handle special case were a subproject of the qt directory is opened, and
qt was configured to be built as a shadow build -> also build in the sub-
project in the correct shadow build directory.
*/
void Qt4RunConfiguration::detectQtShadowBuild(const QString &buildConfiguration) const
{
if (project()->activeBuildConfiguration() == buildConfiguration)
return;
const QString currentQtDir = static_cast<Qt4Project *>(project())->qtDir(buildConfiguration);
const QString qtSourceDir = static_cast<Qt4Project *>(project())->qtVersion(buildConfiguration)->sourcePath();
// if the project is a sub-project of Qt and Qt was shadow-built then automatically
// adjust the build directory of the sub-project.
if (project()->file()->fileName().startsWith(qtSourceDir) && qtSourceDir != currentQtDir) {
project()->setValue(buildConfiguration, "useShadowBuild", true);
QString buildDir = QFileInfo(project()->file()->fileName()).absolutePath();
buildDir.replace(qtSourceDir, currentQtDir);
project()->setValue(buildConfiguration, "buildDirectory", buildDir);
project()->setValue(buildConfiguration, "autoShadowBuild", true);
}
}
/// ///
/// Qt4RunConfigurationFactory /// Qt4RunConfigurationFactory
/// This class is used to restore run settings (saved in .user files) /// This class is used to restore run settings (saved in .user files)

View File

@@ -73,8 +73,15 @@ public:
QString proFilePath() const; QString proFilePath() const;
// Should just be called from qt4project, since that knows that the file changed on disc // TODO detectQtShadowBuild() ? how did this work ?
void updateCachedValues();
public slots:
// This function is called if:
// X the pro file changes
// X the active buildconfiguration changes
// X the qmake parameters change
// X the build directory changes
void invalidateCachedTargetInformation();
signals: signals:
void nameChanged(const QString&); void nameChanged(const QString&);
@@ -82,8 +89,7 @@ signals:
void runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode runMode); void runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode runMode);
// note those signals might not emited for every change // note those signals might not emited for every change
void effectiveExecutableChanged(); void effectiveTargetInformationChanged();
void effectiveWorkingDirectoryChanged();
private slots: private slots:
void setCommandLineArguments(const QString &argumentsString); void setCommandLineArguments(const QString &argumentsString);
@@ -91,10 +97,7 @@ private slots:
void setRunMode(RunMode runMode); void setRunMode(RunMode runMode);
private: private:
void detectQtShadowBuild(const QString &buildConfig) const; void updateTarget();
QString resolveVariables(const QString &buildConfiguration, const QString& in) const;
QString qmakeBuildConfigFromBuildConfiguration(const QString &buildConfigurationName) const;
QStringList m_commandLineArguments; QStringList m_commandLineArguments;
Qt4ProFileNode *m_proFileNode; Qt4ProFileNode *m_proFileNode;
QString m_proFilePath; // Full path to the Application Pro File QString m_proFilePath; // Full path to the Application Pro File
@@ -102,13 +105,13 @@ private:
// Cached startup sub project information // Cached startup sub project information
QStringList m_targets; QStringList m_targets;
QString m_executable; QString m_executable;
QString m_srcDir;
QString m_workingDir; QString m_workingDir;
ProjectExplorer::ApplicationRunConfiguration::RunMode m_runMode; ProjectExplorer::ApplicationRunConfiguration::RunMode m_runMode;
bool m_userSetName; bool m_userSetName;
QWidget *m_configWidget; QWidget *m_configWidget;
QLabel *m_executableLabel; QLabel *m_executableLabel;
QLabel *m_workingDirectoryLabel; QLabel *m_workingDirectoryLabel;
bool m_cachedTargetInformationValid;
}; };
class Qt4RunConfigurationWidget : public QWidget class Qt4RunConfigurationWidget : public QWidget
@@ -116,6 +119,9 @@ class Qt4RunConfigurationWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4runconfigration, QWidget *parent); Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4runconfigration, QWidget *parent);
protected:
void showEvent(QShowEvent *event);
void hideEvent(QHideEvent *event);
private slots: private slots:
void setCommandLineArguments(const QString &arguments); void setCommandLineArguments(const QString &arguments);
void nameEdited(const QString &name); void nameEdited(const QString &name);
@@ -123,8 +129,7 @@ private slots:
void commandLineArgumentsChanged(const QString &args); void commandLineArgumentsChanged(const QString &args);
void nameChanged(const QString &name); void nameChanged(const QString &name);
void runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode runMode); void runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode runMode);
void effectiveExecutableChanged(); void effectiveTargetInformationChanged();
void effectiveWorkingDirectoryChanged();
void termToggled(bool); void termToggled(bool);
private: private:
Qt4RunConfiguration *m_qt4RunConfiguration; Qt4RunConfiguration *m_qt4RunConfiguration;
@@ -134,6 +139,7 @@ private:
QLineEdit *m_nameLineEdit; QLineEdit *m_nameLineEdit;
QLineEdit *m_argumentsLineEdit; QLineEdit *m_argumentsLineEdit;
QCheckBox *m_useTerminalCheck; QCheckBox *m_useTerminalCheck;
bool m_isShown;
}; };
class Qt4RunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory class Qt4RunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory

View File

@@ -217,6 +217,8 @@ public:
int m_prevLineNo; // Checking whether we're assigning the same TARGET int m_prevLineNo; // Checking whether we're assigning the same TARGET
ProFile *m_prevProFile; // See m_prevLineNo ProFile *m_prevProFile; // See m_prevLineNo
QStringList m_addUserConfigCmdArgs;
QStringList m_removeUserConfigCmdArgs;
}; };
ProFileEvaluator::Private::Private(ProFileEvaluator *q_) ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
@@ -628,6 +630,12 @@ bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
// But this also creates a lot of problems // But this also creates a lot of problems
evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok); evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok);
evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"), &ok); evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"), &ok);
QStringList tmp = m_valuemap.value("CONFIG");
tmp.append(m_addUserConfigCmdArgs);
foreach(const QString &remove, m_removeUserConfigCmdArgs)
tmp.removeAll(remove);
m_valuemap.insert("CONFIG", tmp);
m_cumulative = cumulative; m_cumulative = cumulative;
} }
@@ -822,6 +830,7 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
// but this will break just as much as it fixes, so leave it as is. // but this will break just as much as it fixes, so leave it as is.
replaceInList(&m_tempValuemap[varName], regexp, replace, global); replaceInList(&m_tempValuemap[varName], regexp, replace, global);
replaceInList(&m_tempFilevaluemap[currentProFile()][varName], regexp, replace, global); replaceInList(&m_tempFilevaluemap[currentProFile()][varName], regexp, replace, global);
} }
} }
break; break;
@@ -1679,14 +1688,16 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
} }
const QStringList mutuals = args[1].split(QLatin1Char('|')); const QStringList mutuals = args[1].split(QLatin1Char('|'));
const QStringList &configs = valuesDirect(QLatin1String("CONFIG")); const QStringList &configs = valuesDirect(QLatin1String("CONFIG"));
for (int i = configs.size() - 1; i >= 0; i--) { for (int i = configs.size() - 1; i >= 0; i--) {
for (int mut = 0; mut < mutuals.count(); mut++) { for (int mut = 0; mut < mutuals.count(); mut++) {
if (configs[i] == mutuals[mut].trimmed()) { if (configs[i] == mutuals[mut].trimmed()) {
cond = (configs[i] == args[0]); cond = (configs[i] == args[0]);
break; goto done_T_CONFIG;
} }
} }
} }
done_T_CONFIG:
break; break;
} }
case T_CONTAINS: { case T_CONTAINS: {
@@ -1713,12 +1724,12 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
for (int mut = 0; mut < mutuals.count(); mut++) { for (int mut = 0; mut < mutuals.count(); mut++) {
if (val == mutuals[mut].trimmed()) { if (val == mutuals[mut].trimmed()) {
cond = (regx.exactMatch(val) || val == args[1]); cond = (regx.exactMatch(val) || val == args[1]);
break; goto done_T_CONTAINS;
} }
} }
} }
} }
done_T_CONTAINS:
break; break;
} }
case T_COUNT: { case T_COUNT: {
@@ -2284,6 +2295,12 @@ void ProFileEvaluator::setOutputDir(const QString &dir)
d->m_outputDir = dir; d->m_outputDir = dir;
} }
void ProFileEvaluator::setUserConfigCmdArgs(const QStringList &addUserConfigCmdArgs, const QStringList &removeUserConfigCmdArgs)
{
d->m_addUserConfigCmdArgs = addUserConfigCmdArgs;
d->m_removeUserConfigCmdArgs = removeUserConfigCmdArgs;
}
void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap) void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap)
{ {
QStringList sourceFiles; QStringList sourceFiles;

View File

@@ -65,6 +65,7 @@ public:
void setVerbose(bool on); // Default is false void setVerbose(bool on); // Default is false
void setCumulative(bool on); // Default is true! void setCumulative(bool on); // Default is true!
void setOutputDir(const QString &dir); // Default is empty void setOutputDir(const QString &dir); // Default is empty
void setUserConfigCmdArgs(const QStringList &addUserConfigCmdArgs, const QStringList &removeUserConfigCmdArgs);
bool queryProFile(ProFile *pro); bool queryProFile(ProFile *pro);
bool accept(ProFile *pro); bool accept(ProFile *pro);