From cc32cabd4f7d8a4870f86d851bb92b4728c2e7e1 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 30 Jan 2020 13:40:16 +0100 Subject: [PATCH] CppTools: Give early warning if kit has no compilers We keep getting bug reports from users who forgot to set a compiler in their kit and then get confused by (misleading) warnings from the code model. Improve the situation by detecting the condition that a C/C++ project's current kit does not have a C/C++ compiler and showing a warning for that in the issues pane. Task-number: QTCREATORBUG-23247 Change-Id: I10164e85ad595f3a386340e7813d1f3e40fbecb5 Reviewed-by: hjk --- .../cpptools/cppprojectinfogenerator.cpp | 49 ++++++++++++++----- .../cpptools/cppprojectinfogenerator.h | 2 + 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/plugins/cpptools/cppprojectinfogenerator.cpp b/src/plugins/cpptools/cppprojectinfogenerator.cpp index 6c33898d0b5..ab82029d20a 100644 --- a/src/plugins/cpptools/cppprojectinfogenerator.cpp +++ b/src/plugins/cpptools/cppprojectinfogenerator.cpp @@ -29,15 +29,20 @@ #include #include +#include #include +#include + +using namespace ProjectExplorer; + namespace CppTools { namespace Internal { ProjectInfoGenerator::ProjectInfoGenerator( const QFutureInterface &futureInterface, - const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) + const ProjectUpdateInfo &projectUpdateInfo) : m_futureInterface(futureInterface) , m_projectUpdateInfo(projectUpdateInfo) { @@ -47,7 +52,7 @@ ProjectInfo ProjectInfoGenerator::generate() { ProjectInfo projectInfo(m_projectUpdateInfo.project); - for (const ProjectExplorer::RawProjectPart &rpp : m_projectUpdateInfo.rawProjectParts) { + for (const RawProjectPart &rpp : m_projectUpdateInfo.rawProjectParts) { if (m_futureInterface.isCanceled()) return ProjectInfo(); @@ -55,11 +60,26 @@ ProjectInfo ProjectInfoGenerator::generate() projectInfo.appendProjectPart(part); } + static const auto showWarning = [](const QString &message) { + QTimer::singleShot(0, TaskHub::instance(), [message] { + TaskHub::addTask(BuildSystemTask(Task::Warning, message)); + }); + }; + if (m_cToolchainMissing) { + showWarning(QCoreApplication::translate("CppTools", + "The project contains C source files, but the currently active kit " + "has no C compiler. The code model will not be fully functional.")); + } + if (m_cxxToolchainMissing) { + showWarning(QCoreApplication::translate("CppTools", + "The project contains C++ source files, but the currently active kit " + "has no C++ compiler. The code model will not be fully functional.")); + } return projectInfo; } static ProjectPart::Ptr projectPartFromRawProjectPart( - const ProjectExplorer::RawProjectPart &rawProjectPart, ProjectExplorer::Project *project) + const RawProjectPart &rawProjectPart, Project *project) { ProjectPart::Ptr part(new ProjectPart); part->project = project; @@ -73,7 +93,7 @@ static ProjectPart::Ptr projectPartFromRawProjectPart( part->qtVersion = rawProjectPart.qtVersion; part->projectMacros = rawProjectPart.projectMacros; if (!part->projectConfigFile.isEmpty()) - part->projectMacros += ProjectExplorer::Macro::toMacros(ProjectPart::readProjectConfigFile(part)); + part->projectMacros += Macro::toMacros(ProjectPart::readProjectConfigFile(part)); part->headerPaths = rawProjectPart.headerPaths; part->precompiledHeaders = rawProjectPart.precompiledHeaders; part->selectedForBuilding = rawProjectPart.selectedForBuilding; @@ -82,7 +102,7 @@ static ProjectPart::Ptr projectPartFromRawProjectPart( } QVector ProjectInfoGenerator::createProjectParts( - const ProjectExplorer::RawProjectPart &rawProjectPart) + const RawProjectPart &rawProjectPart) { using Utils::LanguageExtension; @@ -114,6 +134,8 @@ QVector ProjectInfoGenerator::createProjectParts( Language::Cxx, LanguageExtension::ObjectiveC); } + } else if (cat.hasCxxSources() || cat.hasObjcxxSources()) { + m_cxxToolchainMissing = true; } if (m_projectUpdateInfo.cToolChain) { @@ -134,21 +156,23 @@ QVector ProjectInfoGenerator::createProjectParts( Language::C, LanguageExtension::ObjectiveC); } + } else if (cat.hasCSources() || cat.hasObjcSources()) { + m_cToolchainMissing = true; } return result; } ProjectPart::Ptr ProjectInfoGenerator::createProjectPart( - const ProjectExplorer::RawProjectPart &rawProjectPart, + const RawProjectPart &rawProjectPart, const ProjectPart::Ptr &templateProjectPart, const ProjectFiles &projectFiles, const QString &partName, Language language, Utils::LanguageExtensions languageExtensions) { - ProjectExplorer::RawProjectPartFlags flags; - ProjectExplorer::ToolChainInfo tcInfo; + RawProjectPartFlags flags; + ToolChainInfo tcInfo; if (language == Language::C) { flags = rawProjectPart.flagsForC; tcInfo = m_projectUpdateInfo.cToolChainInfo; @@ -158,7 +182,6 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart( flags = rawProjectPart.flagsForCxx; tcInfo = m_projectUpdateInfo.cxxToolChainInfo; } - // TODO: If no toolchain is set, show a warning ProjectPart::Ptr part(templateProjectPart->copy()); part->displayName = partName; @@ -189,14 +212,14 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart( // Header paths if (tcInfo.headerPathsRunner) { - const ProjectExplorer::HeaderPaths builtInHeaderPaths + const HeaderPaths builtInHeaderPaths = tcInfo.headerPathsRunner(flags.commandLineFlags, tcInfo.sysRootPath, tcInfo.targetTriple); - ProjectExplorer::HeaderPaths &headerPaths = part->headerPaths; - for (const ProjectExplorer::HeaderPath &header : builtInHeaderPaths) { - const ProjectExplorer::HeaderPath headerPath{header.path, header.type}; + HeaderPaths &headerPaths = part->headerPaths; + for (const HeaderPath &header : builtInHeaderPaths) { + const HeaderPath headerPath{header.path, header.type}; if (!headerPaths.contains(headerPath)) headerPaths.push_back(headerPath); } diff --git a/src/plugins/cpptools/cppprojectinfogenerator.h b/src/plugins/cpptools/cppprojectinfogenerator.h index 2dbc4cd2fa5..3eb3bfd971c 100644 --- a/src/plugins/cpptools/cppprojectinfogenerator.h +++ b/src/plugins/cpptools/cppprojectinfogenerator.h @@ -54,6 +54,8 @@ private: private: const QFutureInterface m_futureInterface; const ProjectExplorer::ProjectUpdateInfo &m_projectUpdateInfo; + bool m_cToolchainMissing = false; + bool m_cxxToolchainMissing = false; }; } // namespace Internal } // namespace CppTools