forked from qt-creator/qt-creator
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:
@@ -1663,6 +1663,36 @@ void CMakeBuildConfiguration::buildTarget(const QString &buildTarget)
|
||||
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
|
||||
{
|
||||
return m_configurationFromCMake;
|
||||
|
@@ -66,6 +66,7 @@ public:
|
||||
|
||||
// Context menu action:
|
||||
void buildTarget(const QString &buildTarget);
|
||||
void reBuildTarget(const QString &cleanTarget, const QString &buildTarget);
|
||||
ProjectExplorer::BuildSystem *buildSystem() const final;
|
||||
|
||||
void addToEnvironment(Utils::Environment &env) const override;
|
||||
|
@@ -443,22 +443,50 @@ CommandLine CMakeBuildStep::cmakeCommand() const
|
||||
project = buildConfiguration()->project();
|
||||
}
|
||||
|
||||
cmd.addArgs(
|
||||
{"--build",
|
||||
CMakeToolManager::mappedFilePath(project, buildDirectory).path()});
|
||||
auto bs = qobject_cast<CMakeBuildSystem *>(buildSystem());
|
||||
const bool hasSubprojectBuild = bs && bs->hasSubprojectBuildSupport();
|
||||
bool ninjaSubprojectClean = false;
|
||||
|
||||
cmd.addArg("--target");
|
||||
cmd.addArgs(Utils::transform(m_buildTargets, [this](const QString &s) {
|
||||
if (s.isEmpty()) {
|
||||
if (RunConfiguration *rc = target()->activeRunConfiguration())
|
||||
return rc->buildKey();
|
||||
// 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(
|
||||
{"--build",
|
||||
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);
|
||||
}
|
||||
return s;
|
||||
}));
|
||||
} else {
|
||||
cmd.addArgs({"--build", CMakeToolManager::mappedFilePath(project, buildDirectory).path()});
|
||||
|
||||
cmd.addArg("--target");
|
||||
cmd.addArgs(Utils::transform(m_buildTargets, [this](const QString &s) {
|
||||
if (s.isEmpty()) {
|
||||
if (RunConfiguration *rc = target()->activeRunConfiguration())
|
||||
return rc->buildKey();
|
||||
}
|
||||
return s;
|
||||
}));
|
||||
}
|
||||
if (useStaging())
|
||||
cmd.addArg("install");
|
||||
|
||||
auto bs = qobject_cast<CMakeBuildSystem *>(buildSystem());
|
||||
if (bs && bs->isMultiConfigReader()) {
|
||||
cmd.addArg("--config");
|
||||
if (m_configuration)
|
||||
@@ -483,6 +511,12 @@ CommandLine CMakeBuildStep::cmakeCommand() const
|
||||
cmd.addArgs("-allowProvisioningUpdates", CommandLine::Raw);
|
||||
}
|
||||
|
||||
if (ninjaSubprojectClean) {
|
||||
if (!toolArgumentsSpecified)
|
||||
cmd.addArg("--");
|
||||
cmd.addArgs({"-t", "clean"});
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
@@ -839,6 +839,16 @@ CMakeBuildSystem::projectFileArgumentPosition(const QString &targetName, const Q
|
||||
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,
|
||||
const FilePaths &filePaths,
|
||||
FilePaths *notRemoved)
|
||||
@@ -1193,6 +1203,13 @@ void CMakeBuildSystem::buildCMakeTarget(const QString &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()
|
||||
{
|
||||
BuildDirParameters parameters(this);
|
||||
|
@@ -81,6 +81,7 @@ public:
|
||||
|
||||
// Context menu actions:
|
||||
void buildCMakeTarget(const QString &buildTarget);
|
||||
void reBuildCMakeTarget(const QString &cleanTarget, const QString &buildTarget);
|
||||
|
||||
// Queries:
|
||||
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> &findPackagesFilesHash() const { return m_findPackagesFilesHash; }
|
||||
|
||||
QString cmakeGenerator() const;
|
||||
bool hasSubprojectBuildSupport() const;
|
||||
|
||||
signals:
|
||||
void configurationCleared();
|
||||
void configurationChanged(const CMakeConfig &config);
|
||||
|
@@ -19,6 +19,12 @@ const char BUILD_FILE[] = "CMakeProject.BuildFile";
|
||||
const char CMAKE_HOME_DIR[] = "CMakeProject.HomeDirectory";
|
||||
const char QML_DEBUG_SETTING[] = "CMakeProject.EnableQmlDebugging";
|
||||
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_GENERAL_GROUP[] = "General";
|
||||
|
@@ -72,6 +72,10 @@ private:
|
||||
void updateBuildFileAction();
|
||||
void enableBuildFileMenus(Node *node);
|
||||
void reloadCMakePresets();
|
||||
void enableBuildSubprojectContextMenu(Node *node);
|
||||
void enableBuildSubprojectMenu();
|
||||
void runSubprojectOperation(const QString &clean, const QString &build);
|
||||
CMakeListsNode* currentListsNodeForEditor();
|
||||
|
||||
QAction *m_runCMakeAction;
|
||||
QAction *m_clearCMakeCacheAction;
|
||||
@@ -85,6 +89,12 @@ private:
|
||||
QAction *m_cmakeDebuggerAction;
|
||||
QAction *m_cmakeDebuggerSeparator;
|
||||
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)
|
||||
@@ -182,6 +192,66 @@ CMakeManager::CMakeManager()
|
||||
.addToContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_BUILD)
|
||||
.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
|
||||
ActionBuilder(this, Constants::RUN_CMAKE_PROFILER)
|
||||
.setIcon(ProjectExplorer::Icons::CMAKE_LOGO.icon())
|
||||
@@ -225,8 +295,10 @@ CMakeManager::CMakeManager()
|
||||
connect(BuildManager::instance(), &BuildManager::buildStateChanged, this, [this] {
|
||||
updateCmakeActions(ProjectTree::currentNode());
|
||||
});
|
||||
connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
|
||||
this, &CMakeManager::updateBuildFileAction);
|
||||
connect(EditorManager::instance(), &EditorManager::currentEditorChanged, this, [this]() {
|
||||
updateBuildFileAction();
|
||||
enableBuildSubprojectMenu();
|
||||
});
|
||||
connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged,
|
||||
this, &CMakeManager::updateCmakeActions);
|
||||
|
||||
@@ -257,6 +329,7 @@ void CMakeManager::updateCmakeActions(Node *node)
|
||||
m_reloadCMakePresetsAction->setVisible(reloadPresetsVisible);
|
||||
|
||||
enableBuildFileMenus(node);
|
||||
enableBuildSubprojectContextMenu(node);
|
||||
}
|
||||
|
||||
void CMakeManager::clearCMakeCache(BuildSystem *buildSystem)
|
||||
@@ -409,6 +482,93 @@ void CMakeManager::reloadCMakePresets()
|
||||
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)
|
||||
{
|
||||
if (!node) {
|
||||
|
@@ -74,6 +74,16 @@ CMakePresetsNode::CMakePresetsNode(const FilePath &projectPath) :
|
||||
setListInProject(false);
|
||||
}
|
||||
|
||||
bool CMakeListsNode::hasSubprojectBuildSupport() const
|
||||
{
|
||||
return m_hasSubprojectBuildSupport;
|
||||
}
|
||||
|
||||
void CMakeListsNode::setHasSubprojectBuildSupport(bool hasSubprojectBuildSupport)
|
||||
{
|
||||
m_hasSubprojectBuildSupport = hasSubprojectBuildSupport;
|
||||
}
|
||||
|
||||
CMakeListsNode::CMakeListsNode(const FilePath &cmakeListPath) :
|
||||
ProjectExplorer::ProjectNode(cmakeListPath)
|
||||
{
|
||||
|
@@ -23,6 +23,8 @@ public:
|
||||
|
||||
class CMakeListsNode : public ProjectExplorer::ProjectNode
|
||||
{
|
||||
bool m_hasSubprojectBuildSupport{false};
|
||||
|
||||
public:
|
||||
CMakeListsNode(const Utils::FilePath &cmakeListPath);
|
||||
|
||||
@@ -32,6 +34,9 @@ public:
|
||||
bool canAddSubProject(const Utils::FilePath &subProjectFilePath) const override;
|
||||
bool addSubProject(const Utils::FilePath &subProjectFilePath) override;
|
||||
QStringList subProjectFileNamePatterns() const override;
|
||||
|
||||
bool hasSubprojectBuildSupport() const;
|
||||
void setHasSubprojectBuildSupport(bool hasSubprojectBuildSupport);
|
||||
};
|
||||
|
||||
class CMakeProjectNode : public ProjectExplorer::ProjectNode
|
||||
|
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
#include <projectexplorer/buildmanager.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
@@ -111,13 +112,16 @@ class CMakeProjectPlugin final : public ExtensionSystem::IPlugin
|
||||
|
||||
void updateContextActions(ProjectExplorer::Node *node)
|
||||
{
|
||||
const Project *project = ProjectTree::projectForNode(node);
|
||||
|
||||
auto targetNode = dynamic_cast<const CMakeTargetNode *>(node);
|
||||
const QString targetDisplayName = targetNode ? targetNode->displayName() : QString();
|
||||
const bool isVisible = targetNode && !BuildManager::isBuilding(project);
|
||||
|
||||
// Build Target:
|
||||
m_buildTargetContextAction->setParameter(targetDisplayName);
|
||||
m_buildTargetContextAction->setEnabled(targetNode);
|
||||
m_buildTargetContextAction->setVisible(targetNode);
|
||||
m_buildTargetContextAction->setEnabled(isVisible);
|
||||
m_buildTargetContextAction->setVisible(isVisible);
|
||||
}
|
||||
|
||||
Action *m_buildTargetContextAction = nullptr;
|
||||
|
@@ -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:
|
||||
// --------------------------------------------------------------------
|
||||
@@ -1018,11 +1032,13 @@ FileApiQtcData extractData(const QFuture<void> &cancelFuture, FileApiData &input
|
||||
return {};
|
||||
|
||||
result.ctestPath = input.replyFile.ctestExecutable;
|
||||
result.cmakeGenerator = input.replyFile.generator;
|
||||
result.isMultiConfig = input.replyFile.isMultiConfig;
|
||||
if (input.replyFile.isMultiConfig && input.replyFile.generator != "Ninja Multi-Config")
|
||||
result.usesAllCapsTargets = true;
|
||||
|
||||
markCMakeModulesFromPrefixPathAsGenerated(result);
|
||||
setSubprojectBuildSupport(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -48,6 +48,7 @@ public:
|
||||
ProjectExplorer::RawProjectParts projectParts;
|
||||
std::unique_ptr<CMakeProjectNode> rootProjectNode;
|
||||
QString ctestPath;
|
||||
QString cmakeGenerator;
|
||||
bool isMultiConfig = false;
|
||||
bool usesAllCapsTargets = false;
|
||||
};
|
||||
|
@@ -290,6 +290,7 @@ void FileApiReader::endState(const FilePath &replyFilePath, bool restoredFromBac
|
||||
m_ctestPath = std::move(value->ctestPath);
|
||||
m_isMultiConfig = value->isMultiConfig;
|
||||
m_usesAllCapsTargets = value->usesAllCapsTargets;
|
||||
m_cmakeGenerator = value->cmakeGenerator;
|
||||
|
||||
if (value->errorMessage.isEmpty()) {
|
||||
emit this->dataAvailable(restoredFromBackup);
|
||||
@@ -347,6 +348,11 @@ void FileApiReader::writeConfigurationIntoBuildDirectory(const QStringList &conf
|
||||
QTC_ASSERT_EXPECTED(settingsFile.writeFileContents(contents), return);
|
||||
}
|
||||
|
||||
QString FileApiReader::cmakeGenerator() const
|
||||
{
|
||||
return m_cmakeGenerator;
|
||||
}
|
||||
|
||||
std::unique_ptr<CMakeProjectNode> FileApiReader::rootProjectNode()
|
||||
{
|
||||
return std::exchange(m_rootProjectNode, {});
|
||||
|
@@ -63,6 +63,8 @@ public:
|
||||
|
||||
Utils::FilePath topCmakeFile() const;
|
||||
|
||||
QString cmakeGenerator() const;
|
||||
|
||||
signals:
|
||||
void configurationStarted() const;
|
||||
void dataAvailable(bool restoredFromBackup) const;
|
||||
@@ -90,6 +92,7 @@ private:
|
||||
ProjectExplorer::RawProjectParts m_projectParts;
|
||||
std::unique_ptr<CMakeProjectNode> m_rootProjectNode;
|
||||
QString m_ctestPath;
|
||||
QString m_cmakeGenerator;
|
||||
bool m_isMultiConfig = false;
|
||||
bool m_usesAllCapsTargets = false;
|
||||
int m_lastCMakeExitCode = 0;
|
||||
|
Reference in New Issue
Block a user