CMakePM: Add subdirectory build/clean/rebuild context menu support

CMake has support for sub directory operations for the Ninja and Unix
Makefiles generators.

See the documentation at:
 * https://cmake.org/cmake/help/latest/generator/Ninja.html
 * https://cmake.org/cmake/help/latest/generator/Unix%20Makefiles.html

Fixes: QTCREATORBUG-27588
Change-Id: If620902df1761cc39a7554d0a8c0291a19f49897
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Cristian Adam
2024-08-29 19:13:25 +02:00
parent cf765fd5f8
commit 415391b2b8
14 changed files with 312 additions and 15 deletions

View File

@@ -1663,6 +1663,36 @@ void CMakeBuildConfiguration::buildTarget(const QString &buildTarget)
cmBs->setBuildTargets(originalBuildTargets); cmBs->setBuildTargets(originalBuildTargets);
} }
void CMakeBuildConfiguration::reBuildTarget(const QString &cleanTarget, const QString &buildTarget)
{
auto cmBs = qobject_cast<CMakeBuildStep *>(
findOrDefault(buildSteps()->steps(), [](const BuildStep *bs) {
return bs->id() == Constants::CMAKE_BUILD_STEP_ID;
}));
auto cmCs = qobject_cast<CMakeBuildStep *>(
findOrDefault(cleanSteps()->steps(), [](const BuildStep *bs) {
return bs->id() == Constants::CMAKE_BUILD_STEP_ID;
}));
QStringList originalBuildTargets;
if (cmBs) {
originalBuildTargets = cmBs->buildTargets();
cmBs->setBuildTargets({buildTarget});
}
QString originalCleanTarget;
if (cmCs) {
originalCleanTarget = cmCs->cleanTarget();
cmCs->setBuildTargets({cleanTarget});
}
BuildManager::buildLists({cleanSteps(), buildSteps()});
if (cmBs)
cmBs->setBuildTargets(originalBuildTargets);
if (cmCs)
cmCs->setBuildTargets({originalCleanTarget});
}
CMakeConfig CMakeBuildSystem::configurationFromCMake() const CMakeConfig CMakeBuildSystem::configurationFromCMake() const
{ {
return m_configurationFromCMake; return m_configurationFromCMake;

View File

@@ -66,6 +66,7 @@ public:
// Context menu action: // Context menu action:
void buildTarget(const QString &buildTarget); void buildTarget(const QString &buildTarget);
void reBuildTarget(const QString &cleanTarget, const QString &buildTarget);
ProjectExplorer::BuildSystem *buildSystem() const final; ProjectExplorer::BuildSystem *buildSystem() const final;
void addToEnvironment(Utils::Environment &env) const override; void addToEnvironment(Utils::Environment &env) const override;

View File

@@ -443,9 +443,37 @@ CommandLine CMakeBuildStep::cmakeCommand() const
project = buildConfiguration()->project(); project = buildConfiguration()->project();
} }
auto bs = qobject_cast<CMakeBuildSystem *>(buildSystem());
const bool hasSubprojectBuild = bs && bs->hasSubprojectBuildSupport();
bool ninjaSubprojectClean = false;
// Subprojects have subdir/<command> structure
if (m_buildTargets.size() == 1 && m_buildTargets.front().contains("/") && hasSubprojectBuild) {
QString target = m_buildTargets.front();
const auto separator = target.lastIndexOf("/");
const QString path = target.left(separator);
const QString operation = target.mid(separator + 1);
if (bs->cmakeGenerator().contains("Makefiles")) {
cmd.addArgs( cmd.addArgs(
{"--build", {"--build",
CMakeToolManager::mappedFilePath(project, buildDirectory).path()}); CMakeToolManager::mappedFilePath(project, buildDirectory.pathAppended(path))
.path()});
cmd.addArg("--target");
cmd.addArg(operation);
} else {
cmd.addArgs(
{"--build", CMakeToolManager::mappedFilePath(project, buildDirectory).path()});
cmd.addArg("--target");
if (operation == "clean") {
target = path + "/" + "all";
ninjaSubprojectClean = true;
}
cmd.addArg(target);
}
} else {
cmd.addArgs({"--build", CMakeToolManager::mappedFilePath(project, buildDirectory).path()});
cmd.addArg("--target"); cmd.addArg("--target");
cmd.addArgs(Utils::transform(m_buildTargets, [this](const QString &s) { cmd.addArgs(Utils::transform(m_buildTargets, [this](const QString &s) {
@@ -455,10 +483,10 @@ CommandLine CMakeBuildStep::cmakeCommand() const
} }
return s; return s;
})); }));
}
if (useStaging()) if (useStaging())
cmd.addArg("install"); cmd.addArg("install");
auto bs = qobject_cast<CMakeBuildSystem *>(buildSystem());
if (bs && bs->isMultiConfigReader()) { if (bs && bs->isMultiConfigReader()) {
cmd.addArg("--config"); cmd.addArg("--config");
if (m_configuration) if (m_configuration)
@@ -483,6 +511,12 @@ CommandLine CMakeBuildStep::cmakeCommand() const
cmd.addArgs("-allowProvisioningUpdates", CommandLine::Raw); cmd.addArgs("-allowProvisioningUpdates", CommandLine::Raw);
} }
if (ninjaSubprojectClean) {
if (!toolArgumentsSpecified)
cmd.addArg("--");
cmd.addArgs({"-t", "clean"});
}
return cmd; return cmd;
} }

View File

@@ -839,6 +839,16 @@ CMakeBuildSystem::projectFileArgumentPosition(const QString &targetName, const Q
return std::nullopt; return std::nullopt;
} }
QString CMakeBuildSystem::cmakeGenerator() const
{
return m_reader.cmakeGenerator();
}
bool CMakeBuildSystem::hasSubprojectBuildSupport() const
{
return cmakeGenerator().contains("Ninja") || cmakeGenerator().contains("Makefiles");
}
RemovedFilesFromProject CMakeBuildSystem::removeFiles(Node *context, RemovedFilesFromProject CMakeBuildSystem::removeFiles(Node *context,
const FilePaths &filePaths, const FilePaths &filePaths,
FilePaths *notRemoved) FilePaths *notRemoved)
@@ -1193,6 +1203,13 @@ void CMakeBuildSystem::buildCMakeTarget(const QString &buildTarget)
cmakeBuildConfiguration()->buildTarget(buildTarget); cmakeBuildConfiguration()->buildTarget(buildTarget);
} }
void CMakeBuildSystem::reBuildCMakeTarget(const QString &cleanTarget, const QString &buildTarget)
{
QTC_ASSERT(!cleanTarget.isEmpty() && !buildTarget.isEmpty(), return);
if (ProjectExplorerPlugin::saveModifiedFiles())
cmakeBuildConfiguration()->reBuildTarget(cleanTarget, buildTarget);
}
bool CMakeBuildSystem::persistCMakeState() bool CMakeBuildSystem::persistCMakeState()
{ {
BuildDirParameters parameters(this); BuildDirParameters parameters(this);

View File

@@ -81,6 +81,7 @@ public:
// Context menu actions: // Context menu actions:
void buildCMakeTarget(const QString &buildTarget); void buildCMakeTarget(const QString &buildTarget);
void reBuildCMakeTarget(const QString &cleanTarget, const QString &buildTarget);
// Queries: // Queries:
const QList<ProjectExplorer::BuildTargetInfo> appTargets() const; const QList<ProjectExplorer::BuildTargetInfo> appTargets() const;
@@ -128,6 +129,9 @@ public:
const QHash<QString, Utils::Link> &dotCMakeFilesHash() const { return m_dotCMakeFilesHash; } const QHash<QString, Utils::Link> &dotCMakeFilesHash() const { return m_dotCMakeFilesHash; }
const QHash<QString, Utils::Link> &findPackagesFilesHash() const { return m_findPackagesFilesHash; } const QHash<QString, Utils::Link> &findPackagesFilesHash() const { return m_findPackagesFilesHash; }
QString cmakeGenerator() const;
bool hasSubprojectBuildSupport() const;
signals: signals:
void configurationCleared(); void configurationCleared();
void configurationChanged(const CMakeConfig &config); void configurationChanged(const CMakeConfig &config);

View File

@@ -19,6 +19,12 @@ const char BUILD_FILE[] = "CMakeProject.BuildFile";
const char CMAKE_HOME_DIR[] = "CMakeProject.HomeDirectory"; const char CMAKE_HOME_DIR[] = "CMakeProject.HomeDirectory";
const char QML_DEBUG_SETTING[] = "CMakeProject.EnableQmlDebugging"; const char QML_DEBUG_SETTING[] = "CMakeProject.EnableQmlDebugging";
const char RELOAD_CMAKE_PRESETS[] = "CMakeProject.ReloadCMakePresets"; const char RELOAD_CMAKE_PRESETS[] = "CMakeProject.ReloadCMakePresets";
const char BUILD_SUBPROJECT[] = "CMakeProject.BuildSubProject";
const char CLEAN_SUBPROJECT[] = "CMakeProject.CleanSubProject";
const char REBUILD_SUBPROJECT[] = "CMakeProject.RebuildSubProject";
const char BUILD_SUBPROJECT_CONTEXT_MENU[] = "CMakeProject.BuildSubProjectContextMenu";
const char CLEAN_SUBPROJECT_CONTEXT_MENU[] = "CMakeProject.CleanSubProjectContextMenu";
const char REBUILD_SUBPROJECT_CONTEXT_MENU[] = "CMakeProject.RebuildSubProjectContextMenu";
const char CMAKEFORMATTER_SETTINGS_GROUP[] = "CMakeFormatter"; const char CMAKEFORMATTER_SETTINGS_GROUP[] = "CMakeFormatter";
const char CMAKEFORMATTER_GENERAL_GROUP[] = "General"; const char CMAKEFORMATTER_GENERAL_GROUP[] = "General";

View File

@@ -72,6 +72,10 @@ private:
void updateBuildFileAction(); void updateBuildFileAction();
void enableBuildFileMenus(Node *node); void enableBuildFileMenus(Node *node);
void reloadCMakePresets(); void reloadCMakePresets();
void enableBuildSubprojectContextMenu(Node *node);
void enableBuildSubprojectMenu();
void runSubprojectOperation(const QString &clean, const QString &build);
CMakeListsNode* currentListsNodeForEditor();
QAction *m_runCMakeAction; QAction *m_runCMakeAction;
QAction *m_clearCMakeCacheAction; QAction *m_clearCMakeCacheAction;
@@ -85,6 +89,12 @@ private:
QAction *m_cmakeDebuggerAction; QAction *m_cmakeDebuggerAction;
QAction *m_cmakeDebuggerSeparator; QAction *m_cmakeDebuggerSeparator;
bool m_canDebugCMake = false; bool m_canDebugCMake = false;
Action *m_buildSubprojectContextAction = nullptr;
QAction *m_cleanSubprojectContextAction = nullptr;
QAction *m_rebuildSubprojectContextAction = nullptr;
Action *m_buildSubprojectAction = nullptr;
QAction *m_cleanSubprojectAction = nullptr;
QAction *m_rebuildSubprojectAction = nullptr;
}; };
bool CMakeManager::isCMakeUrl(const QUrl &url) bool CMakeManager::isCMakeUrl(const QUrl &url)
@@ -182,6 +192,66 @@ CMakeManager::CMakeManager()
.addToContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_BUILD) .addToContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_BUILD)
.addOnTriggered(this, [this] { buildFile(); }); .addOnTriggered(this, [this] { buildFile(); });
// Subproject
ActionBuilder(this, Constants::BUILD_SUBPROJECT)
.setParameterText(
Tr::tr("Build &Subproject \"%1\""),
Tr::tr("Build &Subproject"),
ActionBuilder::AlwaysEnabled)
.setContext(projectContext)
.bindContextAction(&m_buildSubprojectAction)
.setCommandAttribute(Command::CA_Hide)
.setCommandAttribute(Command::CA_UpdateText)
.setCommandDescription(m_buildSubprojectAction->text())
.addToContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_SUBPROJECT)
.addOnTriggered(this, [&] { runSubprojectOperation(QString(), "all"); });
ActionBuilder(this, Constants::REBUILD_SUBPROJECT)
.setText(Tr::tr("Rebuild"))
.setContext(projectContext)
.bindContextAction(&m_rebuildSubprojectAction)
.setCommandAttribute(Command::CA_Hide)
.addToContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_SUBPROJECT)
.addOnTriggered(this, [&] { runSubprojectOperation("clean", "all"); });
ActionBuilder(this, Constants::CLEAN_SUBPROJECT)
.setText(Tr::tr("Clean"))
.setContext(projectContext)
.bindContextAction(&m_cleanSubprojectAction)
.setCommandAttribute(Command::CA_Hide)
.addToContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_SUBPROJECT)
.addOnTriggered(this, [&] { runSubprojectOperation("clean", QString()); });
// Subproject context menus
ActionBuilder(this, Constants::BUILD_SUBPROJECT_CONTEXT_MENU)
.setParameterText(
Tr::tr("Build &Subproject \"%1\""),
Tr::tr("Build &Subproject"),
ActionBuilder::AlwaysEnabled)
.setContext(projectContext)
.bindContextAction(&m_buildSubprojectContextAction)
.setCommandAttribute(Command::CA_Hide)
.setCommandAttribute(Command::CA_UpdateText)
.setCommandDescription(m_buildSubprojectContextAction->text())
.addToContainer(PEC::M_SUBPROJECTCONTEXT, PEC::G_PROJECT_BUILD)
.addOnTriggered(this, [&] { runSubprojectOperation(QString(), "all"); });
ActionBuilder(this, Constants::REBUILD_SUBPROJECT_CONTEXT_MENU)
.setText(Tr::tr("Rebuild"))
.setContext(projectContext)
.bindContextAction(&m_rebuildSubprojectContextAction)
.setCommandAttribute(Command::CA_Hide)
.addToContainer(PEC::M_SUBPROJECTCONTEXT, PEC::G_PROJECT_BUILD)
.addOnTriggered(this, [&] { runSubprojectOperation("clean", "all"); });
ActionBuilder(this, Constants::CLEAN_SUBPROJECT_CONTEXT_MENU)
.setText(Tr::tr("Clean"))
.setContext(projectContext)
.bindContextAction(&m_cleanSubprojectContextAction)
.setCommandAttribute(Command::CA_Hide)
.addToContainer(PEC::M_SUBPROJECTCONTEXT, PEC::G_PROJECT_BUILD)
.addOnTriggered(this, [&] { runSubprojectOperation("clean", QString()); });
// CMake Profiler // CMake Profiler
ActionBuilder(this, Constants::RUN_CMAKE_PROFILER) ActionBuilder(this, Constants::RUN_CMAKE_PROFILER)
.setIcon(ProjectExplorer::Icons::CMAKE_LOGO.icon()) .setIcon(ProjectExplorer::Icons::CMAKE_LOGO.icon())
@@ -225,8 +295,10 @@ CMakeManager::CMakeManager()
connect(BuildManager::instance(), &BuildManager::buildStateChanged, this, [this] { connect(BuildManager::instance(), &BuildManager::buildStateChanged, this, [this] {
updateCmakeActions(ProjectTree::currentNode()); updateCmakeActions(ProjectTree::currentNode());
}); });
connect(EditorManager::instance(), &EditorManager::currentEditorChanged, connect(EditorManager::instance(), &EditorManager::currentEditorChanged, this, [this]() {
this, &CMakeManager::updateBuildFileAction); updateBuildFileAction();
enableBuildSubprojectMenu();
});
connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged, connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged,
this, &CMakeManager::updateCmakeActions); this, &CMakeManager::updateCmakeActions);
@@ -257,6 +329,7 @@ void CMakeManager::updateCmakeActions(Node *node)
m_reloadCMakePresetsAction->setVisible(reloadPresetsVisible); m_reloadCMakePresetsAction->setVisible(reloadPresetsVisible);
enableBuildFileMenus(node); enableBuildFileMenus(node);
enableBuildSubprojectContextMenu(node);
} }
void CMakeManager::clearCMakeCache(BuildSystem *buildSystem) void CMakeManager::clearCMakeCache(BuildSystem *buildSystem)
@@ -409,6 +482,93 @@ void CMakeManager::reloadCMakePresets()
Core::ModeManager::setFocusToCurrentMode(); Core::ModeManager::setFocusToCurrentMode();
} }
void CMakeManager::enableBuildSubprojectContextMenu(Node *node)
{
const Project *project = ProjectTree::projectForNode(node);
auto subProjectNode = dynamic_cast<const CMakeListsNode *>(node);
const QString subProjectDisplayName = subProjectNode ? subProjectNode->displayName()
: QString();
const bool subProjectVisible = subProjectNode && subProjectNode->hasSubprojectBuildSupport()
&& !BuildManager::isBuilding(project);
m_buildSubprojectContextAction->setParameter(subProjectDisplayName);
m_buildSubprojectContextAction->setEnabled(subProjectVisible);
m_buildSubprojectContextAction->setVisible(subProjectVisible);
m_cleanSubprojectContextAction->setEnabled(subProjectVisible);
m_cleanSubprojectContextAction->setVisible(subProjectVisible);
m_rebuildSubprojectContextAction->setEnabled(subProjectVisible);
m_rebuildSubprojectContextAction->setVisible(subProjectVisible);
}
void CMakeManager::enableBuildSubprojectMenu()
{
auto subProjectNode = currentListsNodeForEditor();
const Project *project = ProjectTree::projectForNode(subProjectNode);
const QString subProjectDisplayName = subProjectNode ? subProjectNode->displayName()
: QString();
const bool subProjectVisible = subProjectNode && subProjectNode->hasSubprojectBuildSupport()
&& !BuildManager::isBuilding(project);
m_buildSubprojectAction->setParameter(subProjectDisplayName);
m_buildSubprojectAction->setEnabled(subProjectVisible);
m_buildSubprojectAction->setVisible(subProjectVisible);
m_cleanSubprojectAction->setEnabled(subProjectVisible);
m_cleanSubprojectAction->setVisible(subProjectVisible);
m_rebuildSubprojectAction->setEnabled(subProjectVisible);
m_rebuildSubprojectAction->setVisible(subProjectVisible);
}
void CMakeManager::runSubprojectOperation(const QString &clean, const QString &build)
{
if (auto bs = qobject_cast<CMakeBuildSystem *>(ProjectTree::currentBuildSystem())) {
auto subProject = dynamic_cast<const CMakeListsNode *>(ProjectTree::currentNode());
// We want to allow the build action from a source file when triggered from a keyboard seqnuence
if (!subProject)
subProject = currentListsNodeForEditor();
if (!subProject)
return;
auto subProjectDir = subProject->filePath();
auto projectFileDir = bs->project()->projectFilePath().parentDir();
auto relativePath = subProjectDir.relativeChildPath(projectFileDir);
if (clean.isEmpty()) {
bs->buildCMakeTarget(relativePath.path() + "/" + build);
} else if (build.isEmpty()) {
bs->buildCMakeTarget(relativePath.path() + "/" + clean);
} else {
bs->reBuildCMakeTarget(
relativePath.path() + "/" + clean, relativePath.path() + "/" + build);
}
}
}
CMakeListsNode *CMakeManager::currentListsNodeForEditor()
{
Core::IDocument *currentDocument = Core::EditorManager::currentDocument();
if (!currentDocument)
return nullptr;
const FilePath file = currentDocument->filePath();
Node *n = ProjectTree::nodeForFile(file);
FileNode *node = n ? n->asFileNode() : nullptr;
if (!node)
return nullptr;
auto targetNode = dynamic_cast<const CMakeTargetNode *>(node->parentProjectNode());
if (!targetNode)
return nullptr;
return dynamic_cast<CMakeListsNode*>(targetNode->parentProjectNode());
}
void CMakeManager::buildFile(Node *node) void CMakeManager::buildFile(Node *node)
{ {
if (!node) { if (!node) {

View File

@@ -74,6 +74,16 @@ CMakePresetsNode::CMakePresetsNode(const FilePath &projectPath) :
setListInProject(false); setListInProject(false);
} }
bool CMakeListsNode::hasSubprojectBuildSupport() const
{
return m_hasSubprojectBuildSupport;
}
void CMakeListsNode::setHasSubprojectBuildSupport(bool hasSubprojectBuildSupport)
{
m_hasSubprojectBuildSupport = hasSubprojectBuildSupport;
}
CMakeListsNode::CMakeListsNode(const FilePath &cmakeListPath) : CMakeListsNode::CMakeListsNode(const FilePath &cmakeListPath) :
ProjectExplorer::ProjectNode(cmakeListPath) ProjectExplorer::ProjectNode(cmakeListPath)
{ {

View File

@@ -23,6 +23,8 @@ public:
class CMakeListsNode : public ProjectExplorer::ProjectNode class CMakeListsNode : public ProjectExplorer::ProjectNode
{ {
bool m_hasSubprojectBuildSupport{false};
public: public:
CMakeListsNode(const Utils::FilePath &cmakeListPath); CMakeListsNode(const Utils::FilePath &cmakeListPath);
@@ -32,6 +34,9 @@ public:
bool canAddSubProject(const Utils::FilePath &subProjectFilePath) const override; bool canAddSubProject(const Utils::FilePath &subProjectFilePath) const override;
bool addSubProject(const Utils::FilePath &subProjectFilePath) override; bool addSubProject(const Utils::FilePath &subProjectFilePath) override;
QStringList subProjectFileNamePatterns() const override; QStringList subProjectFileNamePatterns() const override;
bool hasSubprojectBuildSupport() const;
void setHasSubprojectBuildSupport(bool hasSubprojectBuildSupport);
}; };
class CMakeProjectNode : public ProjectExplorer::ProjectNode class CMakeProjectNode : public ProjectExplorer::ProjectNode

View File

@@ -24,6 +24,7 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectmanager.h> #include <projectexplorer/projectmanager.h>
#include <projectexplorer/projecttree.h> #include <projectexplorer/projecttree.h>
@@ -111,13 +112,16 @@ class CMakeProjectPlugin final : public ExtensionSystem::IPlugin
void updateContextActions(ProjectExplorer::Node *node) void updateContextActions(ProjectExplorer::Node *node)
{ {
const Project *project = ProjectTree::projectForNode(node);
auto targetNode = dynamic_cast<const CMakeTargetNode *>(node); auto targetNode = dynamic_cast<const CMakeTargetNode *>(node);
const QString targetDisplayName = targetNode ? targetNode->displayName() : QString(); const QString targetDisplayName = targetNode ? targetNode->displayName() : QString();
const bool isVisible = targetNode && !BuildManager::isBuilding(project);
// Build Target: // Build Target:
m_buildTargetContextAction->setParameter(targetDisplayName); m_buildTargetContextAction->setParameter(targetDisplayName);
m_buildTargetContextAction->setEnabled(targetNode); m_buildTargetContextAction->setEnabled(isVisible);
m_buildTargetContextAction->setVisible(targetNode); m_buildTargetContextAction->setVisible(isVisible);
} }
Action *m_buildTargetContextAction = nullptr; Action *m_buildTargetContextAction = nullptr;

View File

@@ -975,6 +975,20 @@ static void markCMakeModulesFromPrefixPathAsGenerated(FileApiQtcData &result)
}); });
} }
static void setSubprojectBuildSupport(FileApiQtcData &result)
{
if (!result.rootProjectNode)
return;
result.rootProjectNode->forEachGenericNode([&](Node *node) {
if (auto cmakeListsNode = dynamic_cast<CMakeListsNode *>(node)) {
cmakeListsNode->setHasSubprojectBuildSupport(
result.cmakeGenerator.contains("Ninja")
|| result.cmakeGenerator.contains("Makefiles"));
}
});
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// extractData: // extractData:
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@@ -1018,11 +1032,13 @@ FileApiQtcData extractData(const QFuture<void> &cancelFuture, FileApiData &input
return {}; return {};
result.ctestPath = input.replyFile.ctestExecutable; result.ctestPath = input.replyFile.ctestExecutable;
result.cmakeGenerator = input.replyFile.generator;
result.isMultiConfig = input.replyFile.isMultiConfig; result.isMultiConfig = input.replyFile.isMultiConfig;
if (input.replyFile.isMultiConfig && input.replyFile.generator != "Ninja Multi-Config") if (input.replyFile.isMultiConfig && input.replyFile.generator != "Ninja Multi-Config")
result.usesAllCapsTargets = true; result.usesAllCapsTargets = true;
markCMakeModulesFromPrefixPathAsGenerated(result); markCMakeModulesFromPrefixPathAsGenerated(result);
setSubprojectBuildSupport(result);
return result; return result;
} }

View File

@@ -48,6 +48,7 @@ public:
ProjectExplorer::RawProjectParts projectParts; ProjectExplorer::RawProjectParts projectParts;
std::unique_ptr<CMakeProjectNode> rootProjectNode; std::unique_ptr<CMakeProjectNode> rootProjectNode;
QString ctestPath; QString ctestPath;
QString cmakeGenerator;
bool isMultiConfig = false; bool isMultiConfig = false;
bool usesAllCapsTargets = false; bool usesAllCapsTargets = false;
}; };

View File

@@ -290,6 +290,7 @@ void FileApiReader::endState(const FilePath &replyFilePath, bool restoredFromBac
m_ctestPath = std::move(value->ctestPath); m_ctestPath = std::move(value->ctestPath);
m_isMultiConfig = value->isMultiConfig; m_isMultiConfig = value->isMultiConfig;
m_usesAllCapsTargets = value->usesAllCapsTargets; m_usesAllCapsTargets = value->usesAllCapsTargets;
m_cmakeGenerator = value->cmakeGenerator;
if (value->errorMessage.isEmpty()) { if (value->errorMessage.isEmpty()) {
emit this->dataAvailable(restoredFromBackup); emit this->dataAvailable(restoredFromBackup);
@@ -347,6 +348,11 @@ void FileApiReader::writeConfigurationIntoBuildDirectory(const QStringList &conf
QTC_ASSERT_EXPECTED(settingsFile.writeFileContents(contents), return); QTC_ASSERT_EXPECTED(settingsFile.writeFileContents(contents), return);
} }
QString FileApiReader::cmakeGenerator() const
{
return m_cmakeGenerator;
}
std::unique_ptr<CMakeProjectNode> FileApiReader::rootProjectNode() std::unique_ptr<CMakeProjectNode> FileApiReader::rootProjectNode()
{ {
return std::exchange(m_rootProjectNode, {}); return std::exchange(m_rootProjectNode, {});

View File

@@ -63,6 +63,8 @@ public:
Utils::FilePath topCmakeFile() const; Utils::FilePath topCmakeFile() const;
QString cmakeGenerator() const;
signals: signals:
void configurationStarted() const; void configurationStarted() const;
void dataAvailable(bool restoredFromBackup) const; void dataAvailable(bool restoredFromBackup) const;
@@ -90,6 +92,7 @@ private:
ProjectExplorer::RawProjectParts m_projectParts; ProjectExplorer::RawProjectParts m_projectParts;
std::unique_ptr<CMakeProjectNode> m_rootProjectNode; std::unique_ptr<CMakeProjectNode> m_rootProjectNode;
QString m_ctestPath; QString m_ctestPath;
QString m_cmakeGenerator;
bool m_isMultiConfig = false; bool m_isMultiConfig = false;
bool m_usesAllCapsTargets = false; bool m_usesAllCapsTargets = false;
int m_lastCMakeExitCode = 0; int m_lastCMakeExitCode = 0;