When a CMake application project uses a static Qt build, we provide a mechanism to automatically link in a default set of Qt plugins so that the application works out of the box.
This is achieved by adding the plugins to Qt's library link interface (on modules like Qt::Gui) via big generator expressions.
This caused quite a few issues in the implementation of the build system of Qt, as well as certain user project scenarios like in
Try to resurrect the new approach that was tried in https://codereview.qt-project.org/c/qt/qtbase/+/298273
which is to use scope finalizers in qt_add_executable(), so that the plugins are linked at scope finalizer time, and not via Qt's library link interface.
The scope finalizer approach has a few advantages.
1) We can generate one single .cpp file to initialize plugins using the Q_IMPORT_PLUGIN macro, instead of generating one file per plugin. This dramatically speeds up user project compilation if the project has many targets using static Qt. Should fix
2) We can call find_package(QtFoo) to find plugin targets that might not have been created in the current directory scope, which would eliminate the issue at
3) It would fix the work around we did for QTBUG-83498 .
Making the plugin depend on its plugin type module and vice versa causes a static linkage cycle which would influence the link order and cause undefined symbol issues. Removing the link cycle means we don't need to set the link interface multiplicity, the libraries would not be repeated on the link line, and thus link time should go down.
It also has disadvantages
1) User projects will require CMake version 3.19+ to use the scope finalizers aka cmake_language(DEFER CALL).
Fortunately it should be possible to fail gracefully to the old approach when the CMake version is lower, thus not breaking user projects.
We can probably relax the 3.19 requirement by allowing the user to call the finalizer manually in their project, thus opting into the new approach explicitly without requiring a new CMake version.
2) Projects have to use qt_add_executable instead of add_executable, so that we can defer finalizers.
This can be easily mitigated by providing a standalone function that a user project can call themselves.