about summary refs log tree commit diff
path: root/pkgs/development
diff options
context:
space:
mode:
authorThomas Tuegel <ttuegel@mailbox.org>2019-07-05 14:38:10 -0500
committerGitHub <noreply@github.com>2019-07-05 14:38:10 -0500
commit56d5963382da1b4848615aa9139e527978c64670 (patch)
tree6e76232d7b4fd5cf3034eef18f0e109f2b86bbb0 /pkgs/development
parent066491c2e18d6277e0765a3647068c93650fcd19 (diff)
parent3adc9d04870605ca20969a98fe820535fc7a88a5 (diff)
downloadnixlib-56d5963382da1b4848615aa9139e527978c64670.tar
nixlib-56d5963382da1b4848615aa9139e527978c64670.tar.gz
nixlib-56d5963382da1b4848615aa9139e527978c64670.tar.bz2
nixlib-56d5963382da1b4848615aa9139e527978c64670.tar.lz
nixlib-56d5963382da1b4848615aa9139e527978c64670.tar.xz
nixlib-56d5963382da1b4848615aa9139e527978c64670.tar.zst
nixlib-56d5963382da1b4848615aa9139e527978c64670.zip
Merge pull request #54525 from ttuegel/feature/qt-5/wrap-qt-apps
Wrap Qt applications
Diffstat (limited to 'pkgs/development')
-rw-r--r--pkgs/development/compilers/nextpnr/default.nix15
-rw-r--r--pkgs/development/libraries/cutelyst/default.nix10
-rw-r--r--pkgs/development/libraries/gsettings-qt/default.nix6
-rw-r--r--pkgs/development/libraries/kde-frameworks/default.nix15
-rw-r--r--pkgs/development/libraries/kde-frameworks/extra-cmake-modules/setup-hook.sh64
-rw-r--r--pkgs/development/libraries/kde-frameworks/kinit/default.nix4
-rw-r--r--pkgs/development/libraries/qt-5/5.11/default.nix34
-rw-r--r--pkgs/development/libraries/qt-5/5.12/default.nix34
-rw-r--r--pkgs/development/libraries/qt-5/5.6/default.nix30
-rw-r--r--pkgs/development/libraries/qt-5/5.9/default.nix30
-rw-r--r--pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh22
-rw-r--r--pkgs/development/libraries/qt-5/hooks/wrap-qt-apps-hook.sh106
-rw-r--r--pkgs/development/libraries/qt-5/mkDerivation.nix8
-rw-r--r--pkgs/development/libraries/qt-5/modules/qtspeech.nix2
-rw-r--r--pkgs/development/r-modules/wrapper-rstudio.nix9
-rw-r--r--pkgs/development/tools/analysis/hopper/default.nix26
-rw-r--r--pkgs/development/tools/qtcreator/default.nix16
-rw-r--r--pkgs/development/tools/tora/default.nix7
18 files changed, 319 insertions, 119 deletions
diff --git a/pkgs/development/compilers/nextpnr/default.nix b/pkgs/development/compilers/nextpnr/default.nix
index ec5deb4e22aa..d1c0db25351c 100644
--- a/pkgs/development/compilers/nextpnr/default.nix
+++ b/pkgs/development/compilers/nextpnr/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchFromGitHub, cmake, makeWrapper
+{ stdenv, fetchFromGitHub, cmake
 , boost, python3, eigen
 , icestorm, trellis
 
@@ -6,7 +6,7 @@
 # laptop (and over a remote X server on my server...), so mark it broken for
 # now, with intent to fix later.
 , enableGui ? false
-, qtbase
+, qtbase, wrapQtAppsHook
 }:
 
 let
@@ -36,7 +36,9 @@ stdenv.mkDerivation rec {
     sha256 = "1y14jpa948cwk0i19bsfqh7yxsxkgskm4xym4z179sjcvcdvrn3a";
   };
 
-  nativeBuildInputs = [ cmake makeWrapper ];
+  nativeBuildInputs
+     = [ cmake ]
+    ++ (stdenv.lib.optional enableGui wrapQtAppsHook);
   buildInputs
      = [ boostPython python3 eigen ]
     ++ (stdenv.lib.optional enableGui qtbase);
@@ -56,13 +58,6 @@ stdenv.mkDerivation rec {
       --replace 'git log -1 --format=%h' 'echo ${substring 0 11 src.rev}'
   '';
 
-  postInstall = stdenv.lib.optionalString enableGui ''
-    for x in generic ice40 ecp5; do
-      wrapProgram $out/bin/nextpnr-$x \
-        --prefix QT_PLUGIN_PATH : "${qtbase}/${qtbase.qtPluginPrefix}"
-    done
-  '';
-
   meta = with stdenv.lib; {
     description = "Place and route tool for FPGAs";
     homepage    = https://github.com/yosyshq/nextpnr;
diff --git a/pkgs/development/libraries/cutelyst/default.nix b/pkgs/development/libraries/cutelyst/default.nix
index 784a282f6b24..c4778e5b0301 100644
--- a/pkgs/development/libraries/cutelyst/default.nix
+++ b/pkgs/development/libraries/cutelyst/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, lib, fetchFromGitHub, cmake, pkgconfig, makeWrapper
+{ stdenv, lib, fetchFromGitHub, cmake, pkgconfig, wrapQtAppsHook
 , qtbase, libuuid, libcap, uwsgi, grantlee, pcre
 }:
 
@@ -13,7 +13,7 @@ stdenv.mkDerivation rec {
     sha256 = "09cgfpr2k1jp98h1ahxqm5lmv3qbk0bcxpqpill6n5wmq2c8kl8b";
   };
 
-  nativeBuildInputs = [ cmake pkgconfig makeWrapper ];
+  nativeBuildInputs = [ cmake pkgconfig wrapQtAppsHook ];
   buildInputs = [ qtbase libuuid libcap uwsgi grantlee pcre ];
 
   cmakeFlags = [
@@ -31,12 +31,6 @@ stdenv.mkDerivation rec {
     unset LD_LIBRARY_PATH
   '';
 
-  postInstall = ''
-    for prog in $out/bin/*; do
-      wrapProgram "$prog" --set QT_PLUGIN_PATH '${qtbase}/${qtbase.qtPluginPrefix}'
-    done
-  '';
-
   meta = with lib; {
     description = "C++ Web Framework built on top of Qt";
     homepage = https://cutelyst.org/;
diff --git a/pkgs/development/libraries/gsettings-qt/default.nix b/pkgs/development/libraries/gsettings-qt/default.nix
index 3f9cd8120d89..744d9eb6de90 100644
--- a/pkgs/development/libraries/gsettings-qt/default.nix
+++ b/pkgs/development/libraries/gsettings-qt/default.nix
@@ -1,4 +1,7 @@
-{ stdenv, fetchbzr, pkgconfig, qmake, qtbase, qtdeclarative, glib, gobject-introspection }:
+{ stdenv, fetchbzr, pkgconfig
+, qmake, qtbase, qtdeclarative, wrapQtAppsHook
+, glib, gobject-introspection
+}:
 
 stdenv.mkDerivation rec {
   name = "gsettings-qt-${version}";
@@ -14,6 +17,7 @@ stdenv.mkDerivation rec {
     pkgconfig
     qmake
     gobject-introspection
+    wrapQtAppsHook
   ];
 
   buildInputs = [
diff --git a/pkgs/development/libraries/kde-frameworks/default.nix b/pkgs/development/libraries/kde-frameworks/default.nix
index 62ae433ff710..7745d78f8fca 100644
--- a/pkgs/development/libraries/kde-frameworks/default.nix
+++ b/pkgs/development/libraries/kde-frameworks/default.nix
@@ -45,17 +45,9 @@ let
                 if [ "$hookName" != postHook ]; then
                     postHooks+=("source @dev@/nix-support/setup-hook")
                 else
-                    # Propagate $${out} output
-                    propagatedUserEnvPkgs="$propagatedUserEnvPkgs @${out}@"
-
-                    if [ -z "$outputDev" ]; then
-                        echo "error: \$outputDev is unset!" >&2
-                        exit 1
-                    fi
-
                     # Propagate $dev so that this setup hook is propagated
                     # But only if there is a separate $dev output
-                    if [ "$outputDev" != out ]; then
+                    if [ "''${outputDev:?}" != out ]; then
                         propagatedBuildInputs="$propagatedBuildInputs @dev@"
                     fi
                 fi
@@ -75,10 +67,9 @@ let
             inherit (srcs."${name}") src version;
 
             outputs = args.outputs or [ "bin" "dev" "out" ];
-            hasBin = lib.elem "bin" outputs;
-            hasDev = lib.elem "dev" outputs;
+            hasSeparateDev = lib.elem "dev" outputs;
 
-            defaultSetupHook = if hasBin && hasDev then propagateBin else null;
+            defaultSetupHook = if hasSeparateDev then propagateBin else null;
             setupHook = args.setupHook or defaultSetupHook;
 
             meta = {
diff --git a/pkgs/development/libraries/kde-frameworks/extra-cmake-modules/setup-hook.sh b/pkgs/development/libraries/kde-frameworks/extra-cmake-modules/setup-hook.sh
index 88091e78a0cd..4df086ddbf21 100644
--- a/pkgs/development/libraries/kde-frameworks/extra-cmake-modules/setup-hook.sh
+++ b/pkgs/development/libraries/kde-frameworks/extra-cmake-modules/setup-hook.sh
@@ -1,16 +1,16 @@
-_ecmEnvHook() {
+ecmEnvHook() {
     addToSearchPath XDG_DATA_DIRS "$1/share"
     addToSearchPath XDG_CONFIG_DIRS "$1/etc/xdg"
 }
-addEnvHooks "$targetOffset" _ecmEnvHook
+addEnvHooks "$targetOffset" ecmEnvHook
 
-_ecmPreConfigureHook() {
+ecmPostHook() {
     # Because we need to use absolute paths here, we must set *all* the paths.
     cmakeFlags+=" -DKDE_INSTALL_EXECROOTDIR=${!outputBin}"
     cmakeFlags+=" -DKDE_INSTALL_BINDIR=${!outputBin}/bin"
     cmakeFlags+=" -DKDE_INSTALL_SBINDIR=${!outputBin}/sbin"
     cmakeFlags+=" -DKDE_INSTALL_LIBDIR=${!outputLib}/lib"
-    cmakeFlags+=" -DKDE_INSTALL_LIBEXECDIR=${!outputLib}/lib/libexec"
+    cmakeFlags+=" -DKDE_INSTALL_LIBEXECDIR=${!outputLib}/libexec"
     cmakeFlags+=" -DKDE_INSTALL_CMAKEPACKAGEDIR=${!outputDev}/lib/cmake"
     cmakeFlags+=" -DKDE_INSTALL_INCLUDEDIR=${!outputInclude}/include"
     cmakeFlags+=" -DKDE_INSTALL_LOCALSTATEDIR=/var"
@@ -51,4 +51,58 @@ _ecmPreConfigureHook() {
         cmakeFlags+=" -DKDE_INSTALL_QMLDIR=${!outputBin}/$qtQmlPrefix"
     fi
 }
-preConfigureHooks+=(_ecmPreConfigureHook)
+postHooks+=(ecmPostHook)
+
+xdgDataSubdirs=(
+    "doc" "config.kcfg" "kconf_update" "kservices5" "kservicetypes5" \
+    "kxmlgui5" "knotifications5" "icons" "locale" "sounds" "templates" \
+    "wallpapers" "applications" "desktop-directories" "mime" "appdata" "dbus-1" \
+)
+
+
+ecmHostPathSeen=( )
+
+ecmUnseenHostPath() {
+    for pkg in "${ecmHostPathSeen[@]}"
+    do
+        if [ "${pkg:?}" == "$1" ]
+        then
+            return 1
+        fi
+    done
+
+    ecmHostPathSeen+=("$1")
+    return 0
+}
+
+ecmHostPathHook() {
+    ecmUnseenHostPath "$1" || return 0
+
+    local xdgConfigDir="$1/etc/xdg"
+    if [ -d "$xdgConfigDir" ]
+    then
+        qtWrapperArgs+=(--prefix XDG_CONFIG_DIRS : "$xdgConfigDir")
+    fi
+
+    for xdgDataSubdir in "${xdgDataSubdirs[@]}"
+    do
+        if [ -d "$1/share/$xdgDataSubdir" ]
+        then
+            qtWrapperArgs+=(--prefix XDG_DATA_DIRS : "$1/share")
+            break
+        fi
+    done
+
+    local manDir="$1/man"
+    if [ -d "$manDir" ]
+    then
+        qtWrapperArgs+=(--prefix MANPATH : "$manDir")
+    fi
+
+    local infoDir="$1/info"
+    if [ -d "$infoDir" ]
+    then
+        qtWrapperArgs+=(--prefix INFOPATH : "$infoDir")
+    fi
+}
+addEnvHooks "$hostOffset" ecmHostPathHook
diff --git a/pkgs/development/libraries/kde-frameworks/kinit/default.nix b/pkgs/development/libraries/kde-frameworks/kinit/default.nix
index 538078fd7457..42a1e157a917 100644
--- a/pkgs/development/libraries/kde-frameworks/kinit/default.nix
+++ b/pkgs/development/libraries/kde-frameworks/kinit/default.nix
@@ -9,6 +9,7 @@ let inherit (lib) getLib; in
 mkDerivation {
   name = "kinit";
   meta = { maintainers = [ lib.maintainers.ttuegel ]; };
+  outputs = [ "out" "dev" ];
   nativeBuildInputs = [ extra-cmake-modules kdoctools ];
   buildInputs = [
     kconfig kcrash ki18n kio kservice kwindowsystem
@@ -19,9 +20,6 @@ mkDerivation {
     ''-DNIXPKGS_KF5_PARTS=\"${getLib kparts}/lib/libKF5Parts.so.5\"''
     ''-DNIXPKGS_KF5_PLASMA=\"${getLib plasma-framework}/lib/libKF5Plasma.so.5\"''
   ];
-  postFixup = ''
-    moveToOutput "lib/libexec/kf5/start_kdeinit" "$bin"
-  '';
   setupHook = writeScript "setup-hook.sh" ''
     kinitFixupOutputHook() {
         if [ $prefix != ''${!outputBin} ] && [ -d $prefix/lib ]; then
diff --git a/pkgs/development/libraries/qt-5/5.11/default.nix b/pkgs/development/libraries/qt-5/5.11/default.nix
index fe01b89081f4..67c5047e5078 100644
--- a/pkgs/development/libraries/qt-5/5.11/default.nix
+++ b/pkgs/development/libraries/qt-5/5.11/default.nix
@@ -17,7 +17,7 @@ top-level attribute to `top-level/all-packages.nix`.
 
 {
   newScope,
-  stdenv, fetchurl, fetchFromGitHub, makeSetupHook,
+  stdenv, fetchurl, fetchFromGitHub, makeSetupHook, makeWrapper,
   bison, cups ? null, harfbuzz, libGL, perl,
   gstreamer, gst-plugins-base, gtk3, dconf,
   llvmPackages_5,
@@ -34,6 +34,8 @@ let
 
   qtCompatVersion = "5.11";
 
+  stdenvActual = if stdenv.cc.isClang then llvmPackages_5.stdenv else stdenv;
+
   mirror = "https://download.qt.io";
   srcs = import ./srcs.nix { inherit fetchurl; inherit mirror; } // {
     # Community port of the now unmaintained upstream qtwebkit.
@@ -64,16 +66,18 @@ let
     qtwebkit = [ ./qtwebkit.patch ];
   };
 
-  mkDerivation =
-    import ../mkDerivation.nix {
-      inherit (stdenv) lib;
-      stdenv = if stdenv.cc.isClang then llvmPackages_5.stdenv else stdenv;
-    }
-    { inherit debug; };
-
   qtModule =
     import ../qtModule.nix
-    { inherit mkDerivation perl; inherit (stdenv) lib; }
+    {
+      inherit perl;
+      inherit (stdenv) lib;
+      # Use a variant of mkDerivation that does not include wrapQtApplications
+      # to avoid cyclic dependencies between Qt modules.
+      mkDerivation =
+        import ../mkDerivation.nix
+        { inherit (stdenv) lib; inherit debug; wrapQtAppsHook = null; }
+        stdenvActual.mkDerivation;
+    }
     { inherit self srcs patches; };
 
   addPackages = self: with self;
@@ -81,7 +85,11 @@ let
       callPackage = self.newScope { inherit qtCompatVersion qtModule srcs; };
     in {
 
-      inherit mkDerivation;
+      mkDerivationWith =
+        import ../mkDerivation.nix
+        { inherit (stdenv) lib; inherit debug; inherit (self) wrapQtAppsHook; };
+
+      mkDerivation = mkDerivationWith stdenvActual.mkDerivation;
 
       qtbase = callPackage ../modules/qtbase.nix {
         inherit (srcs.qtbase) src version;
@@ -142,6 +150,12 @@ let
           fix_qt_builtin_paths = ../hooks/fix-qt-builtin-paths.sh;
         };
       } ../hooks/qmake-hook.sh;
+
+      wrapQtAppsHook = makeSetupHook {
+        deps =
+          [ self.qtbase.dev makeWrapper ]
+          ++ optional stdenv.isLinux self.qtwayland.dev;
+      } ../hooks/wrap-qt-apps-hook.sh;
     };
 
    self = makeScope newScope addPackages;
diff --git a/pkgs/development/libraries/qt-5/5.12/default.nix b/pkgs/development/libraries/qt-5/5.12/default.nix
index 57b89dd43865..1fbf7b57289f 100644
--- a/pkgs/development/libraries/qt-5/5.12/default.nix
+++ b/pkgs/development/libraries/qt-5/5.12/default.nix
@@ -17,7 +17,7 @@ top-level attribute to `top-level/all-packages.nix`.
 
 {
   newScope,
-  stdenv, fetchurl, fetchFromGitHub, makeSetupHook,
+  stdenv, fetchurl, fetchFromGitHub, makeSetupHook, makeWrapper,
   bison, cups ? null, harfbuzz, libGL, perl,
   gstreamer, gst-plugins-base, gtk3, dconf,
   llvmPackages_5,
@@ -34,6 +34,8 @@ let
 
   qtCompatVersion = "5.12";
 
+  stdenvActual = if stdenv.cc.isClang then llvmPackages_5.stdenv else stdenv;
+
   mirror = "https://download.qt.io";
   srcs = import ./srcs.nix { inherit fetchurl; inherit mirror; } // {
     # Community port of the now unmaintained upstream qtwebkit.
@@ -69,16 +71,18 @@ let
     qttools = [ ./qttools.patch ];
   };
 
-  mkDerivation =
-    import ../mkDerivation.nix {
-      inherit (stdenv) lib;
-      stdenv = if stdenv.cc.isClang then llvmPackages_5.stdenv else stdenv;
-    }
-    { inherit debug; };
-
   qtModule =
     import ../qtModule.nix
-    { inherit mkDerivation perl; inherit (stdenv) lib; }
+    {
+      inherit perl;
+      inherit (stdenv) lib;
+      # Use a variant of mkDerivation that does not include wrapQtApplications
+      # to avoid cyclic dependencies between Qt modules.
+      mkDerivation =
+        import ../mkDerivation.nix
+        { inherit (stdenv) lib; inherit debug; wrapQtAppsHook = null; }
+        stdenvActual.mkDerivation;
+    }
     { inherit self srcs patches; };
 
   addPackages = self: with self;
@@ -86,7 +90,11 @@ let
       callPackage = self.newScope { inherit qtCompatVersion qtModule srcs; };
     in {
 
-      inherit mkDerivation;
+      mkDerivationWith =
+        import ../mkDerivation.nix
+        { inherit (stdenv) lib; inherit debug; inherit (self) wrapQtAppsHook; };
+
+      mkDerivation = mkDerivationWith stdenvActual.mkDerivation;
 
       qtbase = callPackage ../modules/qtbase.nix {
         inherit (srcs.qtbase) src version;
@@ -147,6 +155,12 @@ let
           fix_qt_builtin_paths = ../hooks/fix-qt-builtin-paths.sh;
         };
       } ../hooks/qmake-hook.sh;
+
+      wrapQtAppsHook = makeSetupHook {
+        deps =
+          [ self.qtbase.dev makeWrapper ]
+          ++ optional stdenv.isLinux self.qtwayland.dev;
+      } ../hooks/wrap-qt-apps-hook.sh;
     };
 
    self = makeScope newScope addPackages;
diff --git a/pkgs/development/libraries/qt-5/5.6/default.nix b/pkgs/development/libraries/qt-5/5.6/default.nix
index bf0ae42ea1f2..4f739b57ffec 100644
--- a/pkgs/development/libraries/qt-5/5.6/default.nix
+++ b/pkgs/development/libraries/qt-5/5.6/default.nix
@@ -26,7 +26,7 @@ existing packages here and modify it as necessary.
 
 {
   newScope,
-  stdenv, fetchurl, fetchpatch, makeSetupHook,
+  stdenv, fetchurl, fetchpatch, makeSetupHook, makeWrapper,
   bison, cups ? null, harfbuzz, libGL, perl,
   gstreamer, gst-plugins-base,
 
@@ -104,14 +104,18 @@ let
     ];
   };
 
-  mkDerivation =
-    import ../mkDerivation.nix
-    { inherit stdenv; inherit (stdenv) lib; }
-    { inherit debug; };
-
   qtModule =
     import ../qtModule.nix
-    { inherit mkDerivation perl; inherit (stdenv) lib; }
+    {
+      inherit perl;
+      inherit (stdenv) lib;
+      # Use a variant of mkDerivation that does not include wrapQtApplications
+      # to avoid cyclic dependencies between Qt modules.
+      mkDerivation =
+        import ../mkDerivation.nix
+        { inherit (stdenv) lib; inherit debug; wrapQtAppsHook = null; }
+        stdenv.mkDerivation;
+    }
     { inherit self srcs patches; };
 
   addPackages = self: with self;
@@ -119,7 +123,11 @@ let
       callPackage = self.newScope { inherit qtCompatVersion qtModule srcs; };
     in {
 
-      inherit mkDerivation;
+      mkDerivationWith =
+        import ../mkDerivation.nix
+        { inherit (stdenv) lib; inherit debug; inherit (self) wrapQtAppsHook; };
+
+      mkDerivation = mkDerivationWith stdenv.mkDerivation;
 
       qtbase = callPackage ../modules/qtbase.nix {
         inherit bison cups harfbuzz libGL;
@@ -173,6 +181,12 @@ let
         deps = [ self.qtbase.dev ];
         substitutions = { inherit (stdenv) isDarwin; };
       } ../hooks/qmake-hook.sh;
+
+      wrapQtAppsHook = makeSetupHook {
+        deps =
+          [ self.qtbase.dev makeWrapper ]
+          ++ optional stdenv.isLinux self.qtwayland.dev;
+      } ../hooks/wrap-qt-apps-hook.sh;
     };
 
    self = makeScope newScope addPackages;
diff --git a/pkgs/development/libraries/qt-5/5.9/default.nix b/pkgs/development/libraries/qt-5/5.9/default.nix
index e59b6b90105b..f36f86e26ffe 100644
--- a/pkgs/development/libraries/qt-5/5.9/default.nix
+++ b/pkgs/development/libraries/qt-5/5.9/default.nix
@@ -17,7 +17,7 @@ top-level attribute to `top-level/all-packages.nix`.
 
 {
   newScope,
-  stdenv, fetchurl, fetchpatch, makeSetupHook,
+  stdenv, fetchurl, fetchpatch, makeSetupHook, makeWrapper,
   bison, cups ? null, harfbuzz, libGL, perl,
   gstreamer, gst-plugins-base, gtk3, dconf,
 
@@ -67,14 +67,18 @@ let
 
   };
 
-  mkDerivation =
-    import ../mkDerivation.nix
-    { inherit stdenv; inherit (stdenv) lib; }
-    { inherit debug; };
-
   qtModule =
     import ../qtModule.nix
-    { inherit mkDerivation perl; inherit (stdenv) lib; }
+    {
+      inherit perl;
+      inherit (stdenv) lib;
+      # Use a variant of mkDerivation that does not include wrapQtApplications
+      # to avoid cyclic dependencies between Qt modules.
+      mkDerivation =
+        import ../mkDerivation.nix
+        { inherit (stdenv) lib; inherit debug; wrapQtAppsHook = null; }
+        stdenv.mkDerivation;
+    }
     { inherit self srcs patches; };
 
   addPackages = self: with self;
@@ -82,7 +86,11 @@ let
       callPackage = self.newScope { inherit qtCompatVersion qtModule srcs; };
     in {
 
-      inherit mkDerivation;
+      mkDerivationWith =
+        import ../mkDerivation.nix
+        { inherit (stdenv) lib; inherit debug; inherit (self) wrapQtAppsHook; };
+
+      mkDerivation = mkDerivationWith stdenv.mkDerivation;
 
       qtbase = callPackage ../modules/qtbase.nix {
         inherit (srcs.qtbase) src version;
@@ -140,6 +148,12 @@ let
           fix_qt_builtin_paths = ../hooks/fix-qt-builtin-paths.sh;
         };
       } ../hooks/qmake-hook.sh;
+
+      wrapQtAppsHook = makeSetupHook {
+        deps =
+          [ self.qtbase.dev makeWrapper ]
+          ++ optional stdenv.isLinux self.qtwayland.dev;
+      } ../hooks/wrap-qt-apps-hook.sh;
     };
 
    self = makeScope newScope addPackages;
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 3a558153988c..436c2e1d032a 100644
--- a/pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh
+++ b/pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh
@@ -19,12 +19,14 @@ export QMAKEPATH
 QMAKEMODULES=
 export QMAKEMODULES
 
-addToQMAKEPATH() {
-    if [ -d "$1/mkspecs" ]; then
+qmakePathHook() {
+    if [ -d "$1/mkspecs" ]
+    then
         QMAKEMODULES="${QMAKEMODULES}${QMAKEMODULES:+:}/mkspecs"
         QMAKEPATH="${QMAKEPATH}${QMAKEPATH:+:}$1"
     fi
 }
+envBuildHostHooks+=(qmakePathHook)
 
 # Propagate any runtime dependency of the building package.
 # Each dependency is propagated to the user environment and as a build
@@ -32,18 +34,18 @@ addToQMAKEPATH() {
 # package depending on the building package. (This is necessary in case
 # the building package does not provide runtime dependencies itself and so
 # would not be propagated to the user environment.)
-qtEnvHook() {
-    addToQMAKEPATH "$1"
-    if providesQtRuntime "$1"; then
-        if [ "z${!outputBin}" != "z${!outputDev}" ]; then
-            propagatedBuildInputs+=" $1"
-        fi
-        propagatedUserEnvPkgs+=" $1"
+qtEnvHostTargetHook() {
+    if providesQtRuntime "$1" && [ "z${!outputBin}" != "z${!outputDev}" ]
+    then
+        propagatedBuildInputs+=" $1"
     fi
 }
-envHostTargetHooks+=(qtEnvHook)
+envHostTargetHooks+=(qtEnvHostTargetHook)
 
 postPatchMkspecs() {
+    # Prevent this hook from running multiple times
+    dontPatchMkspecs=1
+
     local bin="${!outputBin}"
     local dev="${!outputDev}"
     local doc="${!outputDoc}"
diff --git a/pkgs/development/libraries/qt-5/hooks/wrap-qt-apps-hook.sh b/pkgs/development/libraries/qt-5/hooks/wrap-qt-apps-hook.sh
new file mode 100644
index 000000000000..83f62e4ec2b8
--- /dev/null
+++ b/pkgs/development/libraries/qt-5/hooks/wrap-qt-apps-hook.sh
@@ -0,0 +1,106 @@
+# Inherit arguments given in mkDerivation
+qtWrapperArgs=( $qtWrapperArgs )
+
+qtHostPathSeen=()
+
+qtUnseenHostPath() {
+    for pkg in "${qtHostPathSeen[@]}"
+    do
+        if [ "${pkg:?}" == "$1" ]
+        then
+            return 1
+        fi
+    done
+
+    qtHostPathSeen+=("$1")
+    return 0
+}
+
+qtHostPathHook() {
+    qtUnseenHostPath "$1" || return 0
+
+    local pluginDir="$1/${qtPluginPrefix:?}"
+    if [ -d "$pluginDir" ]
+    then
+        qtWrapperArgs+=(--prefix QT_PLUGIN_PATH : "$pluginDir")
+    fi
+
+    local qmlDir="$1/${qtQmlPrefix:?}"
+    if [ -d "$qmlDir" ]
+    then
+        qtWrapperArgs+=(--prefix QML2_IMPORT_PATH : "$qmlDir")
+    fi
+}
+addEnvHooks "$hostOffset" qtHostPathHook
+
+makeQtWrapper() {
+    local original="$1"
+    local wrapper="$2"
+    shift 2
+    makeWrapper "$original" "$wrapper" "${qtWrapperArgs[@]}" "$@"
+}
+
+wrapQtApp() {
+    local program="$1"
+    shift 1
+    wrapProgram "$program" "${qtWrapperArgs[@]}" "$@"
+}
+
+qtOwnPathsHook() {
+    local xdgDataDir="${!outputBin}/share"
+    if [ -d "$xdgDataDir" ]
+    then
+        qtWrapperArgs+=(--prefix XDG_DATA_DIRS : "$xdgDataDir")
+    fi
+
+    local xdgConfigDir="${!outputBin}/etc/xdg"
+    if [ -d "$xdgConfigDir" ]
+    then
+        qtWrapperArgs+=(--prefix XDG_CONFIG_DIRS : "$xdgConfigDir")
+    fi
+
+    qtHostPathHook "${!outputBin}"
+}
+
+preFixupPhases+=" qtOwnPathsHook"
+
+isQtApp () {
+    readelf -d "$1" 2>/dev/null | grep -q -F 'libQt5Core'
+}
+
+# Note: $qtWrapperArgs still gets defined even if $dontWrapQtApps is set.
+wrapQtAppsHook() {
+    # skip this hook when requested
+    [ -z "$dontWrapQtApps" ] || return 0
+
+    # guard against running multiple times (e.g. due to propagation)
+    [ -z "$wrapQtAppsHookHasRun" ] || return 0
+    wrapQtAppsHookHasRun=1
+
+    local targetDirs=( "$prefix/bin" )
+    echo "wrapping Qt applications in ${targetDirs[@]}"
+
+    for targetDir in "${targetDirs[@]}"
+    do
+        [ -d "$targetDir" ] || continue
+
+        find "$targetDir" -executable -print0 | while IFS= read -r -d '' file
+        do
+            isQtApp "$file" || continue
+
+            if [ -f "$file" ]
+            then
+                echo "wrapping $file"
+                wrapQtApp "$file"
+            elif [ -h "$file" ]
+            then
+                target="$(readlink -e "$file")"
+                echo "wrapping $file -> $target"
+                rm "$file"
+                makeQtWrapper "$target" "$file"
+            fi
+        done
+    done
+}
+
+fixupOutputHooks+=(wrapQtAppsHook)
diff --git a/pkgs/development/libraries/qt-5/mkDerivation.nix b/pkgs/development/libraries/qt-5/mkDerivation.nix
index d4e2143d564b..95357c096dfd 100644
--- a/pkgs/development/libraries/qt-5/mkDerivation.nix
+++ b/pkgs/development/libraries/qt-5/mkDerivation.nix
@@ -1,8 +1,8 @@
-{ stdenv, lib }:
+{ lib, debug, wrapQtAppsHook }:
 
 let inherit (lib) optional; in
 
-{ debug }:
+mkDerivation:
 
 args:
 
@@ -24,7 +24,9 @@ let
 
     enableParallelBuilding = args.enableParallelBuilding or true;
 
+    nativeBuildInputs = (args.nativeBuildInputs or []) ++ [ wrapQtAppsHook ];
+
   };
 in
 
-stdenv.mkDerivation (args // args_)
+mkDerivation (args // args_)
diff --git a/pkgs/development/libraries/qt-5/modules/qtspeech.nix b/pkgs/development/libraries/qt-5/modules/qtspeech.nix
index 7b4b19ccab5a..ddef01a9482e 100644
--- a/pkgs/development/libraries/qt-5/modules/qtspeech.nix
+++ b/pkgs/development/libraries/qt-5/modules/qtspeech.nix
@@ -3,5 +3,5 @@
 qtModule {
   name = "qtspeech";
   qtInputs = [ ];
-  outputs = [ "out" "dev" "bin" ];
+  outputs = [ "out" "dev" ];
 }
diff --git a/pkgs/development/r-modules/wrapper-rstudio.nix b/pkgs/development/r-modules/wrapper-rstudio.nix
index c89773c2dd55..5eeac8fed30e 100644
--- a/pkgs/development/r-modules/wrapper-rstudio.nix
+++ b/pkgs/development/r-modules/wrapper-rstudio.nix
@@ -1,4 +1,4 @@
-{ lib, runCommand, R, rstudio, makeWrapper, recommendedPackages, packages, qtbase }:
+{ lib, runCommand, R, rstudio, wrapQtAppsHook, recommendedPackages, packages, qtbase }:
 
 let
   qtVersion = with lib.versions; "${major qtbase.version}.${minor qtbase.version}";
@@ -7,7 +7,8 @@ runCommand (rstudio.name + "-wrapper") {
   preferLocalBuild = true;
   allowSubstitutes = false;
 
-  nativeBuildInputs = [makeWrapper];
+  nativeBuildInputs = [wrapQtAppsHook];
+  dontWrapQtApps = true;
 
   buildInputs = [R rstudio] ++ recommendedPackages ++ packages;
 
@@ -29,6 +30,6 @@ echo -n ".libPaths(c(.libPaths(), \"" >> $out/$fixLibsR
 echo -n $R_LIBS_SITE | sed -e 's/:/", "/g' >> $out/$fixLibsR
 echo -n "\"))" >> $out/$fixLibsR
 echo >> $out/$fixLibsR
-makeWrapper ${rstudio}/bin/rstudio $out/bin/rstudio --set R_PROFILE_USER $out/$fixLibsR \
-  --prefix QT_PLUGIN_PATH : ${qtbase}/lib/qt-${qtVersion}/plugins
+makeQtWrapper ${rstudio}/bin/rstudio $out/bin/rstudio \
+  --set R_PROFILE_USER $out/$fixLibsR
 ''
diff --git a/pkgs/development/tools/analysis/hopper/default.nix b/pkgs/development/tools/analysis/hopper/default.nix
index 7158ea38c04d..c9214ae7e35d 100644
--- a/pkgs/development/tools/analysis/hopper/default.nix
+++ b/pkgs/development/tools/analysis/hopper/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchurl, pkgs, makeWrapper, lib }:
+{ stdenv, fetchurl, pkgs, lib }:
 
 stdenv.mkDerivation rec {
   pname    = "hopper";
@@ -16,22 +16,20 @@ stdenv.mkDerivation rec {
 libbsd.out libffi.out gmpxx.out python27Full.out python27Packages.libxml2 qt5.qtbase zlib  xlibs.libX11.out xorg_sys_opengl.out xlibs.libXrender.out gcc-unwrapped.lib
   ];
 
-  nativeBuildInputs = [ makeWrapper ];
+  nativeBuildInputs = [ pkgs.qt5.wrapQtAppsHook ];
+
+  qtWrapperArgs = [ ''--suffix LD_LIBRARY_PATH : ${ldLibraryPath}'' ];
 
   installPhase = ''
-     mkdir -p $out/bin
-     mkdir -p $out/lib
-     mkdir -p $out/share
-     cp $sourceRoot/opt/hopper-${rev}/bin/Hopper $out/bin/hopper
-     cp -r $sourceRoot/opt/hopper-${rev}/lib $out
-     cp -r $sourceRoot/usr/share $out/share
+    mkdir -p $out/bin
+    mkdir -p $out/lib
+    mkdir -p $out/share
+    cp $sourceRoot/opt/hopper-${rev}/bin/Hopper $out/bin/hopper
+    cp -r $sourceRoot/opt/hopper-${rev}/lib $out
+    cp -r $sourceRoot/usr/share $out/share
     patchelf \
-    --set-interpreter ${stdenv.glibc}/lib/ld-linux-x86-64.so.2 \
-    $out/bin/hopper
-    # Details: https://nixos.wiki/wiki/Qt
-     wrapProgram $out/bin/hopper \
-    --suffix LD_LIBRARY_PATH : ${ldLibraryPath} \
-    --suffix QT_PLUGIN_PATH : ${pkgs.qt5.qtbase}/lib/qt-${pkgs.qt5.qtbase.qtCompatVersion}/plugins
+      --set-interpreter ${stdenv.glibc}/lib/ld-linux-x86-64.so.2 \
+      $out/bin/hopper
   '';
 
   meta = {
diff --git a/pkgs/development/tools/qtcreator/default.nix b/pkgs/development/tools/qtcreator/default.nix
index 03b758cbdc6d..1b3bc7a21626 100644
--- a/pkgs/development/tools/qtcreator/default.nix
+++ b/pkgs/development/tools/qtcreator/default.nix
@@ -10,7 +10,7 @@ let
   revision = "1";
 
   # Fetch clang from qt vendor, this contains submodules like this:
-  # clang<-clang-tools-extra<-clazy. 
+  # clang<-clang-tools-extra<-clazy.
   clang_qt_vendor = llvmPackages_8.clang-unwrapped.overrideAttrs (oldAttrs: rec {
     src = fetchgit {
       url = "https://code.qt.io/clang/clang.git";
@@ -32,15 +32,15 @@ stdenv.mkDerivation rec {
 
   buildInputs = [ qtbase qtscript qtquickcontrols qtdeclarative llvmPackages_8.libclang clang_qt_vendor llvmPackages_8.llvm ];
 
-  nativeBuildInputs = [ qmake makeWrapper ];
+  nativeBuildInputs = [ qmake ];
 
-  # 0001-Fix-clang-libcpp-regexp.patch is for fixing regexp that is used to 
+  # 0001-Fix-clang-libcpp-regexp.patch is for fixing regexp that is used to
   # find clang libc++ library include paths. By default it's not covering paths
   # like libc++-version, which is default name for libc++ folder in nixos.
-  patches = [ ./0001-Fix-clang-libcpp-regexp.patch 
+  patches = [ ./0001-Fix-clang-libcpp-regexp.patch
 
-    # Fix clazy plugin name. This plugin was renamed with clang8 
-    # release, and patch didn't make it into 4.9.1 release. Should be removed 
+    # Fix clazy plugin name. This plugin was renamed with clang8
+    # release, and patch didn't make it into 4.9.1 release. Should be removed
     # on qtcreator update, if this problem is fixed.
     (fetchpatch {
       url = "https://code.qt.io/cgit/qt-creator/qt-creator.git/patch/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp?id=53c407bc0c87e0b65b537bf26836ddd8e00ead82";
@@ -51,7 +51,7 @@ stdenv.mkDerivation rec {
       url = "https://code.qt.io/cgit/qt-creator/qt-creator.git/patch/src/plugins/clangtools/clangtidyclazyrunner.cpp?id=53c407bc0c87e0b65b537bf26836ddd8e00ead82";
       sha256 = "1rl0rc2l297lpfhhawvkkmj77zb081hhp0bbi7nnykf3q9ch0clh";
     })
-  ]; 
+  ];
 
   doCheck = true;
 
@@ -70,7 +70,7 @@ stdenv.mkDerivation rec {
       --replace '$$clean_path($${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include)' '${clang_qt_vendor}/lib/clang/8.0.0/include' \
       --replace '$$clean_path($${LLVM_BINDIR})' '${clang_qt_vendor}/bin'
 
-    # Fix include path to find clang and clang-c include directories.  
+    # Fix include path to find clang and clang-c include directories.
     substituteInPlace src/plugins/clangtools/clangtools.pro \
       --replace 'INCLUDEPATH += $$LLVM_INCLUDEPATH' 'INCLUDEPATH += $$LLVM_INCLUDEPATH ${clang_qt_vendor}'
 
diff --git a/pkgs/development/tools/tora/default.nix b/pkgs/development/tools/tora/default.nix
index 5b46b975cf7f..2bbe2cfe16df 100644
--- a/pkgs/development/tools/tora/default.nix
+++ b/pkgs/development/tools/tora/default.nix
@@ -53,10 +53,9 @@ in mkDerivation rec {
 
   NIX_CFLAGS_COMPILE = [ "-L${mysql.connector-c}/lib/mysql" "-I${mysql.connector-c}/include/mysql" ];
 
-  postFixup = ''
-    wrapProgram $out/bin/tora \
-      --prefix PATH : ${lib.getBin graphviz}/bin
-  '';
+  qtWrapperArgs = [
+    ''--prefix PATH : ${lib.getBin graphviz}/bin''
+  ];
 
   meta = with lib; {
     description = "Tora SQL tool";