diff --git a/src/plugins/analyzerbase/ianalyzertool.cpp b/src/plugins/analyzerbase/ianalyzertool.cpp index d86ffea71a66458bf1457674c3ee25c70a8caf83..f531eb82236c12d9410ecb9d6ef8027637bce2f4 100644 --- a/src/plugins/analyzerbase/ianalyzertool.cpp +++ b/src/plugins/analyzerbase/ianalyzertool.cpp @@ -70,15 +70,15 @@ bool AnalyzerAction::isRunnable(QString *reason) const return ProjectExplorerPlugin::canRun(SessionManager::startupProject(), m_runMode, reason); } -static bool buildTypeAccepted(ToolMode toolMode, BuildConfiguration::BuildType buildType) +static bool buildTypeAccepted(QFlags toolMode, BuildConfiguration::BuildType buildType) { - if (toolMode == AnyMode) - return true; if (buildType == BuildConfiguration::Unknown) return true; - if (buildType == BuildConfiguration::Debug && toolMode == DebugMode) + if (buildType == BuildConfiguration::Debug && (toolMode & DebugMode)) + return true; + if (buildType == BuildConfiguration::Release && (toolMode & ReleaseMode)) return true; - if (buildType == BuildConfiguration::Release && toolMode == ReleaseMode) + if (buildType == BuildConfiguration::Profile && (toolMode & ProfileMode)) return true; return false; } @@ -114,17 +114,37 @@ void AnalyzerAction::startTool() // Check the project for whether the build config is in the correct mode // if not, notify the user and urge him to use the correct mode. if (!buildTypeAccepted(m_toolMode, buildType)) { - const QString currentMode = buildType == BuildConfiguration::Debug - ? AnalyzerManager::tr("Debug") - : AnalyzerManager::tr("Release"); + QString currentMode; + switch (buildType) { + case BuildConfiguration::Debug: + currentMode = AnalyzerManager::tr("Debug"); + break; + case BuildConfiguration::Profile: + currentMode = AnalyzerManager::tr("Profile"); + break; + case BuildConfiguration::Release: + currentMode = AnalyzerManager::tr("Release"); + break; + default: + QTC_CHECK(false); + } QString toolModeString; switch (m_toolMode) { case DebugMode: - toolModeString = AnalyzerManager::tr("Debug"); + toolModeString = AnalyzerManager::tr("in Debug mode"); + break; + case ProfileMode: + toolModeString = AnalyzerManager::tr("in Profile mode"); break; case ReleaseMode: - toolModeString = AnalyzerManager::tr("Release"); + toolModeString = AnalyzerManager::tr("in Release mode"); + break; + case SymbolsMode: + toolModeString = AnalyzerManager::tr("with debug symbols (Debug or Profile mode)"); + break; + case OptimizedMode: + toolModeString = AnalyzerManager::tr("on optimized code (Profile or Release mode)"); break; default: QTC_CHECK(false); @@ -133,10 +153,14 @@ void AnalyzerAction::startTool() const QString title = AnalyzerManager::tr("Run %1 in %2 Mode?").arg(toolName).arg(currentMode); const QString message = AnalyzerManager::tr("

You are trying " "to run the tool \"%1\" on an application in %2 mode. " - "The tool is designed to be used in %3 mode.

" - "Debug and Release mode run-time characteristics differ " - "significantly, analytical findings for one mode may or " - "may not be relevant for the other.

" + "The tool is designed to be used %3.

" + "Run-time characteristics differ significantly between " + "optimized and non-optimized binaries. Analytical " + "findings for one mode may or may not be relevant for " + "the other.

" + "Running tools that need debug symbols on binaries that " + "don't provide any may lead to missing function names " + "or otherwise insufficient output.

" "Do you want to continue and run the tool in %2 mode?

") .arg(toolName).arg(currentMode).arg(toolModeString); if (Utils::CheckableMessageBox::doNotAskAgainQuestion(ICore::mainWindow(), diff --git a/src/plugins/analyzerbase/ianalyzertool.h b/src/plugins/analyzerbase/ianalyzertool.h index f7be88476fb9ca93854e7cd7dfb1eee30a9f7b46..b6f35d6b05251fe620ece9a17aeeee16192a3fd3 100644 --- a/src/plugins/analyzerbase/ianalyzertool.h +++ b/src/plugins/analyzerbase/ianalyzertool.h @@ -53,15 +53,20 @@ class AnalyzerRunControl; /** * The mode in which this tool should preferably be run * - * The memcheck tool, for example, requires debug symbols, hence DebugMode - * is preferred. On the other hand, callgrind should look at optimized code, - * hence ReleaseMode. + * Debugging tools which try to show stack traces as close as possible to what the source code + * looks like will prefer SymbolsMode. Profiling tools which need optimized code for realistic + * performance, but still want to show analytical output that depends on debug symbols, will prefer + * ProfileMode. */ enum ToolMode { - DebugMode, - ReleaseMode, - AnyMode + DebugMode = 0x1, + ProfileMode = 0x2, + ReleaseMode = 0x4, + SymbolsMode = DebugMode | ProfileMode, + OptimizedMode = ProfileMode | ReleaseMode, + AnyMode = DebugMode | ProfileMode | ReleaseMode }; +Q_DECLARE_FLAGS(ToolModes, ToolMode) /** * This class represents an analyzation action, i.e. a tool that runs in a specific mode. @@ -84,7 +89,7 @@ public: Core::Id toolId() const { return m_toolId; } void setToolId(Core::Id id) { m_toolId = id; } - void setToolMode(ToolMode mode) { m_toolMode = mode; } + void setToolMode(QFlags mode) { m_toolMode = mode; } Core::Id runMode() const { return m_runMode; } void setRunMode(Core::Id mode) { m_runMode = mode; } @@ -118,7 +123,7 @@ protected: Core::Id m_menuGroup; Core::Id m_actionId; Core::Id m_toolId; - ToolMode m_toolMode; + QFlags m_toolMode; Core::Id m_runMode; WidgetCreator m_widgetCreator; RunControlCreator m_runControlCreator; diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index d5aaeda06bb22178cab7a8e211c55652bce9069b..9db178b09867327437856aa0f961119c810e478b 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -114,8 +114,9 @@ bool AndroidBuildApkStep::init() } - if (bc->buildType() == ProjectExplorer::BuildConfiguration::Debug) - emit addOutput(tr("Warning: Signing a debug package."), BuildStep::ErrorMessageOutput); + if (bc->buildType() != ProjectExplorer::BuildConfiguration::Release) + emit addOutput(tr("Warning: Signing a debug or profile package."), + BuildStep::ErrorMessageOutput); } QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); diff --git a/src/plugins/android/androidbuildapkwidget.cpp b/src/plugins/android/androidbuildapkwidget.cpp index 476da0c9574fd6fe83ecaa73c2fe49dec3b21d44..573422bb8391fa049df83b2e70d9115b0c140a16 100644 --- a/src/plugins/android/androidbuildapkwidget.cpp +++ b/src/plugins/android/androidbuildapkwidget.cpp @@ -237,8 +237,9 @@ void AndroidBuildApkWidget::verboseOutputCheckBoxToggled(bool checked) void AndroidBuildApkWidget::updateSigningWarning() { - bool debug = m_step->buildConfiguration()->buildType() == ProjectExplorer::BuildConfiguration::Debug; - if (m_step->signPackage() && debug) { + bool nonRelease = m_step->buildConfiguration()->buildType() + != ProjectExplorer::BuildConfiguration::Release; + if (m_step->signPackage() && nonRelease) { m_ui->signingDebugWarningIcon->setVisible(true); m_ui->signingDebugWarningLabel->setVisible(true); } else { diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index b8cd3a10b31ae8874395d5c400e3866657c7978f..6ca9168c6c697a6065d6beeb4cb5cac02a484d97 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -345,14 +345,13 @@ ProjectExplorer::BuildConfiguration::BuildType CMakeBuildConfiguration::buildTyp // Cover all common CMake build types if (cmakeBuildType.compare(QLatin1String("Release"), Qt::CaseInsensitive) == 0 - || cmakeBuildType.compare(QLatin1String("MinSizeRel"), Qt::CaseInsensitive) == 0) - { + || cmakeBuildType.compare(QLatin1String("MinSizeRel"), Qt::CaseInsensitive) == 0) { return Release; } else if (cmakeBuildType.compare(QLatin1String("Debug"), Qt::CaseInsensitive) == 0 - || cmakeBuildType.compare(QLatin1String("DebugFull"), Qt::CaseInsensitive) == 0 - || cmakeBuildType.compare(QLatin1String("RelWithDebInfo"), Qt::CaseInsensitive) == 0) - { + || cmakeBuildType.compare(QLatin1String("DebugFull"), Qt::CaseInsensitive) == 0) { return Debug; + } else if (cmakeBuildType.compare(QLatin1String("RelWithDebInfo"), Qt::CaseInsensitive) == 0) { + return Profile; } return Unknown; diff --git a/src/plugins/ios/iosbuildstep.cpp b/src/plugins/ios/iosbuildstep.cpp index 1aea94c804db6eb5f550b887b8a3a6ff63613553..3662ad1d301ba3db55cdfe0c9599d618006ea931 100644 --- a/src/plugins/ios/iosbuildstep.cpp +++ b/src/plugins/ios/iosbuildstep.cpp @@ -187,6 +187,7 @@ QStringList IosBuildStep::defaultArguments() const res << QLatin1String("-configuration") << QLatin1String("Debug"); break; case BuildConfiguration::Release : + case BuildConfiguration::Profile : res << QLatin1String("-configuration") << QLatin1String("Release"); break; case BuildConfiguration::Unknown : diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp index 0a455e51bde454552578dc8b73ff66bb288fe3c5..8f86962747e9e2940d8b77ff2dab7276b30843dc 100644 --- a/src/plugins/ios/iosrunconfiguration.cpp +++ b/src/plugins/ios/iosrunconfiguration.cpp @@ -244,6 +244,7 @@ FileName IosRunConfiguration::bundleDirectory() const else res.appendPath(QLatin1String("Debug-iphonesimulator")); break; + case BuildConfiguration::Profile : case BuildConfiguration::Release : if (isDevice) res.appendPath(QLatin1String("Release-iphoneos")); diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index ebd5b5a3891dc52578ede0ee195e79be2bf364d9..1dae36db758e3ccd873674dfa142585df31354c6 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -86,6 +86,7 @@ public: enum BuildType { Unknown, Debug, + Profile, Release }; virtual BuildType buildType() const = 0; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index b5e7778e9f529ed8811e155625511352e7586a4d..41a9ffc11e73ce0439feaa5e399bdf05d96d92e9 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1377,6 +1377,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er return tr("debug"); if (type == BuildConfiguration::Release) return tr("release"); + if (type == BuildConfiguration::Profile) + return tr("profile"); } return tr("unknown"); }); diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp index 546c2776fba55820b7f78459e43b63831b5f66fd..18e8f07ade33de02cbc6722bd0634da8d9c963a2 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp @@ -445,9 +445,9 @@ BuildConfiguration *QbsBuildConfigurationFactory::create(Target *parent, const B QVariantMap configData; configData.insert(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY), - (qbsInfo->type == BuildConfiguration::Release) - ? QLatin1String(Constants::QBS_VARIANT_RELEASE) - : QLatin1String(Constants::QBS_VARIANT_DEBUG)); + (qbsInfo->type == BuildConfiguration::Debug) + ? QLatin1String(Constants::QBS_VARIANT_DEBUG) + : QLatin1String(Constants::QBS_VARIANT_RELEASE)); Utils::FileName buildDir = info->buildDirectory; if (buildDir.isEmpty()) diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 7f19728c9b6cac11058ccb5b335038f1ca1e1130..611826d09164c80f1d34b9c13e274ec4cd57ea1e 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -97,6 +97,7 @@ static Utils::FileName defaultBuildDirectory(const QString &projectPath, const char QMAKE_BC_ID[] = "Qt4ProjectManager.Qt4BuildConfiguration"; const char USE_SHADOW_BUILD_KEY[] = "Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild"; const char BUILD_CONFIGURATION_KEY[] = "Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration"; +const char PROFILE_BUILD_KEY[] = "Qt4ProjectManager.Qt4BuildConfiguration.ProfileBuild"; enum { debug = 0 }; @@ -566,10 +567,18 @@ QmakeBuildInfo *QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k, //: Non-ASCII characters in directory suffix may cause build issues. suffix = tr("Release", "Shadow build directory suffix"); } else { - //: The name of the debug build configuration created by default for a qmake project. - info->displayName = tr("Debug"); - //: Non-ASCII characters in directory suffix may cause build issues. - suffix = tr("Debug", "Shadow build directory suffix"); + if (type == BuildConfiguration::Debug) { + //: The name of the debug build configuration created by default for a qmake project. + info->displayName = tr("Debug"); + //: Non-ASCII characters in directory suffix may cause build issues. + suffix = tr("Debug", "Shadow build directory suffix"); + } else if (type == BuildConfiguration::Profile) { + //: The name of the profile build configuration created by default for a qmake project. + info->displayName = tr("Profile"); + //: Non-ASCII characters in directory suffix may cause build issues. + suffix = tr("Profile", "Shadow build directory suffix"); + info->config.separateDebugInfo = true; + } if (version && version->qtVersion().majorVersion >= 5) info->config.linkQmlDebuggingQQ2 = true; } @@ -607,6 +616,7 @@ QList QmakeBuildConfigurationFactory::availableBuilds(const Target const QString projectFilePath = parent->project()->projectFilePath().toString(); for (BuildConfiguration::BuildType buildType : { BuildConfiguration::Debug, + BuildConfiguration::Profile, BuildConfiguration::Release }) { QmakeBuildInfo *info = createBuildInfo(parent->kit(), projectFilePath, buildType); @@ -633,6 +643,7 @@ QList QmakeBuildConfigurationFactory::availableSetups(const Kit *k, if (!qtVersion || !qtVersion->isValid()) return result; result << createBuildInfo(k, projectPath, ProjectExplorer::BuildConfiguration::Debug); + result << createBuildInfo(k, projectPath, ProjectExplorer::BuildConfiguration::Profile); result << createBuildInfo(k, projectPath, ProjectExplorer::BuildConfiguration::Release); return result; } @@ -644,10 +655,10 @@ void QmakeBuildConfigurationFactory::configureBuildConfiguration(Target *parent, BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(parent->kit()); BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); - if (qmakeInfo->type == BuildConfiguration::Release) - config &= ~QtSupport::BaseQtVersion::DebugBuild; - else + if (qmakeInfo->type == BuildConfiguration::Debug) config |= QtSupport::BaseQtVersion::DebugBuild; + else + config &= ~QtSupport::BaseQtVersion::DebugBuild; bc->setDefaultDisplayName(qmakeInfo->displayName); bc->setDisplayName(qmakeInfo->displayName); @@ -733,6 +744,8 @@ BuildConfiguration::BuildType QmakeBuildConfiguration::buildType() const { if (qmakeBuildConfiguration() & BaseQtVersion::DebugBuild) return Debug; + else if (qmakeStep()->separateDebugInfo()) + return Profile; else return Release; } diff --git a/src/plugins/valgrind/valgrindplugin.cpp b/src/plugins/valgrind/valgrindplugin.cpp index f92b648230e1a41a0683a3abccb72d947583ab00..fe0b688a779711a19f853f7b3d27c9acfd78b04f 100644 --- a/src/plugins/valgrind/valgrindplugin.cpp +++ b/src/plugins/valgrind/valgrindplugin.cpp @@ -164,7 +164,7 @@ void ValgrindPlugin::extensionsInitialized() action->setToolId("Memcheck"); action->setWidgetCreator(mcWidgetCreator); action->setRunControlCreator(mcRunControlCreator); - action->setToolMode(DebugMode); + action->setToolMode(SymbolsMode); action->setRunMode(MEMCHECK_RUN_MODE); action->setText(tr("Valgrind Memory Analyzer")); action->setToolTip(memcheckToolTip); @@ -180,7 +180,7 @@ void ValgrindPlugin::extensionsInitialized() action->setWidgetCreator([mcgTool] { return mcgTool->createWidgets(); }); action->setRunControlCreator(std::bind(&MemcheckWithGdbTool::createRunControl, mcgTool, _1, _2)); - action->setToolMode(DebugMode); + action->setToolMode(SymbolsMode); action->setRunMode(MEMCHECK_WITH_GDB_RUN_MODE); action->setText(tr("Valgrind Memory Analyzer with GDB")); action->setToolTip(tr("Valgrind Analyze Memory with GDB uses the " @@ -195,7 +195,7 @@ void ValgrindPlugin::extensionsInitialized() action->setToolId(CallgrindToolId); action->setWidgetCreator(cgWidgetCreator); action->setRunControlCreator(cgRunControlCreator); - action->setToolMode(ReleaseMode); + action->setToolMode(OptimizedMode); action->setRunMode(CALLGRIND_RUN_MODE); action->setText(tr("Valgrind Function Profiler")); action->setToolTip(callgrindToolTip);