Details
-
Task
-
Resolution: Done
-
P2: Important
-
6.0, 6.1, 6.2
Description
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 QTBUG-92878.
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 QTBUG-80863
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 QTBUG-92878
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.
Attachments
Issue Links
- relates to
-
QTBUG-96767 static_plugin finalizer mode not applied to shared libraries
- Reported
-
QTBUG-92978 CMake linker error with Linux Static Libraries
- Closed
-
QTBUG-97099 [cmake] dependent qml plugins not auto-loaded with statically linked qt
- Closed
-
QTBUG-95609 cmake names for qml plugins
- Closed
-
QTBUG-94605 Validate use case of qmlimportscanner returning info about a qml plugin without a CMake target
- Reported
-
QTBUG-83498 Fix handling of plugins in static builds (and the dependency cycles it creates)
- Open
-
QTBUG-93257 qt6_import_qml_plugins does not compose
- Closed
-
QTBUG-80863 [cmake] excessive compilation of Import.cpp files for static plugins
- Closed
-
QTBUG-92878 [qt6/cmake] Qt Resource object libraries not found in sibling scopes due to not being global
- Closed
-
QTBUG-92887 [cmake] qt6_import_qml_plugins without import scanner
- Reported