Meson plugin: First working version
ClosedPublic

Authored by dmensinger on Dec 1 2018, 11:09 AM.

Details

Summary

This patch implements the basic functionality of the meson plugin.
Introspection (targets, include dirs, etc.) is not implemented yet.

The current features are:

  • (re)configuring a meson project
  • building with ninja
  • GUI for configuring a build directory (currently only install prefix and build type)
  • managing multiple build directories
  • GUI for adding a new build directory

Diff Detail

Repository
R32 KDevelop
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
dmensinger created this revision.Dec 1 2018, 11:09 AM
Restricted Application added a project: KDevelop. · View Herald TranscriptDec 1 2018, 11:09 AM
dmensinger requested review of this revision.Dec 1 2018, 11:09 AM
dmensinger updated this revision to Diff 46611.Dec 1 2018, 12:33 PM
  • Fixed typo in icons/CMakeLists.txt
Restricted Application added a project: Documentation. · View Herald TranscriptDec 1 2018, 12:33 PM
Restricted Application added a subscriber: kde-doc-english. · View Herald Transcript
yurchor added inline comments.
plugins/meson/kdevmesonmanager.json
6

There is no need to add translations. They will be removed by scripty then renewed after the translator review anyway.

plugins/meson/mesonbuilder.cpp
151

Typo: seam -> seem

156

Typo: can not -> cannot

plugins/meson/settings/mesonconfigpage.ui
123

Typo: seperate -> separate

plugins/meson/settings/mesonnewbuilddir.cpp
170
188

Typo: can not -> cannot

dmensinger updated this revision to Diff 46614.Dec 1 2018, 1:27 PM
  • Fixed typos and removed translations
rizzitello added inline comments.
plugins/meson/mesonbuilder.cpp
56

Would ending the string with a \n (or two) remove the need to append an empty QStringLiteral in the next line?

58

QChar::fromLatin1('\n') instead of the older cast ?

185

Else is not needed since the if ends with a return.

plugins/meson/mesonconfig.cpp
185

return !( buildDir.isEmpty() || mesonExecutable.isEmpty() || buildType.isEmpty() ); ?

plugins/meson/mesonimportjob.cpp
48

"sourcePath" and "bulilddir" appear to be unused here.

plugins/meson/settings/mesonconfigpage.cpp
179

auto

dmensinger marked 6 inline comments as done.Dec 1 2018, 3:11 PM
dmensinger added inline comments.
plugins/meson/mesonimportjob.cpp
48

Yeah, I haven't touched that code yet. This is still from the barebones framework that was created over a year ago. I will replace this function with a stub for the time being.

plugins/meson/settings/mesonconfigpage.cpp
179

I don't know why you would use auto here. Should I use auto for every dynamic_cast?

dmensinger updated this revision to Diff 46623.Dec 1 2018, 3:17 PM
  • Some code cleanup
rizzitello added inline comments.Dec 1 2018, 5:50 PM
plugins/meson/settings/mesonconfigpage.cpp
179

In these cases the type is obvious. Why not use auto?

dmensinger marked 4 inline comments as done.Dec 1 2018, 6:09 PM
dmensinger added inline comments.
plugins/meson/settings/mesonconfigpage.cpp
179

Then I guess it is personal preference :)
I like it better this way for (relatively) short type names without templates and :: (outside C++11 for loops).
If you are OK with it, I would like to keep the types the way they are now.

rizzitello added inline comments.Dec 1 2018, 6:26 PM
plugins/meson/settings/mesonconfigpage.cpp
179

It's okay with me if you keep the types how they are now.

flherne added inline comments.
plugins/meson/mesonbuilder.cpp
47

This needs setStandardToolView(KDevelop::IOutputView::BuildView); or similar, otherwise the output appears as a separate view with no name or icon.

151

This condition is reached in case a previous configure attempt failed, e.g. because of a missing dependency.

KDevelop refuses to re-try the configure step (after installing the dependency) until the build dir is removed, which is quite inconvenient.

It's quite easy to accidentally start repeated configure jobs, in which case the second one fails - e.g. by clicking "Apply" and then "Ok" in the project settings.

Perhaps if a configure job is already running, it should be cancelled before starting a new one (or the new one ignored if the settings are unchanged?).

Will try to review the actual code sometime.

dmensinger updated this revision to Diff 46704.Dec 2 2018, 2:00 PM
  • Only configure when config changed
  • Better status handling in the settings UI
dmensinger marked 2 inline comments as done.Dec 14 2018, 3:55 PM

Ping :)

rjvbb added a subscriber: rjvbb.Dec 31 2018, 1:24 PM

Thanks in advance for fixing this minor typo.

plugins/meson/mesonbuilder.cpp
120

Typo: cheks -> checks

dmensinger updated this revision to Diff 48444.Dec 31 2018, 1:41 PM
  • Fixed typo
dmensinger marked an inline comment as done.Dec 31 2018, 1:43 PM
arrowd added a subscriber: arrowd.Jan 3 2019, 6:46 PM

Tried this out on FreeBSD with KDevelop master.

The project imported successfully, but trying to build caused crash:

Application: KDevelop (kdevelop), signal: Segmentation fault
[KCrash Handler]
#8  0x0000000820c4f721 in MesonBuilder::build(KDevelop::ProjectBaseItem*) (this=0x820069ac0, item=0x82043b070) at /home/arr/projects/kdevelop/plugins/meson/mesonbuilder.cpp:214
#9  0x0000000804784796 in KDevelop::BuilderJobPrivate::addJob(KDevelop::BuilderJob::BuildType, KDevelop::ProjectBaseItem*) (this=0x82b52e3e0, t=KDevelop::BuilderJob::Build, item=0x82043b070) at /home/arr/projects/kdevelop/kdevplatform/project/builderjob.cpp:122
#10 0x0000000804784e39 in KDevelop::BuilderJob::addItems(KDevelop::BuilderJob::BuildType, QList<KDevelop::ProjectBaseItem*> const&) (this=0x8204c00f0, t=KDevelop::BuilderJob::Build, items=...) at /home/arr/projects/kdevelop/kdevplatform/project/builderjob.cpp:157
#11 0x000000081ea6d136 in ProjectManagerViewPlugin::runBuilderJob(KDevelop::BuilderJob::BuildType, QList<KDevelop::ProjectBaseItem*> const&) (this=0x818f41a10, type=KDevelop::BuilderJob::Build, items=...) at /home/arr/projects/kdevelop/plugins/projectmanagerview/projectmanagerviewplugin.cpp:459
#12 0x000000081ea6c1ca in ProjectManagerViewPlugin::buildItemsFromContextMenu() (this=0x818f41a10) at /home/arr/projects/kdevelop/plugins/projectmanagerview/projectmanagerviewplugin.cpp:414
#13 0x000000081ea74a9e in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (ProjectManagerViewPlugin::*)()>::call(void (ProjectManagerViewPlugin::*)(), ProjectManagerViewPlugin*, void**) (f=(void (ProjectManagerViewPlugin::*)(ProjectManagerViewPlugin * const)) 0x81ea6c190 <ProjectManagerViewPlugin::buildItemsFromContextMenu()>, o=0x818f41a10, arg=0x7fffffffa410) at /usr/local/include/qt5/QtCore/qobjectdefs_impl.h:152
#14 0x000000081ea74a03 in QtPrivate::FunctionPointer<void (ProjectManagerViewPlugin::*)()>::call<QtPrivate::List<>, void>(void (ProjectManagerViewPlugin::*)(), ProjectManagerViewPlugin*, void**) (f=(void (ProjectManagerViewPlugin::*)(ProjectManagerViewPlugin * const)) 0x81ea6c190 <ProjectManagerViewPlugin::buildItemsFromContextMenu()>, o=0x818f41a10, arg=0x7fffffffa410) at /usr/local/include/qt5/QtCore/qobjectdefs_impl.h:185
#15 0x000000081ea748e6 in QtPrivate::QSlotObject<void (ProjectManagerViewPlugin::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x82b4d1040, r=0x818f41a10, a=0x7fffffffa410, ret=0x0) at /usr/local/include/qt5/QtCore/qobjectdefs_impl.h:414
#16 0x00000008042580be in QMetaObject::activate(QObject*, int, int, void**) () at /usr/local/lib/qt5/libQt5Core.so.5
#17 0x000000080307562b in QAction::activate(QAction::ActionEvent) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#18 0x00000008031e3900 in  () at /usr/local/lib/qt5/libQt5Widgets.so.5
#19 0x00000008031e10ce in  () at /usr/local/lib/qt5/libQt5Widgets.so.5
#20 0x00000008031e7db3 in QMenu::mouseReleaseEvent(QMouseEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#21 0x00000008030b64e0 in QWidget::event(QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#22 0x00000008031e8481 in QMenu::event(QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#23 0x000000080307dee1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#24 0x0000000803080b63 in QApplication::notify(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#25 0x0000000804226ef1 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Core.so.5
#26 0x000000080307e815 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#27 0x00000008030d4771 in  () at /usr/local/lib/qt5/libQt5Widgets.so.5
#28 0x00000008030d3246 in  () at /usr/local/lib/qt5/libQt5Widgets.so.5
#29 0x000000080307dee1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#30 0x000000080307f27d in QApplication::notify(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#31 0x0000000804226ef1 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Core.so.5
#32 0x00000008036025a2 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /usr/local/lib/qt5/libQt5Gui.so.5
#33 0x00000008035e958c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/local/lib/qt5/libQt5Gui.so.5
#34 0x00000008136a6baf in  () at /usr/local/lib/qt5/libQt5XcbQpa.so.5
#35 0x0000000805bf6b77 in g_main_context_dispatch () at /usr/local/lib/libglib-2.0.so.0
#36 0x0000000805bf6f03 in  () at /usr/local/lib/libglib-2.0.so.0
#37 0x0000000805bf6fb4 in g_main_context_iteration () at /usr/local/lib/libglib-2.0.so.0
#38 0x000000080427bda6 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/local/lib/qt5/libQt5Core.so.5
#39 0x0000000804222a3e in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/local/lib/qt5/libQt5Core.so.5
#40 0x00000008031e659b in QMenu::exec(QPoint const&, QAction*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#41 0x000000081ea84b3a in ProjectTreeView::popupContextMenu(QPoint const&) (this=0x81fd296c0, pos=...) at /home/arr/projects/kdevelop/plugins/projectmanagerview/projecttreeview.cpp:385
#42 0x000000081ea89009 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QPoint const&>, void, void (ProjectTreeView::*)(QPoint const&)>::call(void (ProjectTreeView::*)(QPoint const&), ProjectTreeView*, void**) (f=(void (ProjectTreeView::*)(ProjectTreeView * const, const QPoint &)) 0x81ea842b0 <ProjectTreeView::popupContextMenu(QPoint const&)>, o=0x81fd296c0, arg=0x7fffffffb610) at /usr/local/include/qt5/QtCore/qobjectdefs_impl.h:152
#43 0x000000081ea88f73 in QtPrivate::FunctionPointer<void (ProjectTreeView::*)(QPoint const&)>::call<QtPrivate::List<QPoint const&>, void>(void (ProjectTreeView::*)(QPoint const&), ProjectTreeView*, void**) (f=(void (ProjectTreeView::*)(ProjectTreeView * const, const QPoint &)) 0x81ea842b0 <ProjectTreeView::popupContextMenu(QPoint const&)>, o=0x81fd296c0, arg=0x7fffffffb610) at /usr/local/include/qt5/QtCore/qobjectdefs_impl.h:185
#44 0x000000081ea88e96 in QtPrivate::QSlotObject<void (ProjectTreeView::*)(QPoint const&), QtPrivate::List<QPoint const&>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x81fd32980, r=0x81fd296c0, a=0x7fffffffb610, ret=0x0) at /usr/local/include/qt5/QtCore/qobjectdefs_impl.h:414
#45 0x00000008042580be in QMetaObject::activate(QObject*, int, int, void**) () at /usr/local/lib/qt5/libQt5Core.so.5
#46 0x00000008030b7409 in QWidget::event(QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#47 0x000000080315569d in QFrame::event(QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#48 0x00000008032c4d5d in QAbstractItemView::viewportEvent(QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#49 0x000000080332df45 in QTreeView::viewportEvent(QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#50 0x0000000804227194 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Core.so.5
#51 0x000000080307decc in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#52 0x00000008030803a2 in QApplication::notify(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#53 0x0000000804226ef1 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Core.so.5
#54 0x00000008030d4b90 in  () at /usr/local/lib/qt5/libQt5Widgets.so.5
#55 0x00000008030d3246 in  () at /usr/local/lib/qt5/libQt5Widgets.so.5
#56 0x000000080307dee1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#57 0x000000080307f27d in QApplication::notify(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Widgets.so.5
#58 0x0000000804226ef1 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/local/lib/qt5/libQt5Core.so.5
#59 0x00000008036025a2 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /usr/local/lib/qt5/libQt5Gui.so.5
#60 0x00000008035e958c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/local/lib/qt5/libQt5Gui.so.5
#61 0x00000008136a6baf in  () at /usr/local/lib/qt5/libQt5XcbQpa.so.5
#62 0x0000000805bf6b77 in g_main_context_dispatch () at /usr/local/lib/libglib-2.0.so.0
#63 0x0000000805bf6f03 in  () at /usr/local/lib/libglib-2.0.so.0
#64 0x0000000805bf6fb4 in g_main_context_iteration () at /usr/local/lib/libglib-2.0.so.0
#65 0x000000080427bda6 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/local/lib/qt5/libQt5Core.so.5
#66 0x0000000804222a3e in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/local/lib/qt5/libQt5Core.so.5
#67 0x00000008042274ee in QCoreApplication::exec() () at /usr/local/lib/qt5/libQt5Core.so.5
#68 0x0000000000215fd8 in main(int, char**) (argc=1, argv=0x7fffffffe630) at /home/arr/projects/kdevelop/app/main.cpp:846
[Inferior 1 (process 8040) detached]
dmensinger updated this revision to Diff 48637.Jan 3 2019, 8:09 PM
  • Make sure that the ninja buidler exists

This segfault is/was most likely caused by a missing Ninja builder plugin. I have added checks to prevent the segfault from happening.

arrowd added a comment.Jan 4 2019, 1:22 PM

Yep, that fixed the issue.

Another minor problem - I don't see icons you added anywhere in GUI. When importing project, "Meson Project Manager" doesn't have an icon, and also there is no icon in "Settings -> Plugins" list.

I also don't know why the icons don't show up. I have oriented myself on the code from the CMake plugin, and I don't know what I am doing different/wrong. Maybe KDevelop has to be installed in a system directory (/usr) for this to work?

arrowd accepted this revision.Jan 4 2019, 3:30 PM

I also don't know why the icons don't show up. I have oriented myself on the code from the CMake plugin, and I don't know what I am doing different/wrong. Maybe KDevelop has to be installed in a system directory (/usr) for this to work?

Yep, probably. This isn't blocker anyways.

I've tested some basic scenarios and it at least doesn't crash. I'd say this can be pushed. Let's wait for a couple of days first, though.

This revision is now accepted and ready to land.Jan 4 2019, 3:30 PM
rjvbb added a comment.Jan 4 2019, 4:20 PM

arrowd accepted this revision.
arrowd added a comment.

Maybe KDevelop has to be installed in a system directory (/usr) for this to work?

KDevelop itself not, but the icons evidently have to be installed in the appropriate location. I agree that having an icon isn't crucial, but there's no point wasting space on icon files if they don't show.

I've tested some basic scenarios and it at least doesn't crash. I'd say this can be pushed. Let's wait for a couple of days first, though.

I won't get around to testing this until (hopefully the beginning of) next week but if it works I will probably not have much to add except a strong suggestion I can just as well make now (with apologies if your code already does this).
Experience with cmake has taught me that confusion (as well as parsing and/or build errors) can arise if you configure a project to use a build dir that has a symlink somewhere in its path unless you work with canonicalised build dir (and possibly source dir) paths in the project manager. This is all the more true if you also use meson/make/ninja on the project via a shell instead of exclusively through KDevelop.

dmensinger updated this revision to Diff 48734.Jan 5 2019, 1:11 PM
  • Use canonical paths

Thanks for the input concerning the canonical paths. I have tested the plugin with different setups containing symbolic
links and haven't encountered any issues. Regardless, I have canonicalized the paths just to be safe.

Also, the icon appears when KDevelop is installed (anywhere), and XDG_DATA_DIRS is updated accordingly.

apol added a comment.Jan 8 2019, 3:52 PM

Looks good to me, let's get this in master?

This revision was automatically updated to reflect the committed changes.