gazebosim / gz-gui

Builds on top of Qt to provide widgets which are useful when developing robotics applications, such as a 3D view, plots, dashboard, etc, and can be used together in a convenient unified interface.
https://gazebosim.org
Apache License 2.0
72 stars 41 forks source link

Throw compile error for missing QML dependencies #30

Open osrf-migration opened 6 years ago

osrf-migration commented 6 years ago

Original report (archived issue) by Louise Poubel (Bitbucket: chapulina, GitHub: chapulina).


QML modules are loaded at runtime, so there is no warning for the user at compile time. It could be helpful for downstream developers to throw errors/warnings at compile time.

osrf-migration commented 5 years ago

Original comment by Louise Poubel (Bitbucket: chapulina, GitHub: chapulina).


Some relevant info on this comment

stefanbuettner commented 3 years ago

I ran into this problem when building the project from source as described in the docs while not strictly following the dependency installation. I'm working on packaging ignition-gazebo with conan and want to minimize the Debian package dependencies.

A compilation error would be nice. Or a more informative runtime error. This is the runtime error I encountered

ign gazebo
[GUI] [Err] [MainWindow.cc:81] Internal error: Failed to instantiate QML file [qrc:qml/Main.qml]
[GUI] [Err] [Application.cc:115] Failed to initialize main window.
/home/sb/code/ignition-gazebo/install/lib/ruby/ignition/cmdgazebo4.rb:438: [BUG] Segmentation fault at 0x0000000000000010
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
-- Control frame information -----------------------------------------------
c:0007 p:---- s:0058 e:000057 CFUNC  :call
c:0006 p:0017 s:0053 e:000052 METHOD /home/sb/code/ignition-gazebo/install/lib/ruby/ignition/cmdgazebo4.rb:438
c:0005 p:0057 s:0047 e:000046 BLOCK  /home/sb/code/ignition-gazebo/install/lib/ruby/ignition/cmdgazebo4.rb:474 [FINISH]
c:0004 p:---- s:0044 e:000043 CFUNC  :fork
c:0003 p:0688 s:0040 e:000039 METHOD /home/sb/code/ignition-gazebo/install/lib/ruby/ignition/cmdgazebo4.rb:470
c:0002 p:0686 s:0019 E:0023f8 EVAL   /home/sb/code/ignition-gazebo/install/bin/ign:272 [FINISH]
c:0001 p:0000 s:0003 E:001d30 (none) [FINISH]

The QQmlApplicationEngine::load function seems to issue a warning which might be more informative. Not quite sure if that's the correct function and if the warning would be helpful but maybe it's useful.

chapulina commented 3 years ago

The QQmlApplicationEngine::load function seems to issue a warning which might be more informative.

Can you try running ign-gazebo with higher verbosity (i.e. ign gazebo -v 4)? All qWarnings are being piped to ignwarn and you should see them as [GUI] [Warn] in yellow on the console.

stefanbuettner commented 3 years ago

Thanks, starting with ign gazebo -v 4 includes a bettern error which hints to the problem

ign gazebo -v 4
[Msg] Ignition Gazebo Server v4.2.0
[Msg] Ignition Gazebo GUI    v4.2.0
[Msg] Loading default world.
[Dbg] [Application.cc:87] Initializing application.
[GUI] [Dbg] [Application.cc:407] Create main window
[Dbg] [EntityComponentManager.cc:630] Using components of type [2251689575469537287] / [ign_gazebo_components.World].
[Dbg] [EntityComponentManager.cc:630] Using components of type [13994732549916512682] / [ign_gazebo_components.Name].
[Dbg] [EntityComponentManager.cc:630] Using components of type [12592746352568925681] / [ign_gazebo_components.Gravity].
[Dbg] [EntityComponentManager.cc:630] Using components of type [13224937992534617849] / [ign_gazebo_components.MagneticField].
[Dbg] [EntityComponentManager.cc:630] Using components of type [3630648173860223239] / [ign_gazebo_components.PhysicsEnginePlugin].
[Dbg] [EntityComponentManager.cc:630] Using components of type [17459188283658606303] / [ign_gazebo_components.RenderEngineServerPlugin].
[Dbg] [EntityComponentManager.cc:630] Using components of type [8705992680619689917] / [ign_gazebo_components.RenderEngineGuiPlugin].
[Dbg] [EntityComponentManager.cc:630] Using components of type [8753193699724811771] / [ign_gazebo_components.Wind].
[Dbg] [EntityComponentManager.cc:630] Using components of type [12173050716021724529] / [ign_gazebo_components.WorldLinearVelocity].
[Dbg] [EntityComponentManager.cc:630] Using components of type [15943768124495574352] / [ign_gazebo_components.WorldLinearVelocitySeed].
[Dbg] [EntityComponentManager.cc:630] Using components of type [3297509811873971798] / [ign_gazebo_components.ParentEntity].
[Dbg] [EntityComponentManager.cc:630] Using components of type [17100615127981600159] / [ign_gazebo_components.Scene].
[Dbg] [EntityComponentManager.cc:630] Using components of type [17605309075052480649] / [ign_gazebo_components.Atmosphere].
[Dbg] [EntityComponentManager.cc:630] Using components of type [8064491505919932473] / [ign_gazebo_components.Level].
[Dbg] [EntityComponentManager.cc:630] Using components of type [2668898242563798256] / [ign_gazebo_components.DefaultLevel].
[Dbg] [EntityComponentManager.cc:630] Using components of type [11371360182141354106] / [ign_gazebo_components.LevelEntityNames].
[Dbg] [EntityComponentManager.cc:630] Using components of type [4981278897826323946] / [ign_gazebo_components.WorldSdf].
[Msg] Loaded level [3]
[Msg] No systems loaded from SDF, loading defaults
[Dbg] [ServerConfig.cc:920] Loaded (3) plugins from file [/home/sb/.ignition/gazebo/server.config]
[GUI] [Wrn] [Application.cc:649] [QT] QQmlApplicationEngine failed to load component
[GUI] [Wrn] [Application.cc:649] [QT] qrc:qml/Main.qml:20 module "QtQuick.Dialogs" is not installed

[GUI] [Err] [MainWindow.cc:81] Internal error: Failed to instantiate QML file [qrc:qml/Main.qml]
[GUI] [Err] [Application.cc:115] Failed to initialize main window.
[Dbg] [Physics.cc:600] Loaded [ignition::physics::dartsim::Plugin] from library [/home/sb/code/ignition-gazebo/install/lib/ign-physics-3/engine-plugins/libignition-physics-dartsim-plugin.so]
[Dbg] [SimulationRunner.cc:783] Loaded system [ignition::gazebo::systems::Physics] for entity [1]
[Msg] Create service on [/world/default/create]
[Msg] Remove service on [/world/default/remove]
[Msg] Pose service on [/world/default/set_pose]
[Dbg] [SimulationRunner.cc:783] Loaded system [ignition::gazebo::systems::UserCommands] for entity [1]
[Dbg] [SimulationRunner.cc:783] Loaded system [ignition::gazebo::systems::SceneBroadcaster] for entity [1]
[Msg] Serving world controls on [/world/default/control] and [/world/default/playback/control]
[Msg] Serving GUI information on [/world/default/gui/info]
[Msg] World [default] initialized with [default_physics] physics profile.
[Msg] Serving world SDF generation service on [/world/default/generate_world_sdf]
[Msg] Serving world names on [/gazebo/worlds]
[Msg] Resource path add service on [/gazebo/resource_paths/add].
[Msg] Resource path get service on [/gazebo/resource_paths/add].
[Msg] Resource paths published on [/gazebo/resource_paths].
/home/sb/code/ignition-gazebo/install/lib/ruby/ignition/cmdgazebo4.rb:438: [BUG] Segmentation fault at 0x0000000000000010
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]

-- Control frame information -----------------------------------------------

Would it be possible to check the presence of the library during compile time though?

chapulina commented 3 years ago

Would it be possible to check the presence of the library during compile time though?

That's the million dollar question. I haven't been able to figure out a way. I fixed the link on the comment above from May 1st 2019. Here's a copy of the comment:


tl;dr there may not be a way to do it from cmake without much hacking. We could try detecting it in C++ and printing a runtime error that is more informative than the one Qt is printing.

I couldn't find a straightforward way of doing this. The qml modules themselves install very little:

$ dpkg-query -L qml-module-qtqml-models2
/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/qt5
/usr/lib/x86_64-linux-gnu/qt5/qml
/usr/lib/x86_64-linux-gnu/qt5/qml/QtQml
/usr/lib/x86_64-linux-gnu/qt5/qml/QtQml/Models.2
/usr/lib/x86_64-linux-gnu/qt5/qml/QtQml/Models.2/libmodelsplugin.so
/usr/lib/x86_64-linux-gnu/qt5/qml/QtQml/Models.2/plugins.qmltypes
/usr/lib/x86_64-linux-gnu/qt5/qml/QtQml/Models.2/qmldir
/usr/share
/usr/share/doc
/usr/share/doc/qml-module-qtqml-models2
/usr/share/doc/qml-module-qtqml-models2/copyright
/usr/share/doc/qml-module-qtqml-models2/changelog.Debian.gz

Qt is crawling the /usr/lib/x86_64-linux-gnu/qt5/qml directory to find modules when importing. I found a way to get that path from C++ like this:

diff -r 969dce894062 src/gui/plugins/EntityTree.cc
--- a/src/gui/plugins/EntityTree.cc     Mon Apr 29 18:21:07 2019 -0700
+++ b/src/gui/plugins/EntityTree.cc     Tue Apr 30 17:07:44 2019 -0700
@@ -124,6 +124,10 @@
 EntityTree::EntityTree()
   : GuiSystem(), dataPtr(std::make_unique<EntityTreePrivate>())
 {
+  auto paths = gui::App()->Engine()->importPathList();
+  for (auto p : paths)
+    igndbg << p.toStdString() << std::endl;
+
   // Connect model
   gui::App()->Engine()->rootContext()->setContextProperty("EntityTreeModel",
       &this->dataPtr->treeModel);

which prints this:

[GUI] [Dbg] [EntityTree.cc:129] /home/developer/ws/install/ignition-gazebo2/bin
[GUI] [Dbg] [EntityTree.cc:129] qrc:/qt-project.org/imports
[GUI] [Dbg] [EntityTree.cc:129] /usr/lib/x86_64-linux-gnu/qt5/qml

I didn't figure out how to get the same path from cmake, it's possible that it's only available at runtime. We should be able to append paths with cmake though, setting the QML_IMPORT_PATH variable.

But getting the path is just the first step, as we'd have to crawl the directory looking for what we need. That may be a bad idea. In any case, this page has some helpful info on how QML searches for imports. A handy trick is using the QML_IMPORT_TRACE env var for debugging.

Another possible runtime solution could be trying to use QQmlImports::resolveType, but the lack of official documentation for that class is a bad sign.