diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp index a1ce6467f0a84cdbe68b57d8d7663cfa8f50e2a7..5df843514f38d9014bd304d192820ce95cf5bd4f 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp @@ -444,10 +444,8 @@ bool Qt4RunConfiguration::fromMap(const QVariantMap &map) QString Qt4RunConfiguration::executable() const { Qt4Project *pro = static_cast<Qt4Project *>(target()->project()); - TargetInformation ti = pro->rootQt4ProjectNode()->targetInformation(m_proFilePath); - if (!ti.valid) - return QString(); - return ti.executable; + const Qt4ProFileNode *node = pro->rootQt4ProjectNode()->findProFileFor(m_proFilePath); + return extractWorkingDirAndExecutable(node).second; } LocalApplicationRunConfiguration::RunMode Qt4RunConfiguration::runMode() const @@ -490,10 +488,8 @@ QString Qt4RunConfiguration::baseWorkingDirectory() const // else what the pro file reader tells us Qt4Project *pro = static_cast<Qt4Project *>(target()->project()); - TargetInformation ti = pro->rootQt4ProjectNode()->targetInformation(m_proFilePath); - if (!ti.valid) - return QString(); - return ti.workingDir; + const Qt4ProFileNode *node = pro->rootQt4ProjectNode()->findProFileFor(m_proFilePath); + return extractWorkingDirAndExecutable(node).first; } QString Qt4RunConfiguration::commandLineArguments() const @@ -587,6 +583,49 @@ Utils::OutputFormatter *Qt4RunConfiguration::createOutputFormatter() const return new QtSupport::QtOutputFormatter(target()->project()); } +QPair<QString, QString> Qt4RunConfiguration::extractWorkingDirAndExecutable(const Qt4ProFileNode *node) const +{ + if (!node) + return qMakePair(QString(), QString()); + TargetInformation ti = node->targetInformation(); + if (!ti.valid) + return qMakePair(QString(), QString()); + + const QStringList &config = node->variableValue(ConfigVar); + + QString destDir = ti.destDir; + QString workingDir; + if (!destDir.isEmpty()) { + bool workingDirIsBaseDir = false; + if (destDir == ti.buildTarget) { + workingDirIsBaseDir = true; + } + if (QDir::isRelativePath(destDir)) + destDir = QDir::cleanPath(ti.buildDir + QLatin1Char('/') + destDir); + + if (workingDirIsBaseDir) + workingDir = ti.buildDir; + else + workingDir = destDir; + } else { + destDir = ti.buildDir; + workingDir = ti.buildDir; + } + + if (Utils::HostOsInfo::isMacHost() + && config.contains(QLatin1String("app_bundle"))) { + const QString infix = QLatin1Char('/') + ti.target + + QLatin1String(".app/Contents/MacOS"); + workingDir += infix; + destDir += infix; + } + + QString executable = QDir::cleanPath(destDir + QLatin1Char('/') + ti.target); + executable = Utils::HostOsInfo::withExecutableSuffix(executable); + //qDebug() << "##### Qt4RunConfiguration::extractWorkingDirAndExecutable:" workingDir << executable; + return qMakePair(workingDir, executable); +} + /// /// Qt4RunConfigurationFactory /// This class is used to restore run settings (saved in .user files) diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h index e86ab9b709603853040f74ee2380a24e0cc85835..771cb22ac5196857cdda995260726bd3858d804f 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h @@ -56,6 +56,7 @@ namespace Qt4ProjectManager { class Qt4Project; class Qt4ProFileNode; class Qt4PriFileNode; +struct TargetInformation; namespace Internal { class Qt4RunConfigurationFactory; @@ -114,6 +115,7 @@ protected: virtual bool fromMap(const QVariantMap &map); private: + QPair<QString, QString> extractWorkingDirAndExecutable(const Qt4ProFileNode *node) const; void setBaseWorkingDirectory(const QString &workingDirectory); QString baseWorkingDirectory() const; void setCommandLineArguments(const QString &argumentsString); diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index a5c2cb82a4fb09a1eeae85edabdf077400bd9c95..5414ce7576ddff925bc6e0fcac879c3f3824ffaf 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -1346,16 +1346,6 @@ const Qt4ProFileNode *Qt4ProFileNode::findProFileFor(const QString &fileName) co return 0; } -TargetInformation Qt4ProFileNode::targetInformation(const QString &fileName) const -{ - TargetInformation result; - const Qt4ProFileNode *qt4ProFileNode = findProFileFor(fileName); - if (!qt4ProFileNode) - return result; - - return qt4ProFileNode->targetInformation(); -} - QString Qt4ProFileNode::makefile() const { return singleVariableValue(Makefile); @@ -1911,6 +1901,7 @@ void Qt4ProFileNode::applyEvaluate(EvalResult evalResult, bool async) newVarValues[ObjectExt] = m_readerExact->values(QLatin1String("QMAKE_EXT_OBJ")); newVarValues[ObjectsDir] = m_readerExact->values(QLatin1String("OBJECTS_DIR")); newVarValues[VersionVar] = m_readerExact->values(QLatin1String("VERSION")); + newVarValues[TargetExtVar] = m_readerExact->values(QLatin1String("TARGET_EXT")); newVarValues[TargetVersionExtVar] = m_readerExact->values(QLatin1String("TARGET_VERSION_EXT")); newVarValues[StaticLibExtensionVar] = m_readerExact->values(QLatin1String("QMAKE_EXTENSION_STATICLIB")); @@ -2079,10 +2070,9 @@ TargetInformation Qt4ProFileNode::targetInformation(QtSupport::ProFileReader *re QtSupport::ProFileReader *readerBP = 0; QStringList builds = reader->values(QLatin1String("BUILDS")); - QString buildTarget; if (!builds.isEmpty()) { QString build = builds.first(); - buildTarget = reader->value(build + QLatin1String(".target")); + result.buildTarget = reader->value(build + QLatin1String(".target")); QHash<QString, QStringList> basevars; QStringList basecfgs = reader->values(build + QLatin1String(".CONFIG")); @@ -2113,48 +2103,15 @@ TargetInformation Qt4ProFileNode::targetInformation(QtSupport::ProFileReader *re // BUILD DIR result.buildDir = buildDir(); - const QString baseDir = result.buildDir; - // qDebug() << "base build dir is:"<<baseDir; - QString destDir; - if (reader->contains(QLatin1String("DESTDIR"))) { - destDir = reader->value(QLatin1String("DESTDIR")); - bool workingDirIsBaseDir = false; - if (destDir == buildTarget) // special case for "debug" or "release" - workingDirIsBaseDir = true; - - if (QDir::isRelativePath(destDir)) - destDir = baseDir + QLatin1Char('/') + destDir; - - if (workingDirIsBaseDir) - result.workingDir = baseDir; - else - result.workingDir = destDir; - } else { - destDir = baseDir; - result.workingDir = baseDir; - } + if (reader->contains(QLatin1String("DESTDIR"))) + result.destDir = reader->value(QLatin1String("DESTDIR")); // Target result.target = reader->value(QLatin1String("TARGET")); if (result.target.isEmpty()) result.target = QFileInfo(m_projectFilePath).baseName(); - if (Utils::HostOsInfo::isMacHost() - && reader->values(QLatin1String("CONFIG")).contains(QLatin1String("app_bundle"))) { - const QString infix = QLatin1Char('/') + result.target - + QLatin1String(".app/Contents/MacOS"); - result.workingDir += infix; - destDir += infix; - } - - result.workingDir = QDir::cleanPath(result.workingDir); - - /// should this really be in this method? - result.executable = QDir::cleanPath(destDir + QLatin1Char('/') + result.target); - //qDebug() << "##### updateTarget sets:" << result.workingDir << result.executable; - - result.executable = Utils::HostOsInfo::withExecutableSuffix(result.executable); result.valid = true; if (readerBP) diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h index a552d615c43a8036513fc32378ba66bc9d38bf26..188080f058a4efb695072e20e11093b3d9b7dd78 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.h +++ b/src/plugins/qt4projectmanager/qt4nodes.h @@ -98,6 +98,7 @@ enum Qt4Variable { ObjectExt, ObjectsDir, VersionVar, + TargetExtVar, TargetVersionExtVar, StaticLibExtensionVar, ShLibExtensionVar, @@ -295,17 +296,17 @@ private: struct QT4PROJECTMANAGER_EXPORT TargetInformation { bool valid; - QString workingDir; QString target; - QString executable; + QString destDir; QString buildDir; + QString buildTarget; bool operator==(const TargetInformation &other) const { - return workingDir == other.workingDir - && target == other.target - && executable == other.executable + return target == other.target && valid == other.valid - && buildDir == other.buildDir; + && destDir == other.destDir + && buildDir == other.buildDir + && buildTarget == other.buildTarget; } bool operator!=(const TargetInformation &other) const { @@ -318,10 +319,10 @@ struct QT4PROJECTMANAGER_EXPORT TargetInformation TargetInformation(const TargetInformation &other) : valid(other.valid), - workingDir(other.workingDir), target(other.target), - executable(other.executable), - buildDir(other.buildDir) + destDir(other.destDir), + buildDir(other.buildDir), + buildTarget(other.buildTarget) { } @@ -380,7 +381,6 @@ public: QStringList uiFiles() const; const Qt4ProFileNode *findProFileFor(const QString &string) const; - TargetInformation targetInformation(const QString &fileName) const; TargetInformation targetInformation() const; InstallsList installsList() const; diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index 013f10068db9bcab47ce8279d0a4095921d2decc..103e534627dbc397b901f1ada7b0ce351602deee 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -1422,7 +1422,7 @@ void Qt4Project::updateBuildSystemData() BuildTargetInfoList appTargetList; foreach (const Qt4ProFileNode * const node, applicationProFiles()) - appTargetList.list << BuildTargetInfo(node->targetInformation().executable, node->path()); + appTargetList.list << BuildTargetInfo(executableFor(node), node->path()); target->setApplicationTargets(appTargetList); } @@ -1440,8 +1440,7 @@ void Qt4Project::collectData(const Qt4ProFileNode *node, DeploymentData &deploym switch (node->projectType()) { case ApplicationTemplate: if (!installsList.targetPath.isEmpty()) - deploymentData.addFile(node->targetInformation().executable, installsList.targetPath, - DeployableFile::TypeExecutable); + collectApplicationData(node, deploymentData); break; case LibraryTemplate: collectLibraryData(node, deploymentData); @@ -1460,6 +1459,14 @@ void Qt4Project::collectData(const Qt4ProFileNode *node, DeploymentData &deploym } } +void Qt4Project::collectApplicationData(const Qt4ProFileNode *node, DeploymentData &deploymentData) +{ + QString executable = executableFor(node); + if (!executable.isEmpty()) + deploymentData.addFile(executable, node->installsList().targetPath, + DeployableFile::TypeExecutable); +} + void Qt4Project::collectLibraryData(const Qt4ProFileNode *node, DeploymentData &deploymentData) { const QString targetPath = node->installsList().targetPath; @@ -1489,12 +1496,13 @@ void Qt4Project::collectLibraryData(const Qt4ProFileNode *node, DeploymentData & } targetFileName += targetVersionExt + QLatin1Char('.'); targetFileName += QLatin1String(isStatic ? "lib" : "dll"); - deploymentData.addFile(ti.workingDir + QLatin1Char('/') + targetFileName, targetPath); + deploymentData.addFile(destDirFor(ti) + QLatin1Char('/') + targetFileName, targetPath); break; } - case ProjectExplorer::Abi::MacOS: + case ProjectExplorer::Abi::MacOS: { + QString destDir = destDirFor(ti); if (config.contains(QLatin1String("lib_bundle"))) { - ti.workingDir.append(QLatin1Char('/')).append(ti.target) + destDir.append(QLatin1Char('/')).append(ti.target) .append(QLatin1String(".framework")); } else { targetFileName.prepend(QLatin1String("lib")); @@ -1510,8 +1518,9 @@ void Qt4Project::collectLibraryData(const Qt4ProFileNode *node, DeploymentData & targetFileName += node->singleVariableValue(isStatic ? StaticLibExtensionVar : ShLibExtensionVar); } - deploymentData.addFile(ti.workingDir + QLatin1Char('/') + targetFileName, targetPath); + deploymentData.addFile(destDir + QLatin1Char('/') + targetFileName, targetPath); break; + } case ProjectExplorer::Abi::LinuxOS: case ProjectExplorer::Abi::BsdOS: case ProjectExplorer::Abi::UnixOS: @@ -1521,14 +1530,14 @@ void Qt4Project::collectLibraryData(const Qt4ProFileNode *node, DeploymentData & targetFileName += QLatin1Char('a'); } else { targetFileName += QLatin1String("so"); - deploymentData.addFile(ti.workingDir + QLatin1Char('/') + targetFileName, targetPath); + deploymentData.addFile(destDirFor(ti) + QLatin1Char('/') + targetFileName, targetPath); if (!isPlugin) { QString version = node->singleVariableValue(VersionVar); if (version.isEmpty()) version = QLatin1String("1.0.0"); targetFileName += QLatin1Char('.'); while (true) { - deploymentData.addFile(ti.workingDir + QLatin1Char('/') + deploymentData.addFile(destDirFor(ti) + QLatin1Char('/') + targetFileName + version, targetPath); const QString tmpVersion = version.left(version.lastIndexOf(QLatin1Char('.'))); if (tmpVersion == version) @@ -1543,6 +1552,44 @@ void Qt4Project::collectLibraryData(const Qt4ProFileNode *node, DeploymentData & } } +QString Qt4Project::destDirFor(const TargetInformation &ti) +{ + if (ti.destDir.isEmpty()) + return ti.buildDir; + if (QDir::isRelativePath(ti.destDir)) + return QDir::cleanPath(ti.buildDir + QLatin1Char('/') + ti.destDir); + return ti.destDir; +} + +QString Qt4Project::executableFor(const Qt4ProFileNode *node) +{ + const ProjectExplorer::Kit * const kit = activeTarget()->kit(); + const ProjectExplorer::ToolChain * const toolchain + = ProjectExplorer::ToolChainKitInformation::toolChain(kit); + if (!toolchain) + return QString(); + + TargetInformation ti = node->targetInformation(); + + switch (toolchain->targetAbi().os()) { + case ProjectExplorer::Abi::MacOS: + if (node->variableValue(ConfigVar).contains(QLatin1String("app_bundle"))) + return QDir::cleanPath(destDirFor(ti) + QLatin1Char('/') + ti.target + + QLatin1String(".app/Contents/MacOS/") + ti.target); + // else fall through + case ProjectExplorer::Abi::WindowsOS: + case ProjectExplorer::Abi::LinuxOS: + case ProjectExplorer::Abi::BsdOS: + case ProjectExplorer::Abi::UnixOS: { + QString extension = node->singleVariableValue(TargetExtVar); + QString executable = QDir::cleanPath(destDirFor(ti) + QLatin1Char('/') + ti.target + extension); + return executable; + } + default: + return QString(); + } +} + void Qt4Project::emitBuildDirectoryInitialized() { emit buildDirectoryInitialized(); diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h index c03ef7e96096d7281f2b71b99a4c1fb2a9f2920a..17e2133f2de4bb8ef1ee4116fe0c64315df0f136 100644 --- a/src/plugins/qt4projectmanager/qt4project.h +++ b/src/plugins/qt4projectmanager/qt4project.h @@ -56,6 +56,7 @@ class Qt4Manager; class Qt4PriFileNode; class Qt4ProFileNode; class Qt4RunStep; +struct TargetInformation; namespace Internal { class CentralizedFolderWatcher; @@ -161,6 +162,7 @@ private slots: void activeTargetWasChanged(); private: + QString executableFor(const Qt4ProFileNode *node); void updateRunConfigurations(); void updateCppCodeModel(); @@ -177,8 +179,11 @@ private: void updateBuildSystemData(); void collectData(const Qt4ProFileNode *node, ProjectExplorer::DeploymentData &deploymentData); + void collectApplicationData(const Qt4ProFileNode *node, + ProjectExplorer::DeploymentData &deploymentData); void collectLibraryData(const Qt4ProFileNode *node, ProjectExplorer::DeploymentData &deploymentData); + QString destDirFor(const TargetInformation &ti); Qt4Manager *m_manager; Qt4ProFileNode *m_rootProjectNode;