Breakthrough!!!
Not everything is fully tested yet, and I already see that some plugins are still not working yet, but it looks like a major breakthrough is now reached! So I want to share it here.
And it is not the XML file, not any EXCLUDE_WRAP or whatever: the key is in the vtk.module file!
Symptom: plugins do compile and build without trouble, also they are loaded - and once they should do their job, they are crashing with that fatal message that “client server wrapping is not initialized”. The only problem is then: after learning about how to successfully write PV plugins, currently mostly from examples (and the one or other friendly hint from experts!) in a rather “top level” way, such a message from the “lowest level” is hard to follow - because there is a long way to go from that top level to the bottom of how things are working. But without that, a solution cannot be found!
First of all, turning on the maximum tracking and logging is important:
- define an environment variable PARAVIEW_LOG_PIPELINE_VERBOSITY and set it to MAX
- start the program with -v=TRACE as command line parameter
On top of that, I had to insert a number of vtkWarningMessage() commands into the ParaView code - in order to see what is actually going on in the different functions (and of course recompile Paraview then). This is important because there are thousands of plugins loaded before the own set of plugins is handled - which is far beyond common debugging with a debugger.
Basically plugins are first found and “registered”. That basically means: an initialization function is put into a list of plugin initialization functions. If this does not work, the program will complain about “not a proper plugin”, and otherwise it will keep the plugin.
Next, I am “loading” the plugins from the main window constructor of my application. For some unknown reason this triggers another round of searching for the shared library file of the plugin. (I did not do further research about this because it worked already long ago for all my plugins, plus the optional PV plugins that I decided to include into my application.)
With this, all the plugins are visible in the Plugin manager and marked as “loaded” - which gives the impression of a full success - but this is totally wrong! Only now the famous “client server wrapping” will hit - at the moment that the plugin is first being used for some functionality.
At that moment, the vtkSIProxy::CreateVTKObjects() function tries to create an object from one of the classes in the plugin, and for that it tries to find a “new instance function” in a list of such functions - and fails if it does not exist.
So the question arises: where does this function come from, and how does it come into that list? The second question is easier to answer than the first: it comes with the “registration” step above: the initialization function, that is registered for every plugin, actually adds these functions - OR NOT!
In my specific case I found out that those plugins that did load properly did have such an initialization function (_Init()), but that was empty. Not that the “new instance functions” (ClientServerNewCommand) did not exist for the class - only they were not added withing the Init function!
This adding of that function into the _Init() function seems to be named “client server wrapping” in the PV language. But where does it happen? There is actually an external tool for that purpose: vtkWrapClientServer.
Now this program takes a “hierarchy” file as input, and somehow processes this into the proper “wrapping” code in the _Init() function - or else just generates an empty dummy. So next question: what is this “hierarchy” file and where does it come from? Looking into it, it looks like it contains some info about required code for the working of a specific class, like the parent class and somehow also many others.
This I also did not fully get detangled, but I was lucky that my guess went now towards the vtk.module vile - which has both a DEPENDS and a PRIVATE_DEPENDS section - and that looks like where the key for the “strange” behaviour can be found:
- If nothing is in the DEPENDS section, the cmake code will already complain that this is not very likely - because whatever module is there, must depend on something.
- Next you will get compile errors if certain #includes are not found. In my case, with all code that was already once built and tested successfully with an earlier version of PV, this always meant: some additional target/module/library has to be added in the vtk.module file.
With this, the entire application finally built and started successfully! But - see above.
Now so far I put some of the dependencies into the DEPENDS section - if I had the impression that they are “core” for that new module - and others I put into the PRIVATE_DEPENDS section, like if the module is only “using” some functions from another module. And for compilation it looks like there is no really visible difference between the two. So I put more into the PRIVATE_DEPENDS - like I would also put all “internal” stuff into the private section of a C++ class. But that turned out to be completely wrong:
THE DIFFERENCE IS WITH THE “CLIENT SERVER WRAPPING”!!
So finally the “trick” was: move some more modules/targets from the PRIVATE_DEPENDS to the DEPENDS section. The effect was: the “hierarchy” files became much bigger - and finally the “new instance functions” were also appearing in the _Init() functions - AND THE PLUGINS DID NOT CRASH ANY MORE!
I am writing this long story only in order to help others to avoid this very long and tedious way: Of course I left out all the many detours that I also had to try unsuccessfully. So I am now happy if I can save one person from having to repeat this odyssee!