diff --git a/pkgs/development/libraries/qt-5/5.11/default.nix b/pkgs/development/libraries/qt-5/5.11/default.nix index b50ff61219fd4c..2e462029afba26 100644 --- a/pkgs/development/libraries/qt-5/5.11/default.nix +++ b/pkgs/development/libraries/qt-5/5.11/default.nix @@ -39,6 +39,7 @@ let patches = { qtbase = [ ./qtbase.patch + ./qtbase-additional.patch ./qtbase-darwin.patch ./qtbase-revert-no-macos10.10.patch ]; diff --git a/pkgs/development/libraries/qt-5/5.11/qtbase-additional.patch b/pkgs/development/libraries/qt-5/5.11/qtbase-additional.patch new file mode 100644 index 00000000000000..5cd8cbef934525 --- /dev/null +++ b/pkgs/development/libraries/qt-5/5.11/qtbase-additional.patch @@ -0,0 +1,32 @@ +diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp +index 5ae3fd62e5..ec3fccfc76 100644 +--- a/src/corelib/kernel/qcoreapplication.cpp ++++ b/src/corelib/kernel/qcoreapplication.cpp +@@ -2533,6 +2533,27 @@ QStringList QCoreApplication::libraryPaths() + QStringList *app_libpaths = new QStringList; + coreappdata()->app_libpaths.reset(app_libpaths); + ++ { ++ // Start at the binary; this allows us to *always* start by stripping the last part. ++ QStringList components = applicationFilePath().split(QDir::separator()); ++ ++ // We don't care about /nix/store/nix-support, only /nix/store/*/nix-support ++ // This is why we're checking for more than 3 parts. It will bail out once /nix/xtore/*/nix-support/qt-plugin-paths has been tested. ++ while (components.length() > 4) { ++ components.removeLast(); ++ const QString support_plugin_paths = QDir::cleanPath(QDir::separator() + components.join(QDir::separator()) + QStringLiteral("/nix-support/qt-plugin-paths")); ++ if (QFile::exists(support_plugin_paths)) { ++ QFile file(support_plugin_paths); ++ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { ++ QTextStream in(&file); ++ while (!in.atEnd()) { ++ app_libpaths->append(in.readLine()); ++ } ++ } ++ } ++ } ++ } ++ + // Add library paths derived from PATH + const QStringList paths = QFile::decodeName(qgetenv("PATH")).split(':'); + const QString plugindir = QStringLiteral("../" NIXPKGS_QT_PLUGIN_PREFIX); diff --git a/pkgs/development/libraries/qt-5/5.9/default.nix b/pkgs/development/libraries/qt-5/5.9/default.nix index e109fe447aa235..0c5878f256132f 100644 --- a/pkgs/development/libraries/qt-5/5.9/default.nix +++ b/pkgs/development/libraries/qt-5/5.9/default.nix @@ -37,7 +37,7 @@ let srcs = import ./srcs.nix { inherit fetchurl; inherit mirror; }; patches = { - qtbase = [ ./qtbase.patch ] ++ optional stdenv.isDarwin ./qtbase-darwin.patch; + qtbase = [ ./qtbase.patch ./qtbase-additional.patch ] ++ optional stdenv.isDarwin ./qtbase-darwin.patch; qtdeclarative = [ ./qtdeclarative.patch ]; qtscript = [ ./qtscript.patch ]; qtserialport = [ ./qtserialport.patch ]; diff --git a/pkgs/development/libraries/qt-5/5.9/qtbase-additional.patch b/pkgs/development/libraries/qt-5/5.9/qtbase-additional.patch new file mode 100644 index 00000000000000..5cd8cbef934525 --- /dev/null +++ b/pkgs/development/libraries/qt-5/5.9/qtbase-additional.patch @@ -0,0 +1,32 @@ +diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp +index 5ae3fd62e5..ec3fccfc76 100644 +--- a/src/corelib/kernel/qcoreapplication.cpp ++++ b/src/corelib/kernel/qcoreapplication.cpp +@@ -2533,6 +2533,27 @@ QStringList QCoreApplication::libraryPaths() + QStringList *app_libpaths = new QStringList; + coreappdata()->app_libpaths.reset(app_libpaths); + ++ { ++ // Start at the binary; this allows us to *always* start by stripping the last part. ++ QStringList components = applicationFilePath().split(QDir::separator()); ++ ++ // We don't care about /nix/store/nix-support, only /nix/store/*/nix-support ++ // This is why we're checking for more than 3 parts. It will bail out once /nix/xtore/*/nix-support/qt-plugin-paths has been tested. ++ while (components.length() > 4) { ++ components.removeLast(); ++ const QString support_plugin_paths = QDir::cleanPath(QDir::separator() + components.join(QDir::separator()) + QStringLiteral("/nix-support/qt-plugin-paths")); ++ if (QFile::exists(support_plugin_paths)) { ++ QFile file(support_plugin_paths); ++ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { ++ QTextStream in(&file); ++ while (!in.atEnd()) { ++ app_libpaths->append(in.readLine()); ++ } ++ } ++ } ++ } ++ } ++ + // Add library paths derived from PATH + const QStringList paths = QFile::decodeName(qgetenv("PATH")).split(':'); + const QString plugindir = QStringLiteral("../" NIXPKGS_QT_PLUGIN_PREFIX); diff --git a/pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh b/pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh index 3a558153988c31..10553ba30ba39a 100644 --- a/pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh +++ b/pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh @@ -62,3 +62,59 @@ postPatchMkspecs() { if [ -z "$dontPatchMkspecs" ]; then postPhases="${postPhases}${postPhases:+ }postPatchMkspecs" fi + +_Qt_sortless_uniq() { + # `uniq`, but keeps initial order. + # This is to remove risks of combinatorial explosion of plugin paths. + cat -n | sort -uk2 | sort -nk1 | cut -f2- +} + +_QtGetPluginPaths() { + # Lists all plugin paths for current Qt for given buildInputs and propagatedBuildInputs + local i + local _i + local o + local inputs + + # FIXME : this causes output path cycles... + # I am unsure if it is even needed, though. + ## Outputs self's plugins paths + #for o in $outputs; do + # o="${!o}/@qtPluginPrefix@" + # if [ -e "$o" ]; then + # echo "$o" + # fi + #done + + inputs="$( + for i in $buildInputs $propagatedBuildInputs; do + echo "$i" + done | uniq + )" + + for i in $inputs; do + _i="$i/@qtPluginPrefix@" + if [ -e "$_i" ]; then + echo "$_i" + fi + _i="$i/nix-support/qt-plugin-paths" + if [ -e "$_i" ]; then + cat "$_i" + fi + done +} + +postAddPluginPaths() { + # Dumps all plugins paths to a nix-support file inside all outputs. + local o + + for o in $outputs; do + o="${!o}/nix-support" + mkdir -p "$o" + _QtGetPluginPaths | _Qt_sortless_uniq > $o/qt-plugin-paths + done +} + +if [ -z "$dontAddPluginPaths" ]; then + postPhases="${postPhases}${postPhases:+ }postAddPluginPaths" +fi diff --git a/pkgs/development/libraries/qt-5/modules/qtbase.nix b/pkgs/development/libraries/qt-5/modules/qtbase.nix index 15e19c77567a01..dde5c8feb571d0 100644 --- a/pkgs/development/libraries/qt-5/modules/qtbase.nix +++ b/pkgs/development/libraries/qt-5/modules/qtbase.nix @@ -382,7 +382,13 @@ stdenv.mkDerivation { sed -i "$dev/lib/pkgconfig/Qt5Core.pc" \ -e "/^host_bins=/ c host_bins=$dev/bin" '' - ); + ) + + '' + # Adds `qtbase-bin` as a basic dependency to *all* qtbase builds. + mkdir -p $dev/nix-support + echo "$bin/$qtPluginPrefix" >> $dev/nix-support/qt-plugin-paths + '' + ; setupHook = ../hooks/qtbase-setup-hook.sh;