diff --git a/CMakeLists.txt b/CMakeLists.txt index b6eea00..69686aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,53 +1,72 @@ +cmake_minimum_required(VERSION 3.0.0) + project(kdevkernel) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) -find_package(KDE4 4.7.0 REQUIRED) -find_package(KDevPlatform 1.2.60 REQUIRED) +find_package(ECM REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +# TODO Check these min versions +set(MIN_KDEV_VERSION "5.1.80") +set(MIN_QT_VER "5.5.0") +set(MIN_KF_VER "5.15.0") + +# Find what is the prefix of the KDevelop installation +set(KDevelop_Include_DIR "include/kdevelop") +find_path(KDevelop_PREFIX ${KDevelop_Include_DIR}) +set(KDevelop_Include_Full_DIR ${KDevelop_PREFIX}/${KDevelop_Include_DIR}) +message(STATUS "KDevelop headers : " ${KDevelop_Include_Full_DIR}) + +set(KDevPlatform_Include_DIR "include/kdevplatform") +set(KDevPlatform_Include_Full_DIR ${KDevelop_PREFIX}/${KDevPlatform_Include_DIR}) +message(STATUS "KDevPlatform headers : " ${KDevPlatform_Include_Full_DIR}) + +include(KDECompilerSettings NO_POLICY_SCOPE) +include(ECMAddTests) +include(ECMInstallIcons) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(FeatureSummary) + +find_package(Qt5 ${MIN_QT_VER} CONFIG REQUIRED Core Gui Widgets Test) +find_package(KF5 ${MIN_KF_VER} REQUIRED COMPONENTS ItemModels TextEditor) +find_package(KDevelop ${MIN_KDEV_VERSION} REQUIRED) +find_package(KDevPlatform ${MIN_KDEV_VERSION} REQUIRED CONFIG) include_directories( - ${KDE4_INCLUDES} - ${KDEVPLATFORM_INCLUDE_DIR} - ${KDEVPLATFORM_INCLUDE_DIR}/../kdevelop + ${KDevPlatform_Include_Full_DIR} + ${KDevelop_Include_Full_DIR} + ${KDevPlatform_DIR} + ${KDevelop_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} - ${CMAKE_PREFIX_PATH}/include/kdevelop ) set(kdevkernel_plugin_SRCS kdevkernelplugin.cpp -) -kde4_add_plugin(kdevkernel - ${kdevkernel_plugin_SRCS}) -target_link_libraries(kdevkernel - ${KDEVPLATFORM_PROJECT_LIBRARIES} - ${KDEVPLATFORM_INTERFACES_LIBRARIES} - ${KDEVPLATFORM_UTIL_LIBRARIES} - ${KDEVPLATFORM_OUTPUTVIEW_LIBRARIES} + config/projectconfigpage.cpp ) -set (kdevkernel_kcm_SRCS - kcm_kdevkernel.cpp - kdevkernelconfigwidget.cpp +ki18n_wrap_ui(kdevkernel_plugin_SRCS + config/projectconfigpage.ui ) -kde4_add_ui_files(kdevkernel_kcm_SRCS kdevkernelconfigwidget.ui) -kde4_add_kcfg_files(kdevkernel_kcm_SRCS kcfg_kdevkernelconfig.kcfgc) -kde4_add_plugin(kcm_kdevkernel ${kdevkernel_kcm_SRCS}) -target_link_libraries(kcm_kdevkernel ${KDE4_KIO_LIBS} ${KDEVPLATFORM_INTERFACES_LIBRARIES} ${KDEVPLATFORM_LANGUAGE_LIBRARIES} ${KDEVPLATFORM_PROJECT_LIBRARIES} ${KDEVPLATFORM_UTIL_LIBRARIES}) - -install( - TARGETS kdevkernel - kcm_kdevkernel - DESTINATION ${PLUGIN_INSTALL_DIR} +kconfig_add_kcfg_files(kdevkernel_plugin_SRCS + config/projectconfig.kcfgc ) -install( - FILES kdevkernel.desktop - kcm_kdevkernel.desktop - DESTINATION ${SERVICES_INSTALL_DIR} +kdevplatform_add_plugin(kdevkernel JSON kdevkernel.json SOURCES ${kdevkernel_plugin_SRCS}) + +target_link_libraries(kdevkernel + KDev::Interfaces + KDev::Project + KDev::OutputView + KDev::Util ) add_subdirectory(icons) +feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/README.md b/README.md index 98363c7..3f51ab3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ KDevelop Linux Kernel Development Plugin ======================================== +## This branch contains ported code to KF5/Qt5/KDevelop 5. It generally works but with a lot of bugs! + This plugin offers a "Linux Kernel" project type to KDevelop that makes it easy and comfortable to work on the Linux kernel. The raw KDevelop comes with extremely useful cross-reference and code parsing tools, but they do not apply well to the Linux kernel. Problems are: diff --git a/config/projectconfig.kcfg b/config/projectconfig.kcfg new file mode 100644 index 0000000..9e51dc2 --- /dev/null +++ b/config/projectconfig.kcfg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/projectconfig.kcfgc b/config/projectconfig.kcfgc new file mode 100644 index 0000000..5e56787 --- /dev/null +++ b/config/projectconfig.kcfgc @@ -0,0 +1,3 @@ +File=projectconfig.kcfg +NameSpace=KDevKernel +ClassName=ProjectConfig diff --git a/config/projectconfigpage.cpp b/config/projectconfigpage.cpp new file mode 100644 index 0000000..e736771 --- /dev/null +++ b/config/projectconfigpage.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2012 Alexandre Courbot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "projectconfigpage.h" +#include "ui_projectconfigpage.h" + +#include "../kdevkernelconfig.h" + +#include "projectconfig.h" + +#include +#include + +namespace KDevKernel +{ + +ProjectConfigPage::ProjectConfigPage(KDevelop::IPlugin* plugin, KDevelop::IProject* project, QWidget* parent) + : ConfigPage(plugin, new ProjectConfig, parent) + , ui(new Ui::ProjectConfigPage) +{ + this->project = project; + + configSkeleton()->setSharedConfig(project->projectConfiguration()); + configSkeleton()->load(); + + ui->setupUi(this); + + connect(ui->kcfg_arch, QOverload::of(&KComboBox::currentIndexChanged), this, &ProjectConfigPage::archChanged); +} + +ProjectConfigPage::~ProjectConfigPage() = default; + +QString ProjectConfigPage::name() const +{ + return i18n("kdev-kernel"); +} + +QString ProjectConfigPage::fullName() const +{ + return i18n("Linux Kernel Project Manager"); +} + +QIcon ProjectConfigPage::icon() const +{ + return QIcon::fromTheme(QStringLiteral("kdevkernel")); +} + +void ProjectConfigPage::apply() +{ + KConfigGroup cg = configSkeleton()->sharedConfig()->group(KERN_KGROUP); + KDevelop::Path projectRoot = project->path(); + + if (!ui->kcfg_buildDir->url().isEmpty()) + cg.writeEntry(KERN_BDIR, ui->kcfg_buildDir->url()); + else cg.deleteEntry(KERN_BDIR); + + cg.writeEntry(KERN_ARCH, ui->kcfg_arch->currentText()); + + if (!ui->kcfg_crossCompiler->url().isEmpty()) { + QString cc(ui->kcfg_crossCompiler->url().toLocalFile()); + cc.remove("file://"); + + if (cc.endsWith("gcc")) { + QString crossPrefix(cc.mid(0, cc.size() - 3)); + cg.writeEntry(KERN_CROSS, crossPrefix); + } else { + // TODO notify error + } + } else cg.deleteEntry(KERN_CROSS); + + // Remove the .config file if configuration changed. This will trigger + // the corresponding make rule from the plugin the next time we parse. + if (ui->kcfg_defconfig->currentText() != cg.readEntry(KERN_DEFCONFIG, "")) { + KDevelop::Path buildDir(cg.readEntry(KERN_BDIR, projectRoot.toUrl())); +// buildDir.adjustPath(KUrl::AddTrailingSlash); + QFile dotConfig(KDevelop::Path(buildDir, ".config").toLocalFile()); + if (dotConfig.exists()) dotConfig.remove(); + } + + cg.writeEntry(KERN_DEFCONFIG, ui->kcfg_defconfig->currentText()); + + ConfigPage::apply(); +} + +void ProjectConfigPage::reset() +{ + KConfigGroup cg = configSkeleton()->sharedConfig()->group(KERN_KGROUP); + + // Fill in the arch values + KDevelop::Path projectRoot = project->path(); + QDir archDir(KDevelop::Path(projectRoot, "arch").toLocalFile()); + archDir.setFilter(QDir::Dirs); + foreach (const QString &archEntry, archDir.entryList()) { + if (archEntry.startsWith('.')) continue; + ui->kcfg_arch->addItem(archEntry); + } + + ui->kcfg_buildDir->setStartDir(projectRoot.toUrl()); + ui->kcfg_crossCompiler->setStartDir(QUrl("/usr/bin/")); + + ConfigPage::reset(); +} + +void ProjectConfigPage::archChanged(const QString &arch) +{ + ui->kcfg_defconfig->clear(); + + QUrl projectRoot = project->path().toUrl(); + projectRoot.setPath(projectRoot.path() + "/"); + QDir configDirs(projectRoot.resolved(QUrl(QString("arch/%1/configs").arg(arch))).toLocalFile()); + foreach (const QString &configFile, configDirs.entryList()) { + if (configFile.startsWith('.')) continue; + ui->kcfg_defconfig->addItem(configFile.left(configFile.size() - QString("_defconfig").size())); + } +} + +} diff --git a/kdevkernelconfigwidget.h b/config/projectconfigpage.h similarity index 55% rename from kdevkernelconfigwidget.h rename to config/projectconfigpage.h index e9eb7ca..95f6074 100644 --- a/kdevkernelconfigwidget.h +++ b/config/projectconfigpage.h @@ -15,39 +15,48 @@ * along with this program. If not, see . */ -#ifndef KDEVKERNELCONFIGWIDGET_H -#define KDEVKERNELCONFIGWIDGET_H +#ifndef KDEVKERNEL_PROJECTCONFIGPAGE_H +#define KDEVKERNEL_PROJECTCONFIGPAGE_H -#include -#include "ui_kdevkernelconfigwidget.h" - -#include -#include - -class KConfig; +#include "interfaces/configpage.h" namespace KDevelop { class IProject; +class Path; } -class KDevKernelConfigWidget : public QWidget, public Ui::KDevKernelConfigWidget +namespace KDevKernel +{ + +namespace Ui +{ +class ProjectConfigPage; +} + +class ProjectConfigPage : public KDevelop::ConfigPage { Q_OBJECT + public: - KDevKernelConfigWidget(QWidget *parent, const QString &projectRoot); - void loadFrom(KConfig *config); - void saveTo(KConfig *config, KDevelop::IProject *project); - void loadDefaults(); + ProjectConfigPage(KDevelop::IPlugin* plugin, KDevelop::IProject* project, QWidget* parent); + ~ProjectConfigPage() override; + + QString name() const override; + QString fullName() const override; + QIcon icon() const override; -signals: - void changed(); + void apply() override; + void reset() override; -private slots: +private Q_SLOTS: void archChanged(const QString &arch); private: - const QString _projectRoot; + QScopedPointer ui; + KDevelop::IProject* project; }; -#endif +} + +#endif // KDEVKERNEL_PROJECTCONFIGPAGE_H diff --git a/kdevkernelconfigwidget.ui b/config/projectconfigpage.ui similarity index 84% rename from kdevkernelconfigwidget.ui rename to config/projectconfigpage.ui index bb11d65..ae5ffdf 100644 --- a/kdevkernelconfigwidget.ui +++ b/config/projectconfigpage.ui @@ -1,13 +1,13 @@ - KDevKernelConfigWidget - + KDevKernel::ProjectConfigPage + 0 0 362 - 308 + 318 @@ -23,18 +23,18 @@ - You can specify a build directory if you build your kernel out of source. + &You can specify a build directory if you build your kernel out of source. true - buildDir + kcfg_buildDir - + KFile::Directory|KFile::LocalOnly @@ -59,7 +59,7 @@ - + Target architecture of the kernel. This will set the ARCH variable accordingly. @@ -77,7 +77,7 @@ - + @@ -91,7 +91,7 @@ - + @@ -119,7 +119,7 @@ KUrlRequester - QFrame + QWidget
kurlrequester.h
diff --git a/icons/hi128-app-linux.png b/icons/128-apps-kdevkernel.png similarity index 100% rename from icons/hi128-app-linux.png rename to icons/128-apps-kdevkernel.png diff --git a/icons/hi16-app-linux.png b/icons/16-apps-kdevkernel.png similarity index 100% rename from icons/hi16-app-linux.png rename to icons/16-apps-kdevkernel.png diff --git a/icons/hi32-app-linux.png b/icons/32-apps-kdevkernel.png similarity index 100% rename from icons/hi32-app-linux.png rename to icons/32-apps-kdevkernel.png diff --git a/icons/hi64-app-linux.png b/icons/64-apps-kdevkernel.png similarity index 100% rename from icons/hi64-app-linux.png rename to icons/64-apps-kdevkernel.png diff --git a/icons/CMakeLists.txt b/icons/CMakeLists.txt index 1cc0772..564fff2 100644 --- a/icons/CMakeLists.txt +++ b/icons/CMakeLists.txt @@ -1,2 +1,8 @@ -kde4_install_icons(${ICON_INSTALL_DIR}) - +ecm_install_icons(ICONS + 128-apps-kdevkernel.png + 16-apps-kdevkernel.png + 32-apps-kdevkernel.png + 64-apps-kdevkernel.png + DESTINATION ${ICON_INSTALL_DIR} + THEME hicolor +) diff --git a/kcfg_kdevkernelconfig.kcfg b/kcfg_kdevkernelconfig.kcfg deleted file mode 100644 index 5d258ed..0000000 --- a/kcfg_kdevkernelconfig.kcfg +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/kcfg_kdevkernelconfig.kcfgc b/kcfg_kdevkernelconfig.kcfgc deleted file mode 100644 index 312f586..0000000 --- a/kcfg_kdevkernelconfig.kcfgc +++ /dev/null @@ -1,5 +0,0 @@ -File=kcfg_kdevkernelconfig.kcfg -ClassName=KDevKernelConfig -Singleton=true -Inherits=KDevelop::ProjectConfigSkeleton -IncludeFiles=project/projectconfigskeleton.h diff --git a/kcm_kdevkernel.cpp b/kcm_kdevkernel.cpp deleted file mode 100644 index f758815..0000000 --- a/kcm_kdevkernel.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2012 Alexandre Courbot - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "kcm_kdevkernel.h" - -#include -#include -#include -#include - -#include "kdevkernelconfigwidget.h" -#include "kcfg_kdevkernelconfig.h" - -K_PLUGIN_FACTORY(KDevKernelKCModuleFactory, registerPlugin(); ) -K_EXPORT_PLUGIN(KDevKernelKCModuleFactory("kcm_kdevkernel", "kdevkernel")) - -KDevKernelKCModule::KDevKernelKCModule(QWidget *parent, const QVariantList &args) - : ProjectKCModule(KDevKernelKCModuleFactory::componentData(), parent, args) -{ - QVBoxLayout *layout = new QVBoxLayout(this); - configWidget = new KDevKernelConfigWidget(this, KUrl(args.at(2).toString()).directory()); - connect(configWidget, SIGNAL(changed()), SLOT(dataChanged())); - layout->addWidget(configWidget); - - addConfig(KDevKernelConfig::self(), configWidget); -} - -void KDevKernelKCModule::dataChanged() -{ - emit changed(true); -} - -KDevKernelKCModule::~KDevKernelKCModule() -{ -} - -void KDevKernelKCModule::defaults() -{ - KCModule::defaults(); - configWidget->loadDefaults(); -} - -void KDevKernelKCModule::save() -{ - KCModule::save(); - configWidget->saveTo(KDevKernelConfig::self()->config(), project()); -} - -void KDevKernelKCModule::load() -{ - KCModule::load(); - configWidget->loadFrom(KDevKernelConfig::self()->config()); -} - -#include "kcm_kdevkernel.moc" diff --git a/kcm_kdevkernel.desktop b/kcm_kdevkernel.desktop deleted file mode 100644 index 4d60964..0000000 --- a/kcm_kdevkernel.desktop +++ /dev/null @@ -1,13 +0,0 @@ -[Desktop Entry] -Icon=linux -Type=Service -ServiceTypes=KCModule - -X-KDE-ModuleType=Library -X-KDE-Library=kcm_kdevkernel -X-KDE-ParentApp=kdevplatformproject -X-KDE-ParentComponents=KDevKernel -X-KDE-CfgDlgHierarchy=BUILDTOOL - -Name=Linux Kernel -Comment=Configure Linux Kernel Development Settings diff --git a/kcm_kdevkernel.h b/kcm_kdevkernel.h deleted file mode 100644 index b7dc545..0000000 --- a/kcm_kdevkernel.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2012 Alexandre Courbot - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef KCM_KDEVKERNEL_H -#define KCM_KDEVKERNEL_H - -#include -#include "kdevkernelplugin.h" - -class KDevKernelConfig; - -class KDevKernelKCModule : public ProjectKCModule -{ - Q_OBJECT -public: - KDevKernelKCModule(QWidget *parent, const QVariantList &args = QVariantList()); - virtual ~KDevKernelKCModule(); - - virtual void defaults(); - virtual void save(); - virtual void load(); - -public slots: - void dataChanged(); - -private: - class KDevKernelConfigWidget *configWidget; -}; - -#endif diff --git a/kdevkernel.desktop b/kdevkernel.desktop deleted file mode 100644 index ccaf1d9..0000000 --- a/kdevkernel.desktop +++ /dev/null @@ -1,19 +0,0 @@ -[Desktop Entry] -Type=Service -Name=Linux Kernel Project Manager -Comment=Project Manager for editing the Linux Kernel -Icon=linux -ServiceTypes=KDevelop/Plugin -GenericName=KernelPlugin -X-KDE-Library=kdevkernel -X-KDE-PluginInfo-Name=KDevKernel -X-KDE-PluginInfo-Author=Alexandre Courbot -X-KDE-PluginInfo-Email=gnurou@gmail.com -X-KDE-PluginInfo-License=GPL -X-KDE-PluginInfo-Category=Project Management -X-KDevelop-Version=17 -X-KDevelop-Category=Project -X-KDevelop-Interfaces=org.kdevelop.IProjectBuilder,org.kdevelop.IProjectFileManager,org.kdevelop.IBuildSystemManager -X-KDevelop-IRequired=org.kdevelop.IMakeBuilder -X-KDevelop-Mode=GUI -X-KDevelop-LoadMode=AlwaysOn diff --git a/kdevkernel.json b/kdevkernel.json new file mode 100644 index 0000000..7504ac8 --- /dev/null +++ b/kdevkernel.json @@ -0,0 +1,34 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "gnurou@gmail.com", + "Name": "Alexandre Courbot" + }, + { + "Email": "luca@z3ntu.xyz", + "Name": "Luca Weiss" + } + ], + "Category": "Project Management", + "Description": "Project Manager for editing the Linux Kernel", + "Icon": "kdevkernel", + "Id": "KDevKernel", + "License": "GPL", + "Name": "Linux Kernel Project Manager", + "ServiceTypes": [ + "KDevelop/Plugin" + ] + }, + "X-KDevelop-Category": "Project", + "X-KDevelop-IRequired": [ + "org.kdevelop.IMakeBuilder" + ], + "X-KDevelop-Interfaces": [ + "org.kdevelop.IProjectBuilder", + "org.kdevelop.IProjectFileManager", + "org.kdevelop.IBuildSystemManager" + ], + "X-KDevelop-LoadMode": "AlwaysOn", + "X-KDevelop-Mode": "GUI" +} diff --git a/kdevkernelconfigwidget.cpp b/kdevkernelconfigwidget.cpp deleted file mode 100644 index 54aed9e..0000000 --- a/kdevkernelconfigwidget.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2012 Alexandre Courbot - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "kdevkernelconfigwidget.h" -#include "kdevkernelconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -KDevKernelConfigWidget::KDevKernelConfigWidget(QWidget *parent, const QString &projectRoot) : QWidget(parent), _projectRoot(projectRoot) -{ - Ui::KDevKernelConfigWidget::setupUi(this); - - connect(buildDir, SIGNAL(textChanged(const QString &)), this, SIGNAL(changed())); - connect(arch, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed())); - connect(defconfig, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed())); - connect(arch, SIGNAL(currentIndexChanged(QString)), this, SLOT(archChanged(QString))); - connect(crossCompiler, SIGNAL(textChanged(const QString &)), this, SIGNAL(changed())); -} - -void KDevKernelConfigWidget::loadDefaults() -{ -} - -void KDevKernelConfigWidget::loadFrom(KConfig *config) -{ - KConfigGroup group(config->group(KERN_KGROUP)); - - // Fill in the arch values - KUrl pRoot(_projectRoot); - pRoot.adjustPath(KUrl::AddTrailingSlash); - QDir archDir(KUrl(pRoot, "arch").toLocalFile()); - archDir.setFilter(QDir::Dirs); - foreach (const QString &archEntry, archDir.entryList()) { - if (archEntry.startsWith('.')) continue; - arch->addItem(archEntry); - } - - if (group.hasKey(KERN_BDIR)) { - buildDir->setUrl(group.readEntry(KERN_BDIR, KUrl())); - } else { - buildDir->setStartDir(pRoot); - } - - if (group.hasKey(KERN_ARCH)) { - arch->setCurrentItem(group.readEntry(KERN_ARCH, "")); - } - - if (group.hasKey(KERN_DEFCONFIG)) { - defconfig->setCurrentItem(group.readEntry(KERN_DEFCONFIG, "")); - } - - if (group.hasKey(KERN_CROSS)) { - crossCompiler->setUrl(KUrl(group.readEntry(KERN_CROSS, "") + "gcc")); - } else { - crossCompiler->setStartDir(KUrl("/usr/bin/")); - } -} - -void KDevKernelConfigWidget::saveTo(KConfig *config, KDevelop::IProject *project) -{ - KConfigGroup group(config->group(KERN_KGROUP)); - - if (!buildDir->url().isEmpty()) - group.writeEntry(KERN_BDIR, buildDir->url()); - else group.deleteEntry(KERN_BDIR); - - group.writeEntry(KERN_ARCH, arch->currentText()); - - if (!crossCompiler->url().isEmpty()) { - QString cc(crossCompiler->url().toLocalFile()); - cc.remove("file://"); - - if (cc.endsWith("gcc")) { - QString crossPrefix(cc.mid(0, cc.size() - 3)); - group.writeEntry(KERN_CROSS, crossPrefix); - } else { - // TODO notify error - } - } else group.deleteEntry(KERN_CROSS); - - // Remove the .config file if configuration changed. This will trigger - // the corresponding make rule from the plugin the next time we parse. - if (defconfig->currentText() != group.readEntry(KERN_DEFCONFIG, "")) { - KUrl buildDir(group.readEntry(KERN_BDIR, _projectRoot)); - buildDir.adjustPath(KUrl::AddTrailingSlash); - QFile dotConfig(KUrl(buildDir, ".config").toLocalFile()); - if (dotConfig.exists()) dotConfig.remove(); - } - - group.writeEntry(KERN_DEFCONFIG, defconfig->currentText()); - - config->sync(); - - // For initial setup we get called with a null project. In this case KDev will - // do the parsing automatically anyway. - /*if (KDevelop::IProjectController::parseAllProjectSources() && project) { - KJob *parseProjectJob = new KDevelop::ParseProjectJob(project); - KDevelop::ICore::self()->runController()->registerJob(parseProjectJob); - }*/ -} - -void KDevKernelConfigWidget::archChanged (const QString &arch) -{ - defconfig->clear(); - - // Fill in the configs values - KUrl pRoot(_projectRoot); - pRoot.adjustPath(KUrl::AddTrailingSlash); - QDir configDirs(KUrl(pRoot, QString("arch/%1/configs").arg(arch)).toLocalFile()); - foreach (const QString &configFile, configDirs.entryList()) { - if (configFile.startsWith('.')) continue; - defconfig->addItem(configFile.left(configFile.size() - QString("_defconfig").size())); - } -} diff --git a/kdevkernelplugin.cpp b/kdevkernelplugin.cpp index e693f14..e37c63f 100644 --- a/kdevkernelplugin.cpp +++ b/kdevkernelplugin.cpp @@ -18,87 +18,76 @@ #include "kdevkernelplugin.h" #include "kdevkernelconfig.h" +#include "config/projectconfigpage.h" + #include #include #include #include #include #include +#include + #include #include #include +#include #include -#include +#include #include #include #include -K_PLUGIN_FACTORY(KernelProjectFactory, registerPlugin();) -K_EXPORT_PLUGIN(KernelProjectFactory( - KAboutData("kdevkernel", "kdevkernel", - ki18n("Linux Kernel"), - "0.1", - ki18n("Linux Kernel Project Manager"), - KAboutData::License_GPL, - ki18n("Copyright (C) 2011-2013 Alexandre Courbot "), - KLocalizedString(), - "", - "gnurou@gmail.com" - ) - )) +K_PLUGIN_FACTORY_WITH_JSON(KernelProjectFactory, "kdevkernel.json", registerPlugin();) KDevKernelPlugin::KDevKernelPlugin(QObject *parent, const QVariantList &args) - : KDevelop::AbstractFileManagerPlugin(KernelProjectFactory::componentData(), parent) + : KDevelop::AbstractFileManagerPlugin(QStringLiteral("kdevkernel"), parent, args) { Q_UNUSED(args); - KDEV_USE_EXTENSION_INTERFACE(KDevelop::IBuildSystemManager) - KDEV_USE_EXTENSION_INTERFACE(KDevelop::IProjectFileManager) - KDEV_USE_EXTENSION_INTERFACE(KDevelop::IProjectBuilder) IPlugin* i = core()->pluginController()->pluginForExtension("org.kdevelop.IMakeBuilder"); - if (i) - { - _builder = i->extension(); - } - - connect(core()->projectController(), SIGNAL(projectClosing(KDevelop::IProject *)), this, SLOT(projectClosing(KDevelop::IProject *))); + Q_ASSERT(i); + m_builder = i->extension(); + Q_ASSERT(m_builder); } -KDevelop::IProjectBuilder *KDevKernelPlugin::builder() const +KDevelop::IProjectBuilder* KDevKernelPlugin::builder() const { + /*Q_ASSERT(m_builder); // TODO I've seen this in kdevelop plugins, why doesn't this work? + return m_builder;*/ return (KDevelop::IProjectBuilder *)(this); } KDevelop::Path::List KDevKernelPlugin::includeDirectories(KDevelop::ProjectBaseItem *item) const { - return KDevelop::toPathList(includeDirectories(item->project())); + return includeDirectories(item->project()); } -KUrl::List KDevKernelPlugin::includeDirectories(KDevelop::IProject *project) const +KDevelop::Path::List KDevKernelPlugin::includeDirectories(KDevelop::IProject *project) const { - KUrl::List ret; - KUrl projectRoot = project->folder(); - KConfigGroup config(project->projectConfiguration()->group(KERN_KGROUP)); - KUrl bDir(KUrl(config.readEntry(KERN_BDIR, projectRoot))); - bDir.adjustPath(KUrl::AddTrailingSlash); + KDevelop::Path::List ret; + KDevelop::Path projectRoot = project->path(); + KConfigGroup cg = project->projectConfiguration()->group(KERN_KGROUP); + KDevelop::Path bDir(cg.readEntry(KERN_BDIR, projectRoot.toUrl())); +// bDir.adjustPath(QUrl::AddTrailingSlash); // TODO cache for better efficiency - this should be built when loading a project // or when config changes - ret << KUrl(projectRoot, "include"); + ret << KDevelop::Path(projectRoot, "include"); if (bDir != projectRoot) - ret << KUrl(bDir, "include"); + ret << KDevelop::Path(bDir, "include"); - if (config.hasKey(KERN_ARCH)) { - QString arch(config.readEntry(KERN_ARCH)); - KUrl archUrl(projectRoot, "arch/"); - ret << KUrl(projectRoot, QString("arch/%1/include").arg(arch)); + if (cg.hasKey(KERN_ARCH)) { + QString arch(cg.readEntry(KERN_ARCH)); + KDevelop::Path archUrl(projectRoot, "arch/"); + ret << KDevelop::Path(projectRoot, QString("arch/%1/include").arg(arch)); foreach (const QString & machDir, _machDirs[project]) { - ret << KUrl(projectRoot, QString("arch/%1/%2/include").arg(arch).arg(machDir)); + ret << KDevelop::Path(projectRoot, QString("arch/%1/%2/include").arg(arch).arg(machDir)); } // Build-specific generated includes - ret << KUrl(bDir, QString("arch/%1/include/generated").arg(arch)); + ret << KDevelop::Path(bDir, QString("arch/%1/include/generated").arg(arch)); } // TODO /usr/include and such should not be looked for @@ -106,12 +95,18 @@ KUrl::List KDevKernelPlugin::includeDirectories(KDevelop::IProject *project) con return ret; } +KDevelop::Path::List KDevKernelPlugin::frameworkDirectories(KDevelop::ProjectBaseItem *item) const +{ + Q_UNUSED(item) + return {}; +} + QHash KDevKernelPlugin::defines(KDevelop::ProjectBaseItem *item) const { return _defines[item->project()]; } -void KDevKernelPlugin::parseDotConfig(KDevelop::IProject *project, const KUrl &dotconfig, QHash &_defs) +void KDevKernelPlugin::parseDotConfig(KDevelop::IProject *project, const KDevelop::Path &dotconfig, QHash &_defs) { QFile dfile(dotconfig.toLocalFile()); static QRegExp def("(\\w+)=(\"?[^\\n]+\"?)\n?"); @@ -122,8 +117,8 @@ void KDevKernelPlugin::parseDotConfig(KDevelop::IProject *project, const KUrl &d // If the .config file does not exist, create it by invoking make. if (!dfile.exists()) { - KConfigGroup config(project->projectConfiguration()->group(KERN_KGROUP)); - QString conf(config.readEntry(KERN_DEFCONFIG, "")); + KConfigGroup cg = project->projectConfiguration()->group(KERN_KGROUP); + QString conf(cg.readEntry(KERN_DEFCONFIG, "")); if (!conf.isEmpty()) { MakeVariables makeVars(makeVarsForProject(project)); QStringList vars; @@ -134,7 +129,7 @@ void KDevKernelPlugin::parseDotConfig(KDevelop::IProject *project, const KUrl &d } vars += conf + "_defconfig"; KProcess *process = new KProcess(); - process->setWorkingDirectory(project->folder().toLocalFile()); + process->setWorkingDirectory(project->path().toLocalFile()); process->setProgram("make", vars); process->execute(); delete process; @@ -167,12 +162,12 @@ void KDevKernelPlugin::parseDotConfig(KDevelop::IProject *project, const KUrl &d // TODO This is crap. Valid files should be stored in the project directly, and every // directory/file with includes should have a list of the valid files it added, and which // get removed from the global list as we reparse the Makefile/source file. -void KDevKernelPlugin::parseMakefile(const KUrl &dir, KDevelop::IProject *project) const +void KDevKernelPlugin::parseMakefile(const KDevelop::Path &dir, KDevelop::IProject *project) const { static QRegExp objy("([\\w-]+)-([^+:= \t]*)[\t ]*\\+?:?=([^\\\\]+)\\\\?\n"); static QRegExp repl("\\$\\((\\w_+)\\)"); static QRegExp spTab("\t| "); - QFile makefile(KUrl(dir, "Makefile").toLocalFile()); + QFile makefile(KDevelop::Path(dir, "Makefile").toLocalFile()); ValidFilesList &validFiles = _validFiles[project][dir]; validFiles.lastUpdate = QDateTime::currentDateTime(); @@ -230,30 +225,30 @@ void KDevKernelPlugin::parseMakefile(const KUrl &dir, KDevelop::IProject *projec } } - KConfigGroup config(project->projectConfiguration()->group(KERN_KGROUP)); - QString archDir(QString("arch/%1/").arg(config.readEntry(KERN_ARCH))); + KConfigGroup cg = project->projectConfiguration()->group(KERN_KGROUP); + QString archDir(QString("arch/%1/").arg(cg.readEntry(KERN_ARCH))); foreach (QString file, files) { if (file.endsWith(".o")) file = file.mid(0, file.size() - 2) + ".c"; - else if (file.endsWith(".dtb")) file = file.mid(0, file.size() - 4) + ".dts"; + else if (file.endsWith(".dtb")) file = file.mid(0, file.size() - 4) + ".dts"; else if (file.endsWith("/")) file = file.left(file.size() - 1); // Some directories are specified from the source root in the arch dir if (dir.toLocalFile().endsWith(archDir) && file.startsWith(archDir)) - file = file.mid(archDir.size()); + file = file.mid(archDir.size()); // Sometimes files are referenced that are several directories below if (file.contains('/')) { - KUrl nFile(dir, file); - KUrl nDir(nFile.directory()); - // Add all the subdirectories - KUrl nDir2(nDir); - while (nDir2 != dir) { - QString f(nDir2.fileName()); - QString d(nDir2.directory() + "/"); - _validFiles[project][d].validFiles << f; - nDir2 = KUrl(d); - } - nDir.adjustPath(KUrl::AddTrailingSlash); - _validFiles[project][nDir].validFiles << nFile.fileName(); + KDevelop::Path nFile(KDevelop::Path(dir, file).toUrl()); + KDevelop::Path nDir(nFile.parent()); + // Add all the subdirectories + KDevelop::Path nDir2(nDir.toUrl()); + while (nDir2 != dir) { + QString f(nDir2.toUrl().fileName()); + KDevelop::Path d(nDir2.parent()); + _validFiles[project][d].validFiles << f; + nDir2 = KDevelop::Path(d); + } +// nDir.adjustPath(KUrl::AddTrailingSlash); + _validFiles[project][nDir].validFiles << nFile.toUrl().fileName(); } validFiles.validFiles << file; #ifdef DEBUG @@ -264,11 +259,11 @@ void KDevKernelPlugin::parseMakefile(const KUrl &dir, KDevelop::IProject *projec KDevelop::ProjectFolderItem *KDevKernelPlugin::import(KDevelop::IProject *project) { - KUrl projectRoot(project->folder()); - projectRoot.adjustPath(KUrl::AddTrailingSlash); - KConfigGroup config(project->projectConfiguration()->group(KERN_KGROUP)); - KUrl buildRoot = config.readEntry(KERN_BDIR, projectRoot); - buildRoot.adjustPath(KUrl::AddTrailingSlash); + KDevelop::Path projectRoot(project->path()); +// projectRoot.adjustPath(KUrl::AddTrailingSlash); + KConfigGroup cg = project->projectConfiguration()->group(KERN_KGROUP); + KDevelop::Path buildRoot(cg.readEntry(KERN_BDIR, projectRoot.toUrl())); +// buildRoot.adjustPath(KUrl::AddTrailingSlash); // This effectively cleans up everything projectClosing(project); @@ -279,7 +274,7 @@ KDevelop::ProjectFolderItem *KDevKernelPlugin::import(KDevelop::IProject *projec project->projectConfiguration()->group("MakeBuilder").writeEntry("Resolve Using Make", false); // If no .config file in the build directory, force user to configure to choose one - if (!QFile(KUrl(buildRoot, ".config").toLocalFile()).exists()) { + if (!QFile(KDevelop::Path(buildRoot, ".config").toLocalFile()).exists()) { // Populate a drop down list with all the _defconfig options, plus one "no change" // if there is already a .config file in the build dir. When dialog closes and a // defconfig is selected, run make to create it in the build dir. @@ -290,27 +285,27 @@ KDevelop::ProjectFolderItem *KDevKernelPlugin::import(KDevelop::IProject *projec QHash &_defs = _defines[project]; _defs["__KERNEL__"] = ""; - if (config.hasKey(KERN_BDIR)) - buildRoot = config.readEntry(KERN_BDIR, KUrl()); + if (cg.hasKey(KERN_BDIR)) + buildRoot = KDevelop::Path(cg.readEntry(KERN_BDIR, KDevelop::Path().toUrl())); else buildRoot = projectRoot; - buildRoot.adjustPath(KUrl::AddTrailingSlash); - parseDotConfig(project, KUrl(buildRoot, ".config"), _defs); +// buildRoot.adjustPath(KUrl::AddTrailingSlash); + parseDotConfig(project, KDevelop::Path(buildRoot, ".config"), _defs); _validFiles[project].clear(); ValidFilesList &rootFiles = _validFiles[project][projectRoot]; rootFiles.lastUpdate = QDateTime::currentDateTime(); - if (config.hasKey(KERN_ARCH)) { - KUrl archUrl(projectRoot, "arch/"); - QString arch(config.readEntry(KERN_ARCH, "")); - KUrl archArchUrl(archUrl, arch); - archArchUrl.adjustPath(KUrl::AddTrailingSlash); + if (cg.hasKey(KERN_ARCH)) { + KDevelop::Path archUrl(projectRoot, "arch/"); + QString arch(cg.readEntry(KERN_ARCH, "")); + KDevelop::Path archArchUrl(archUrl, arch); +// archArchUrl.adjustPath(KUrl::AddTrailingSlash); rootFiles.validFiles << "arch"; _validFiles[project][archUrl].lastUpdate = QDateTime::currentDateTime(); _validFiles[project][archUrl].validFiles << arch; - _validFiles[project][archArchUrl].validFiles << "boot"; + _validFiles[project][archArchUrl].validFiles << "boot"; } /* @@ -344,7 +339,7 @@ KDevelop::ProjectTargetItem *KDevKernelPlugin::createTarget(const QString &targe { Q_UNUSED(target); Q_UNUSED(parent); - return 0; + return {}; } bool KDevKernelPlugin::removeTarget(KDevelop::ProjectTargetItem *target) @@ -356,7 +351,7 @@ bool KDevKernelPlugin::removeTarget(KDevelop::ProjectTargetItem *target) QList KDevKernelPlugin::targets(KDevelop::ProjectFolderItem *item) const { Q_UNUSED(item); - return QList(); + return {}; } bool KDevKernelPlugin::addFilesToTarget(const QList &files, KDevelop::ProjectTargetItem *target) @@ -372,17 +367,23 @@ bool KDevKernelPlugin::removeFilesFromTargets(const QListfolder(), "Documentation/").toLocalFile())) valid = true; + else if (lFile.startsWith(KDevelop::Path(project->path(), "Documentation/").toLocalFile())) valid = true; // Same thing for .h files and Makefiles else if (lFile.endsWith(".h") || lFile.endsWith("/Makefile")) valid = true; // And KConfig files @@ -409,11 +410,11 @@ bool KDevKernelPlugin::isValid(const KDevelop::Path &url, const bool isFolder, K else if (validFiles.validFiles.contains(file)) valid = true; // Last ressort, the user-list of hardcoded files to accept else { - KConfigGroup config = project->projectConfiguration()->group(KERN_KGROUP); - QStringList vFiles(config.readEntry(KERN_VALIDFILES, QStringList())); - KUrl pRoot(project->folder()); - pRoot.adjustPath(KUrl::AddTrailingSlash); - QString fPath(url.toLocalFile().mid(pRoot.toLocalFile().size())); + KConfigGroup cg = project->projectConfiguration()->group(KERN_KGROUP); + QStringList vFiles(cg.readEntry(KERN_VALIDFILES, QStringList())); + KDevelop::Path pRoot(project->path()); +// pRoot.adjustPath(KUrl::AddTrailingSlash); + QString fPath(url.toLocalFile().mid(pRoot.toLocalFile().size()+1)); // +1 instead of AddTrailingSlash if (vFiles.contains(fPath)) valid = true; } @@ -425,13 +426,20 @@ bool KDevKernelPlugin::isValid(const KDevelop::Path &url, const bool isFolder, K KDevelop::Path KDevKernelPlugin::buildDirectory(KDevelop::ProjectBaseItem *item) const { - KUrl buildDir(item->project()->projectItem()->url()); + KDevelop::Path buildDir(item->project()->projectItem()->path()); return KDevelop::Path(buildDir); } -KJob *KDevKernelPlugin::install(KDevelop::ProjectBaseItem *item) +QString KDevKernelPlugin::extraArguments(KDevelop::ProjectBaseItem *item) const +{ + Q_UNUSED(item) + return {}; +} + +KJob *KDevKernelPlugin::install(KDevelop::ProjectBaseItem *item, const QUrl &specificPrefix) { Q_UNUSED(item) + Q_UNUSED(specificPrefix) return 0; } @@ -460,42 +468,57 @@ KJob *KDevKernelPlugin::prune(KDevelop::IProject *project) KJob *KDevKernelPlugin::createDotConfig (KDevelop::IProject *project) { - KConfigGroup config(project->projectConfiguration()->group(KERN_KGROUP)); - QString defConfig(config.readEntry(KERN_DEFCONFIG, "")); + KConfigGroup cg = project->projectConfiguration()->group(KERN_KGROUP); + QString defConfig(cg.readEntry(KERN_DEFCONFIG, "")); if (defConfig.isEmpty()) return 0; return jobForTarget(project, QStringList(defConfig + "_defconfig")); } MakeVariables KDevKernelPlugin::makeVarsForProject(KDevelop::IProject* project) { + Q_UNUSED(project) MakeVariables makeVars; - KConfigGroup config(project->projectConfiguration()->group(KERN_KGROUP)); - if (config.hasKey(KERN_BDIR)) - makeVars << QPair("O", KUrl(config.readEntry(KERN_BDIR)).toLocalFile()); - if (config.hasKey(KERN_ARCH)) - makeVars << QPair("ARCH", config.readEntry(KERN_ARCH)); - if (config.hasKey(KERN_CROSS)) - makeVars << QPair("CROSS_COMPILE", config.readEntry(KERN_CROSS)); + KConfigGroup cg = project->projectConfiguration()->group(KERN_KGROUP); + if (cg.hasKey(KERN_BDIR)) + makeVars << QPair("O", KDevelop::Path(cg.readEntry(KERN_BDIR)).toLocalFile()); + if (cg.hasKey(KERN_ARCH)) + makeVars << QPair("ARCH", cg.readEntry(KERN_ARCH)); + if (cg.hasKey(KERN_CROSS)) + makeVars << QPair("CROSS_COMPILE", cg.readEntry(KERN_CROSS)); return makeVars; } KJob *KDevKernelPlugin::jobForTarget(KDevelop::IProject *project, const QStringList &targets) { - if (_builder) { - return _builder->executeMakeTargets(project->projectItem(), - targets, makeVarsForProject(project)); - } - else return 0; + if (m_builder) { + return m_builder->executeMakeTargets(project->projectItem(), + targets, makeVarsForProject(project)); + } else return 0; } QList KDevKernelPlugin::additionalBuilderPlugins(KDevelop::IProject *project) const { - Q_UNUSED(project); + Q_UNUSED(project); + + QList ret; + ret << m_builder; + return ret; +} + +int KDevKernelPlugin::perProjectConfigPages() const +{ + return 1; // TODO 1 or 0 ? It shows up with 1 when in a KDevKernel project, with 0 it doesn't +} + +KDevelop::ConfigPage* KDevKernelPlugin::perProjectConfigPage(int number, const KDevelop::ProjectConfigOptions& options, QWidget* parent) +{ + if (number != 0) { + return nullptr; + } - QList ret; - ret << _builder; - return ret; + return new KDevKernel::ProjectConfigPage(this, options.project, parent); } +// needed for QObject class created from K_PLUGIN_FACTORY_WITH_JSON #include "kdevkernelplugin.moc" diff --git a/kdevkernelplugin.h b/kdevkernelplugin.h index bc8f9a9..af0c48b 100644 --- a/kdevkernelplugin.h +++ b/kdevkernelplugin.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -40,8 +40,7 @@ class IProject; class Path; } -struct ValidFilesList -{ +struct ValidFilesList { QDateTime lastUpdate; QSet validFiles; }; @@ -54,59 +53,64 @@ class KDevKernelPlugin : public KDevelop::AbstractFileManagerPlugin, public KDev Q_INTERFACES(KDevelop::IBuildSystemManager) private: - IMakeBuilder *_builder; + IMakeBuilder *m_builder; - mutable QMap > _validFiles; + mutable QMap > _validFiles; mutable QMap _machDirs; mutable QMap > _defines; /** * Parse the given configuration file and set the kernel definitions accordingly. */ - void parseDotConfig(KDevelop::IProject *project, const KUrl &dotconfig, QHash &_defs); + void parseDotConfig(KDevelop::IProject *project, const KDevelop::Path &dotconfig, QHash &_defs); /** * Parse the Makefiles and build the list of files we need to include according * to the definitions that have been parsed by parseDotConfig. */ - void parseMakefile(const KUrl &dir, KDevelop::IProject *project) const; + void parseMakefile(const KDevelop::Path &dir, KDevelop::IProject *project) const; public: KDevKernelPlugin(QObject *parent, const QVariantList &args); // AbstractFileManagerPlugin interface - virtual KDevelop::ProjectFolderItem *import(KDevelop::IProject *project); + virtual KDevelop::ProjectFolderItem *import(KDevelop::IProject *project) override; // IBuildSystemManager interface - virtual KDevelop::IProjectBuilder *builder() const; - virtual KDevelop::Path::List includeDirectories(KDevelop::ProjectBaseItem *item) const; - virtual KUrl::List includeDirectories(KDevelop::IProject *project) const; - virtual QHash defines(KDevelop::ProjectBaseItem *item) const; - virtual KDevelop::ProjectTargetItem *createTarget(const QString &target, KDevelop::ProjectFolderItem *parent); - virtual bool removeTarget(KDevelop::ProjectTargetItem *target); - virtual QList targets(KDevelop::ProjectFolderItem *item) const; - virtual bool addFilesToTarget(const QList &files, KDevelop::ProjectTargetItem *target); - virtual bool removeFilesFromTargets(const QList &files); + virtual KDevelop::IProjectBuilder *builder() const override; + virtual KDevelop::Path::List includeDirectories(KDevelop::ProjectBaseItem *item) const override; + virtual KDevelop::Path::List frameworkDirectories(KDevelop::ProjectBaseItem *item) const override; + virtual QHash defines(KDevelop::ProjectBaseItem *item) const override; + virtual KDevelop::ProjectTargetItem *createTarget(const QString &target, KDevelop::ProjectFolderItem *parent) override; + virtual bool removeTarget(KDevelop::ProjectTargetItem *target) override; + virtual QList targets(KDevelop::ProjectFolderItem *item) const override; + virtual bool addFilesToTarget(const QList &files, KDevelop::ProjectTargetItem *target) override; + virtual bool removeFilesFromTargets(const QList &files) override; + virtual bool hasBuildInfo(KDevelop::ProjectBaseItem *item) const override; /** * A file is valid if it belongs to the list of files that are enabled through the kernel configuration. * A directory is valid if it contains any file we are interested in. */ - virtual bool isValid(const KDevelop::Path &url, const bool isFolder, KDevelop::IProject *project) const; - virtual KDevelop::Path buildDirectory(KDevelop::ProjectBaseItem *item) const; + virtual bool isValid(const KDevelop::Path &url, const bool isFolder, KDevelop::IProject *project) const override; + virtual KDevelop::Path buildDirectory(KDevelop::ProjectBaseItem *item) const override; + virtual QString extraArguments(KDevelop::ProjectBaseItem *item) const override; // IProjectBuilder interface - virtual KJob *install(KDevelop::ProjectBaseItem *project); - virtual KJob *build(KDevelop::ProjectBaseItem *project); - virtual KJob *clean(KDevelop::ProjectBaseItem *project); - virtual KJob *configure(KDevelop::IProject *project); - virtual KJob *prune(KDevelop::IProject *project); - virtual QList additionalBuilderPlugins(KDevelop::IProject *project) const; + virtual KJob *install(KDevelop::ProjectBaseItem *project, const QUrl &specificPrefix = {}) override; + virtual KJob *build(KDevelop::ProjectBaseItem *project) override; + virtual KJob *clean(KDevelop::ProjectBaseItem *project) override; + virtual KJob *configure(KDevelop::IProject *project) override; + virtual KJob *prune(KDevelop::IProject *project) override; + virtual QList additionalBuilderPlugins(KDevelop::IProject *project) const override; virtual KJob *createDotConfig(KDevelop::IProject *project); + int perProjectConfigPages() const override; + KDevelop::ConfigPage* perProjectConfigPage(int number, const KDevelop::ProjectConfigOptions& options, QWidget* parent) override; protected: virtual MakeVariables makeVarsForProject(KDevelop::IProject *project); virtual KJob *jobForTarget(KDevelop::IProject *project, const QStringList &targets); + virtual KDevelop::Path::List includeDirectories(KDevelop::IProject *project) const; private slots: virtual void projectClosing(KDevelop::IProject *project);