As far as I can tell, Qt requires each plugin to provide a function qt_plugin_instance that returns some required metadata. (As well as some other adjacent machinery.)
Normally, C++ code would provide it by calling the QT_MOC_EXPORT_PLUGIN_V2 macro (the wiki provides some additional context, but it's also pretty outdated; Q_EXPORT_PLUGIN2 doesn't exist anymore), but we obviously can't do that from Rust.
Instead, cxx_qt_build::CxxQtBuild seems to be responsible for generating that stub if it's constructed via new_qml_module (via moc).
Given this repro (and building it with cargo build), I can confirm that it does write the call:
$ rg -uuu QT_MOC_EXPORT_PLUGIN_V2
target/debug/build/cxx-qt-plugin-16d11c48e807be72/out/moc/moc_mymodule_plugin.cpp.cpp
91:#ifdef QT_MOC_EXPORT_PLUGIN_V2
111:QT_MOC_EXPORT_PLUGIN_V2(mymodule_plugin, mymodule_plugin, qt_pluginMetaDataV2_mymodule_plugin)
137:#endif // QT_MOC_EXPORT_PLUGIN_V2
and that it does get linked in:
$ nm -gC target/debug/build/cxx-qt-plugin-16d11c48e807be72/out/libcxx-qt-plugin-cxxqt-generated.a | grep qt_plugin_instance
0000000000000000 T qt_plugin_instance
However, it doesn't seem to get reexported when linked into the final .so, and so it ends up dropped by the tree shaker:
$ nm -C target/debug/libcxx_qt_plugin.so | grep qt_plugin_instance
[a whole lot of nothing]
Which prevents Qt from picking up the plugin.
(Yes, I realize that there's more to be done in terms of actually helping Qt find the plugin, but that doesn't help if it refuses to load it anyway.)
As far as I can tell, Qt requires each plugin to provide a function
qt_plugin_instancethat returns some required metadata. (As well as some other adjacent machinery.)Normally, C++ code would provide it by calling the
QT_MOC_EXPORT_PLUGIN_V2macro (the wiki provides some additional context, but it's also pretty outdated;Q_EXPORT_PLUGIN2doesn't exist anymore), but we obviously can't do that from Rust.Instead,
cxx_qt_build::CxxQtBuildseems to be responsible for generating that stub if it's constructed vianew_qml_module(viamoc).Given this repro (and building it with
cargo build), I can confirm that it does write the call:and that it does get linked in:
However, it doesn't seem to get reexported when linked into the final .so, and so it ends up dropped by the tree shaker:
Which prevents Qt from picking up the plugin.
(Yes, I realize that there's more to be done in terms of actually helping Qt find the plugin, but that doesn't help if it refuses to load it anyway.)