From 129c0abb5a38d8f928a122f173ac361f56f2df3e Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 20 Jun 2019 15:49:05 +0200 Subject: [PATCH] CMake: Get some timings about the data update process This should help to remove UI blocking by pointing to the costly operations. Change-Id: I8b3250e9ec5995c7b6a705337d60250554b77b53 Reviewed-by: hjk --- .../cmakeprojectmanager/cmakeproject.cpp | 198 +++++++++++------- 1 file changed, 125 insertions(+), 73 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index cebd0dac42e..08039b7229d 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -59,6 +59,7 @@ #include #include +#include #include using namespace ProjectExplorer; @@ -68,6 +69,25 @@ namespace CMakeProjectManager { Q_LOGGING_CATEGORY(cmakeProjectLog, "qtc.cmake.project", QtWarningMsg); +class TraceTimer +{ +public: + TraceTimer(const QString &msg) + : m_message(msg) + { + m_timer.start(); + } + + ~TraceTimer() + { + qCInfo(cmakeProjectLog) << QString("%1 (%2ms)").arg(m_message).arg(m_timer.elapsed()); + } + +private: + QElapsedTimer m_timer; + QString m_message; +}; + using namespace Internal; static CMakeBuildConfiguration *activeBc(const CMakeProject *p) @@ -269,6 +289,7 @@ CMakeProject::~CMakeProject() void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) { + TraceTimer updateProjectTotalTimer(__PRETTY_FUNCTION__); qCDebug(cmakeProjectLog) << "Updating CMake project data"; const CMakeBuildConfiguration *aBc = activeBc(this); QString errorMessage; @@ -277,103 +298,131 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) QTC_ASSERT(bc == aBc, return); QTC_ASSERT(m_treeScanner.isFinished() && !m_buildDirManager.isParsing(), return); - const QList buildTargets = m_buildDirManager.takeBuildTargets(errorMessage); - checkAndReportError(errorMessage); - bc->setBuildTargets(buildTargets); - qCDebug(cmakeProjectLog) << "Build target data set."; - const CMakeConfig cmakeConfig = m_buildDirManager.takeCMakeConfiguration(errorMessage); - checkAndReportError(errorMessage); - bc->setConfigurationFromCMake(cmakeConfig); - qCDebug(cmakeProjectLog) << "CMake configuration data set."; - - CMakeConfig patchedConfig = cmakeConfig; { - CMakeConfigItem settingFileItem; - settingFileItem.key = "ANDROID_DEPLOYMENT_SETTINGS_FILE"; - settingFileItem.value = bc->buildDirectory() - .pathAppended("android_deployment_settings.json").toString().toUtf8(); - patchedConfig.append(settingFileItem); + TraceTimer buildTargetsTimer(" build targets"); + const QList buildTargets = m_buildDirManager.takeBuildTargets( + errorMessage); + checkAndReportError(errorMessage); + bc->setBuildTargets(buildTargets); + qCDebug(cmakeProjectLog) << "Build target data set."; } + CMakeConfig patchedConfig; + { + TraceTimer cacheTimer(" cache data (plus patching)"); + const CMakeConfig cmakeConfig = m_buildDirManager.takeCMakeConfiguration(errorMessage); + checkAndReportError(errorMessage); + bc->setConfigurationFromCMake(cmakeConfig); + qCDebug(cmakeProjectLog) << "CMake configuration data set."; - QSet res; - QStringList apps; - for (const auto &target : bc->buildTargets()) { - if (target.targetType == CMakeProjectManager::DynamicLibraryType) { - res.insert(target.executable.parentDir().toString()); - apps.push_back(target.executable.toUserOutput()); + patchedConfig = cmakeConfig; + { + CMakeConfigItem settingFileItem; + settingFileItem.key = "ANDROID_DEPLOYMENT_SETTINGS_FILE"; + settingFileItem.value = bc->buildDirectory() + .pathAppended("android_deployment_settings.json") + .toString() + .toUtf8(); + patchedConfig.append(settingFileItem); } - // ### shall we add also the ExecutableType ? } { - CMakeConfigItem paths; - paths.key = "ANDROID_SO_LIBS_PATHS"; - paths.values = res.toList(); - patchedConfig.append(paths); + TraceTimer appsTimer(" application data"); + QSet res; + QStringList apps; + for (const auto &target : bc->buildTargets()) { + if (target.targetType == CMakeProjectManager::DynamicLibraryType) { + res.insert(target.executable.parentDir().toString()); + apps.push_back(target.executable.toUserOutput()); + } + // ### shall we add also the ExecutableType ? + } + { + CMakeConfigItem paths; + paths.key = "ANDROID_SO_LIBS_PATHS"; + paths.values = res.toList(); + patchedConfig.append(paths); + } + + apps.sort(); + { + CMakeConfigItem appsPaths; + appsPaths.key = "TARGETS_BUILD_PATH"; + appsPaths.values = apps; + patchedConfig.append(appsPaths); + } } - apps.sort(); { - CMakeConfigItem appsPaths; - appsPaths.key = "TARGETS_BUILD_PATH"; - appsPaths.values = apps; - patchedConfig.append(appsPaths); - } - qCDebug(cmakeProjectLog) << "Application data regenerated."; + TraceTimer projectTreeTimer(" project tree"); + auto newRoot = generateProjectTree(m_allFiles); + if (newRoot) { + setRootProjectNode(std::move(newRoot)); + if (rootProjectNode()) + setDisplayName(rootProjectNode()->displayName()); - auto newRoot = generateProjectTree(m_allFiles); - if (newRoot) { - setRootProjectNode(std::move(newRoot)); - if (rootProjectNode()) - setDisplayName(rootProjectNode()->displayName()); - - for (const CMakeBuildTarget &bt : buildTargets) { - const QString buildKey = CMakeTargetNode::generateId(bt.sourceDirectory, bt.title); - if (ProjectNode *node = findNodeForBuildKey(buildKey)) { - if (auto targetNode = dynamic_cast(node)) - targetNode->setConfig(patchedConfig); + for (const CMakeBuildTarget &bt : bc->buildTargets()) { + const QString buildKey = CMakeTargetNode::generateId(bt.sourceDirectory, bt.title); + if (ProjectNode *node = findNodeForBuildKey(buildKey)) { + if (auto targetNode = dynamic_cast(node)) + targetNode->setConfig(patchedConfig); + } } } } - qCDebug(cmakeProjectLog) << "Project tree updated."; - Target *t = bc->target(); - t->setApplicationTargets(bc->appTargets()); - t->setDeploymentData(bc->deploymentData()); + { + TraceTimer projectTreeTimer(" target updated"); + Target *t = bc->target(); + t->setApplicationTargets(bc->appTargets()); + t->setDeploymentData(bc->deploymentData()); - t->updateDefaultRunConfigurations(); + t->updateDefaultRunConfigurations(); + } - qDeleteAll(m_extraCompilers); - m_extraCompilers = findExtraCompilers(); - CppTools::GeneratedCodeModelSupport::update(m_extraCompilers); - qCDebug(cmakeProjectLog) << "Extra compilers updated."; + { + TraceTimer projectTreeTimer(" extra compilers"); + qDeleteAll(m_extraCompilers); + m_extraCompilers = findExtraCompilers(); + CppTools::GeneratedCodeModelSupport::update(m_extraCompilers); + qCDebug(cmakeProjectLog) << "Extra compilers updated."; + } QtSupport::CppKitInfo kitInfo(this); QTC_ASSERT(kitInfo.isValid(), return); - CppTools::RawProjectParts rpps = m_buildDirManager.createRawProjectParts(errorMessage); - checkAndReportError(errorMessage); - qCDebug(cmakeProjectLog) << "Raw project parts created."; + { + TraceTimer cxxCodemodelTimer(" cxx codemodel"); + CppTools::RawProjectParts rpps = m_buildDirManager.createRawProjectParts(errorMessage); + checkAndReportError(errorMessage); + qCDebug(cmakeProjectLog) << "Raw project parts created."; - for (CppTools::RawProjectPart &rpp : rpps) { - rpp.setQtVersion(kitInfo.projectPartQtVersion); // TODO: Check if project actually uses Qt. - if (kitInfo.cxxToolChain) - rpp.setFlagsForCxx({kitInfo.cxxToolChain, rpp.flagsForCxx.commandLineFlags}); - if (kitInfo.cToolChain) - rpp.setFlagsForC({kitInfo.cToolChain, rpp.flagsForC.commandLineFlags}); + for (CppTools::RawProjectPart &rpp : rpps) { + rpp.setQtVersion( + kitInfo.projectPartQtVersion); // TODO: Check if project actually uses Qt. + if (kitInfo.cxxToolChain) + rpp.setFlagsForCxx({kitInfo.cxxToolChain, rpp.flagsForCxx.commandLineFlags}); + if (kitInfo.cToolChain) + rpp.setFlagsForC({kitInfo.cToolChain, rpp.flagsForC.commandLineFlags}); + } + + m_cppCodeModelUpdater->update({this, kitInfo, rpps}); + } + { + TraceTimer qmlCodemodelTimer(" qml codemodel"); + updateQmlJSCodeModel(); } - m_cppCodeModelUpdater->update({this, kitInfo, rpps}); - qCDebug(cmakeProjectLog) << "C++ codemodel updated."; + { + TraceTimer resetTimer(" resetting builddirmanager"); + m_buildDirManager.resetData(); + } - updateQmlJSCodeModel(); - qCDebug(cmakeProjectLog) << "QML codemodel updated."; + { + TraceTimer emitTimer(" emitting signals"); + emit fileListChanged(); - m_buildDirManager.resetData(); - qCDebug(cmakeProjectLog) << "CMake specific data was reset."; - - emit fileListChanged(); - - bc->emitBuildTypeChanged(); + bc->emitBuildTypeChanged(); + } qCDebug(cmakeProjectLog) << "All CMake project data up to date."; } @@ -603,7 +652,10 @@ void CMakeProject::combineScanAndParse(CMakeBuildConfiguration *bc) if (m_combinedScanAndParseResult) updateProjectData(bc); - emitParsingFinished(m_combinedScanAndParseResult); + { + TraceTimer parsingDoneTimer(" parsing finished signal"); + emitParsingFinished(m_combinedScanAndParseResult); + } } QStringList CMakeProject::filesGeneratedFrom(const QString &sourceFile) const