From 34b900087c505d65b54a429abcba7f7526ce1ba4 Mon Sep 17 00:00:00 2001 From: Ray Donnelly Date: Mon, 3 Aug 2015 22:00:16 +0100 Subject: [PATCH 4/8] Implement Qt5 static plugin support Enabled via a new target property "AUTOSTATICPLUGINS". At CMake execution time, a C++ file is created to link the static plugins. For this to work, patches for Qt5-static from [1] are necessary [2], [3] and [4] [1] https://github.com/Alexpux/MINGW-packages/tree/master/mingw-w64-qt5-static [2] 0038-qt-5.4.0-Make-it-possible-to-use-static-builds-of-Qt-with-CMa.patch [3] 0039-qt-5.4.0-Generate-separated-libraries-in-prl-files-for-CMake.patch [4] 0041-qt-5.4.0-static-cmake-also-link-plugins-and-plugin-deps.patch .. and also some more minor ones that aren't strictly related to Qt5 static CMake but are necessary for this to work on MinGW-w64 (0040- for example). --- Source/cmGlobalGenerator.cxx | 6 ++-- Source/cmQtAutoGen.h | 3 +- Source/cmQtAutoGenInitializer.cxx | 65 ++++++++++++++++++++++++++++++++++++- Source/cmQtAutoGenInitializer.h | 2 ++ Source/cmTarget.cxx | 1 + Source/cmTargetPropertyComputer.cxx | 1 + 6 files changed, 74 insertions(+), 4 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index c805b98d7..aa50eebc8 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1502,7 +1502,8 @@ cmGlobalGenerator::CreateQtAutoGenInitializers() const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); - if (!mocEnabled && !uicEnabled && !rccEnabled) { + const bool staticPluginsEnabled = target->GetPropertyAsBool("AUTOSTATICPLUGINS"); + if (!mocEnabled && !uicEnabled && !rccEnabled && !staticPluginsEnabled) { continue; } @@ -1514,7 +1515,8 @@ cmGlobalGenerator::CreateQtAutoGenInitializers() } autogenInits.emplace_back(new cmQtAutoGenInitializer( - target, mocEnabled, uicEnabled, rccEnabled, qtVersionMajor)); + target, mocEnabled, uicEnabled, rccEnabled, staticPluginsEnabled, + qtVersionMajor)); } } #endif diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index 67f61b197..3d156e056 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -25,7 +25,8 @@ public: GEN, // General MOC, UIC, - RCC + RCC, + STATICPLUGINS }; public: diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 93c78b5bd..9e7349baa 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -86,6 +86,9 @@ static bool AddToSourceGroup(cmMakefile* makefile, std::string const& fileName, case cmQtAutoGen::GeneratorT::RCC: props[0] = "AUTORCC_SOURCE_GROUP"; break; + case cmQtAutoGen::GeneratorT::STATICPLUGINS: + props[0] = "AUTOSTATICPLUGINS_SOURCE_GROUP"; + break; default: props[0] = "AUTOGEN_SOURCE_GROUP"; break; @@ -192,11 +195,12 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, cmQtAutoGenInitializer::cmQtAutoGenInitializer( cmGeneratorTarget* target, bool mocEnabled, bool uicEnabled, bool rccEnabled, - std::string const& qtVersionMajor) + bool staticPluginsEnabled, std::string const& qtVersionMajor) : Target(target) , MocEnabled(mocEnabled) , UicEnabled(uicEnabled) , RccEnabled(rccEnabled) + , StaticPluginsEnabled(staticPluginsEnabled) , MultiConfig(false) , QtVersionMajor(qtVersionMajor) { @@ -366,6 +370,12 @@ void cmQtAutoGenInitializer::InitCustomTargets() } } + // Add AutoStaticPlugins import to generated files list + if (this->StaticPluginsEnabled) { + std::string staticPluginsComp = this->DirBuild + "/plugin_import.cpp"; + this->AddGeneratedSource(staticPluginsComp, GeneratorT::STATICPLUGINS); + } + // Extract relevant source files std::vector generatedSources; std::vector generatedHeaders; @@ -1051,6 +1061,59 @@ void cmQtAutoGenInitializer::SetupCustomTargets() } } } + + // Generate plugin static-link source files + if (this->StaticPluginsEnabled) + { + /* in qt5-static/lib/cmake/Qt5Core/Qt5CoreConfig.cmake, + * macro(_populate_Core_plugin_properties ..), we'd have: + * set_property(TARGET PROPERTY AUTOSTATICPLUGINS True) // Not currently needed + * as defaults to "ON" + * set_property(TARGET Qt5::Core APPEND PROPERTY STATIC_PLUGINS ${Plugin}) + */ + + std::vector libTargets = + this->Target->GetLinkImplementationClosure(""); + std::vector::const_iterator li; + std::vector staticPlugins; + for (li = libTargets.begin(); li != libTargets.end(); ++li) { + cmGeneratorTarget const* tgt = *li; + const char* staticPluginsProp = tgt->GetProperty("STATIC_PLUGINS"); + if (staticPluginsProp) { + std::vector staticPluginsTgt = + cmSystemTools::tokenize(staticPluginsProp, ";"); + for (std::vector::const_iterator spti = + staticPluginsTgt.begin(); + spti != staticPluginsTgt.end(); ++spti) { + if (std::find(staticPlugins.begin(), staticPlugins.end(), *spti) == + staticPlugins.end()) { + staticPlugins.push_back(*spti); + } + } + } + } + + std::string static_plugins_output_file = this->DirBuild + "/plugin_import.cpp"; + cmGeneratedFileStream staticPluginsFileStream( + static_plugins_output_file.c_str()); + if (staticPluginsFileStream) { + staticPluginsFileStream << "// This file is autogenerated by cmake. " + "It imports static plugin classes for" + << std::endl; + staticPluginsFileStream + << "// static plugins specified using QTPLUGIN and " + "QT_PLUGIN_CLASS. variables." + << std::endl; + staticPluginsFileStream << "#include " << std::endl; + for (std::vector::const_iterator spti = + staticPlugins.begin(); + spti != staticPlugins.end(); ++spti) { + staticPluginsFileStream << "Q_IMPORT_PLUGIN(" << *spti << ")" + << std::endl; + } + staticPluginsFileStream.Close(); + } + } } void cmQtAutoGenInitializer::SetupCustomTargetsMoc() diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 2a47e46a4..1f21b3476 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -47,6 +47,7 @@ public: public: cmQtAutoGenInitializer(cmGeneratorTarget* target, bool mocEnabled, bool uicEnabled, bool rccEnabled, + bool staticPluginsEnabled, std::string const& qtVersionMajor); void InitCustomTargets(); @@ -70,6 +71,7 @@ private: bool MocEnabled; bool UicEnabled; bool RccEnabled; + bool StaticPluginsEnabled; bool MultiConfig; // Qt std::string QtVersionMajor; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index cd11c4b14..1b0bfbdcd 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -247,6 +247,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, this->SetPropertyDefault("AUTOMOC", nullptr); this->SetPropertyDefault("AUTOUIC", nullptr); this->SetPropertyDefault("AUTORCC", nullptr); + this->SetPropertyDefault("AUTOSTATICPLUGINS", nullptr); this->SetPropertyDefault("AUTOGEN_PARALLEL", nullptr); this->SetPropertyDefault("AUTOMOC_COMPILER_PREDEFINES", nullptr); this->SetPropertyDefault("AUTOMOC_DEPEND_FILTERS", nullptr); diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx index 06ce0b1e6..0e7ccb34e 100644 --- a/Source/cmTargetPropertyComputer.cxx +++ b/Source/cmTargetPropertyComputer.cxx @@ -66,6 +66,7 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty( builtIns.insert("IMPORTED"); builtIns.insert("IMPORTED_GLOBAL"); builtIns.insert("NAME"); + builtIns.insert("STATIC_PLUGINS"); builtIns.insert("TYPE"); } -- 2.16.2.windows.1