diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index c76af32e775..9bb7837dd9e 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -33,6 +33,8 @@ namespace CMakeProjectManager::Internal { static Q_LOGGING_CATEGORY(cmakeLogger, "qtc.cmake.fileApiExtractor", QtWarningMsg); +static const char QTC_RUNNABLE[] = "qtc_runnable"; + // -------------------------------------------------------------------- // Helpers: // -------------------------------------------------------------------- @@ -275,7 +277,8 @@ static CMakeBuildTarget toBuildTarget(const TargetDetails &t, || f.fragment.contains("Qt6Gui")); }); - ct.qtcRunnable = t.folderTargetProperty == "qtc_runnable"; + // FIXME: remove the usage of "qtc_runnable" by parsing the CMake code instead + ct.qtcRunnable = t.folderTargetProperty == QTC_RUNNABLE; // Extract library directories for executables: for (const FragmentInfo &f : t.link.value().fragments) { @@ -761,7 +764,8 @@ static void addGeneratedFilesNode(ProjectNode *targetRoot, const FilePath &topLe addCMakeVFolder(targetRoot, buildDir, 10, Tr::tr(""), std::move(nodes)); } -static void addTargets(const QFuture &cancelFuture, +static void addTargets(FolderNode *root, + const QFuture &cancelFuture, const QHash &cmakeListsNodes, const Configuration &config, const std::vector &targetDetails, @@ -772,23 +776,55 @@ static void addTargets(const QFuture &cancelFuture, for (const TargetDetails &t : targetDetails) targetDetailsHash.insert(t.id, &t); const TargetDetails defaultTargetDetails; - auto getTargetDetails = [&targetDetailsHash, &defaultTargetDetails](const QString &id) - -> const TargetDetails & { + auto getTargetDetails = [&targetDetailsHash, + &defaultTargetDetails](const QString &id) -> const TargetDetails & { auto it = targetDetailsHash.constFind(id); if (it != targetDetailsHash.constEnd()) return *it.value(); return defaultTargetDetails; }; + auto createTargetNode = [](auto &cmakeListsNodes, + const Utils::FilePath &dir, + const QString &displayName) -> CMakeTargetNode * { + auto *cmln = cmakeListsNodes.value(dir); + QTC_ASSERT(cmln, return nullptr); + + QString targetId = displayName; + + CMakeTargetNode *tn = static_cast( + cmln->findNode([&targetId](const Node *n) { return n->buildKey() == targetId; })); + if (!tn) { + auto newNode = std::make_unique(dir, displayName); + tn = newNode.get(); + cmln->addNode(std::move(newNode)); + } + tn->setDisplayName(displayName); + return tn; + }; + + QHash folderNodes; + for (const FileApiDetails::Target &t : config.targets) { if (cancelFuture.isCanceled()) return; const TargetDetails &td = getTargetDetails(t.id); + CMakeTargetNode *tNode{nullptr}; const FilePath dir = directorySourceDir(config, sourceDir, t.directory); - CMakeTargetNode *tNode = createTargetNode(cmakeListsNodes, dir, t.name); + // FIXME: remove the usage of "qtc_runnable" by parsing the CMake code instead + if (!td.folderTargetProperty.isEmpty() && td.folderTargetProperty != QTC_RUNNABLE) { + const FilePath folderDir = FilePath::fromString(td.folderTargetProperty); + if (!folderNodes.contains(folderDir)) + folderNodes.insert( + folderDir, createSourceGroupNode(td.folderTargetProperty, folderDir, root)); + + tNode = createTargetNode(folderNodes, folderDir, t.name); + } else { + tNode = createTargetNode(cmakeListsNodes, dir, t.name); + } QTC_ASSERT(tNode, continue); tNode->setTargetInformation(td.artifacts, td.type); @@ -821,7 +857,8 @@ static std::unique_ptr generateRootProjectNode(const QFuture &cmakeListsNo pn->setDisplayName(displayName); } -CMakeTargetNode *createTargetNode(const QHash &cmakeListsNodes, - const Utils::FilePath &dir, - const QString &displayName) -{ - ProjectNode *cmln = cmakeListsNodes.value(dir); - QTC_ASSERT(cmln, return nullptr); - - QString targetId = displayName; - - CMakeTargetNode *tn = static_cast( - cmln->findNode([&targetId](const Node *n) { return n->buildKey() == targetId; })); - if (!tn) { - auto newNode = std::make_unique(dir, displayName); - tn = newNode.get(); - cmln->addNode(std::move(newNode)); - } - tn->setDisplayName(displayName); - return tn; -} - template static std::unique_ptr cloneFolderNode(FolderNode *node) { diff --git a/src/plugins/cmakeprojectmanager/projecttreehelper.h b/src/plugins/cmakeprojectmanager/projecttreehelper.h index 35f7cf16a43..b3d1c2d58bd 100644 --- a/src/plugins/cmakeprojectmanager/projecttreehelper.h +++ b/src/plugins/cmakeprojectmanager/projecttreehelper.h @@ -43,10 +43,6 @@ QHash addCMakeLists( void createProjectNode(const QHash &cmakeListsNodes, const Utils::FilePath &dir, const QString &displayName); -CMakeTargetNode *createTargetNode( - const QHash &cmakeListsNodes, - const Utils::FilePath &dir, - const QString &displayName); void addFileSystemNodes(ProjectExplorer::ProjectNode *root, const std::shared_ptr &folderNode); diff --git a/tests/manual/cmakeprojectmanager/hello-widgets/CMakeLists.txt b/tests/manual/cmakeprojectmanager/hello-widgets/CMakeLists.txt index 8c0c413d663..77193e0be94 100644 --- a/tests/manual/cmakeprojectmanager/hello-widgets/CMakeLists.txt +++ b/tests/manual/cmakeprojectmanager/hello-widgets/CMakeLists.txt @@ -35,3 +35,4 @@ file(GLOB SOURCE_FILES CONFIGURE_DEPENDS *.cpp *.h *.ui) add_executable(hello-widgets-glob ${SOURCE_FILES}) target_link_libraries(hello-widgets-glob PRIVATE Qt6::Widgets) +set_target_properties(hello-widgets-glob PROPERTIES FOLDER "Glob")