summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/applications/kde/libkcddb.nix4
-rw-r--r--pkgs/applications/networking/browsers/lynx/default.nix6
-rw-r--r--pkgs/applications/office/skrooge/default.nix7
-rw-r--r--pkgs/applications/science/logic/coq/8.4.nix2
-rw-r--r--pkgs/applications/science/logic/coq/default.nix2
-rw-r--r--pkgs/applications/science/math/R/setup-hook.sh6
-rw-r--r--pkgs/applications/video/mplayer/default.nix3
-rw-r--r--pkgs/build-support/bintools-wrapper/default.nix2
-rw-r--r--pkgs/build-support/bintools-wrapper/setup-hook.sh45
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix3
-rw-r--r--pkgs/build-support/cc-wrapper/setup-hook.sh55
-rw-r--r--pkgs/build-support/emacs/setup-hook.sh6
-rw-r--r--pkgs/build-support/gcc-wrapper-old/setup-hook.sh4
-rw-r--r--pkgs/build-support/setup-hooks/find-xml-catalogs.sh2
-rw-r--r--pkgs/build-support/setup-hooks/set-java-classpath.sh2
-rw-r--r--pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh2
-rw-r--r--pkgs/build-support/setup-hooks/strip.sh37
-rw-r--r--pkgs/build-support/setup-hooks/wrap-gapps-hook.sh2
-rw-r--r--pkgs/data/icons/hicolor-icon-theme/setup-hook.sh3
-rw-r--r--pkgs/desktops/gnome-3/core/grilo/setup-hook.sh2
-rw-r--r--pkgs/desktops/gnustep/make/setup-hook.sh2
-rw-r--r--pkgs/development/compilers/chicken/setup-hook.sh2
-rw-r--r--pkgs/development/compilers/gcc/4.5/default.nix68
-rw-r--r--pkgs/development/compilers/gcc/4.8/default.nix54
-rw-r--r--pkgs/development/compilers/gcc/4.9/default.nix68
-rw-r--r--pkgs/development/compilers/gcc/5/default.nix72
-rw-r--r--pkgs/development/compilers/gcc/6/default.nix71
-rw-r--r--pkgs/development/compilers/gcc/7/default.nix71
-rw-r--r--pkgs/development/compilers/gcc/snapshot/default.nix71
-rw-r--r--pkgs/development/compilers/go/setup-hook.sh2
-rw-r--r--pkgs/development/compilers/haxe/setup-hook.sh2
-rw-r--r--pkgs/development/compilers/sbcl/default.nix2
-rw-r--r--pkgs/development/haskell-modules/generic-builder.nix4
-rw-r--r--pkgs/development/idris-modules/build-idris-package.nix3
-rw-r--r--pkgs/development/idris-modules/with-packages.nix2
-rw-r--r--pkgs/development/interpreters/elixir/setup-hook.sh2
-rw-r--r--pkgs/development/interpreters/erlang/setup-hook.sh2
-rw-r--r--pkgs/development/interpreters/guile/setup-hook-2.0.sh2
-rw-r--r--pkgs/development/interpreters/guile/setup-hook-2.2.sh2
-rw-r--r--pkgs/development/interpreters/guile/setup-hook.sh2
-rw-r--r--pkgs/development/interpreters/jruby/default.nix2
-rw-r--r--pkgs/development/interpreters/perl/setup-hook.sh2
-rw-r--r--pkgs/development/interpreters/python/setup-hook.sh2
-rw-r--r--pkgs/development/interpreters/ruby/default.nix2
-rw-r--r--pkgs/development/libraries/SDL/setup-hook.sh6
-rw-r--r--pkgs/development/libraries/SDL2/setup-hook.sh6
-rw-r--r--pkgs/development/libraries/gdk-pixbuf/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/glib/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/glibc/common.nix2
-rw-r--r--pkgs/development/libraries/gmp/6.x.nix4
-rw-r--r--pkgs/development/libraries/gobject-introspection/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/grantlee/5/setup-hook.sh6
-rw-r--r--pkgs/development/libraries/gstreamer/core/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/gstreamer/legacy/gstreamer/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/kde-frameworks/extra-cmake-modules/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/kde-frameworks/kdoctools/default.nix14
-rw-r--r--pkgs/development/libraries/kde-frameworks/kdoctools/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/libopcodes/default.nix3
-rw-r--r--pkgs/development/libraries/librep/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/ncurses/default.nix3
-rw-r--r--pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh6
-rw-r--r--pkgs/development/libraries/rep-gtk/setup-hook.sh2
-rw-r--r--pkgs/development/libraries/slib/setup-hook.sh2
-rw-r--r--pkgs/development/lisp-modules/clwrapper/setup-hook.sh2
-rw-r--r--pkgs/development/ocaml-modules/eliom/setup-hook.sh2
-rw-r--r--pkgs/development/ocaml-modules/ocamlmake/setup-hook.sh2
-rwxr-xr-xpkgs/development/tools/build-managers/cmake/setup-hook.sh6
-rw-r--r--pkgs/development/tools/misc/automake/setup-hook.sh2
-rw-r--r--pkgs/development/tools/misc/binutils/default.nix9
-rw-r--r--pkgs/development/tools/misc/pkgconfig/setup-hook.sh6
-rw-r--r--pkgs/development/tools/ocaml/findlib/default.nix2
-rw-r--r--pkgs/development/web/nodejs/setup-hook.sh2
-rw-r--r--pkgs/os-specific/darwin/apple-sdk/framework-setup-hook.sh2
-rw-r--r--pkgs/os-specific/darwin/apple-sdk/security-setup-hook.sh2
-rw-r--r--pkgs/os-specific/linux/busybox/default.nix2
-rw-r--r--pkgs/os-specific/linux/kernel-headers/4.4.nix3
-rw-r--r--pkgs/servers/x11/xorg/builder.sh7
-rw-r--r--pkgs/shells/bash/4.4.nix4
-rw-r--r--pkgs/stdenv/generic/make-derivation.nix76
-rw-r--r--pkgs/stdenv/generic/setup.sh338
-rw-r--r--pkgs/stdenv/linux/make-bootstrap-tools-cross.nix1
-rw-r--r--pkgs/tools/text/sgml/opensp/setup-hook.sh2
-rw-r--r--pkgs/tools/typesetting/tex/tetex/setup-hook.sh2
-rw-r--r--pkgs/tools/typesetting/tex/texlive/setup-hook.sh2
-rw-r--r--pkgs/top-level/splice.nix69
85 files changed, 675 insertions, 645 deletions
diff --git a/pkgs/applications/kde/libkcddb.nix b/pkgs/applications/kde/libkcddb.nix
index edd9732d051..3fd48605654 100644
--- a/pkgs/applications/kde/libkcddb.nix
+++ b/pkgs/applications/kde/libkcddb.nix
@@ -8,8 +8,8 @@ mkDerivation {
     license = with licenses; [ gpl2 lgpl21 bsd3 ];
     maintainers = with maintainers; [ peterhoeg ];
   };
-  nativeBuildInputs = [ extra-cmake-modules ];
-  buildInputs = [ qtbase kdoctools ];
+  nativeBuildInputs = [ extra-cmake-modules kdoctools ];
+  buildInputs = [ qtbase ];
   propagatedBuildInputs = [
     kcodecs ki18n kio kwidgetsaddons
     libmusicbrainz5
diff --git a/pkgs/applications/networking/browsers/lynx/default.nix b/pkgs/applications/networking/browsers/lynx/default.nix
index 0f6c4ed36d4..4e68d21be0c 100644
--- a/pkgs/applications/networking/browsers/lynx/default.nix
+++ b/pkgs/applications/networking/browsers/lynx/default.nix
@@ -22,9 +22,9 @@ stdenv.mkDerivation rec {
 
   configureFlags = [ "--enable-widec" ] ++ stdenv.lib.optional sslSupport "--with-ssl";
 
-  nativeBuildInputs = stdenv.lib.optional sslSupport pkgconfig
-    ++ stdenv.lib.optional (hostPlatform != buildPlatform) buildPackages.stdenv.cc
-    ++ [ nukeReferences ];
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ nukeReferences ]
+    ++ stdenv.lib.optional sslSupport pkgconfig;
 
   buildInputs = [ ncurses gzip ] ++ stdenv.lib.optional sslSupport openssl.dev;
 
diff --git a/pkgs/applications/office/skrooge/default.nix b/pkgs/applications/office/skrooge/default.nix
index f88cc147098..1aaf05a123e 100644
--- a/pkgs/applications/office/skrooge/default.nix
+++ b/pkgs/applications/office/skrooge/default.nix
@@ -14,9 +14,12 @@ mkDerivation rec {
     sha256 = "1dbvdrkdpgv39v8h7k3mri0nzlslfyd5kk410czj0jdn4qq400md";
   };
 
-  nativeBuildInputs = [ cmake extra-cmake-modules shared_mime_info ];
+  nativeBuildInputs = [
+    cmake extra-cmake-modules kdoctools shared_mime_info
+  ];
 
-  buildInputs = [ qtwebkit qtscript grantlee kxmlgui kwallet kparts kdoctools
+  buildInputs = [
+    qtwebkit qtscript grantlee kxmlgui kwallet kparts
     kjobwidgets kdesignerplugin kiconthemes knewstuff sqlcipher qca-qt5
     kactivities karchive kguiaddons knotifyconfig krunner kwindowsystem libofx
   ];
diff --git a/pkgs/applications/science/logic/coq/8.4.nix b/pkgs/applications/science/logic/coq/8.4.nix
index 1f7ef571eaf..64b0f85aed2 100644
--- a/pkgs/applications/science/logic/coq/8.4.nix
+++ b/pkgs/applications/science/logic/coq/8.4.nix
@@ -60,7 +60,7 @@ stdenv.mkDerivation {
       fi
     }
 
-    envHooks=(''${envHooks[@]} addCoqPath)
+    addEnvHooks "$targetOffset" addCoqPath
   '';
 
   passthru = {
diff --git a/pkgs/applications/science/logic/coq/default.nix b/pkgs/applications/science/logic/coq/default.nix
index 4c67904b2b1..9ed535cfe63 100644
--- a/pkgs/applications/science/logic/coq/default.nix
+++ b/pkgs/applications/science/logic/coq/default.nix
@@ -110,7 +110,7 @@ self = stdenv.mkDerivation {
       fi
     }
 
-    envHooks=(''${envHooks[@]} addCoqPath)
+    addEnvHooks "$targetOffset" addCoqPath
   '';
 
   preConfigure = ''
diff --git a/pkgs/applications/science/math/R/setup-hook.sh b/pkgs/applications/science/math/R/setup-hook.sh
index 09a775db9bf..6951e2a4b61 100644
--- a/pkgs/applications/science/math/R/setup-hook.sh
+++ b/pkgs/applications/science/math/R/setup-hook.sh
@@ -1,5 +1,7 @@
 addRLibPath () {
-    addToSearchPath R_LIBS_SITE $1/library
+    if [[ -d "$1/library" ]]; then
+        addToSearchPath R_LIBS_SITE "$1/library"
+    fi
 }
 
-envHooks+=(addRLibPath)
+addEnvHooks "$targetOffset" addRLibPath
diff --git a/pkgs/applications/video/mplayer/default.nix b/pkgs/applications/video/mplayer/default.nix
index 24c5b4335c4..fe6090c3230 100644
--- a/pkgs/applications/video/mplayer/default.nix
+++ b/pkgs/applications/video/mplayer/default.nix
@@ -102,7 +102,8 @@ stdenv.mkDerivation rec {
     rm -rf ffmpeg
   '';
 
-  nativeBuildInputs = [ buildPackages.stdenv.cc pkgconfig yasm ];
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ pkgconfig yasm ];
   buildInputs = with stdenv.lib;
     [ freetype ffmpeg ]
     ++ optional aalibSupport aalib
diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix
index 57859b2f371..bb0e6b82aa5 100644
--- a/pkgs/build-support/bintools-wrapper/default.nix
+++ b/pkgs/build-support/bintools-wrapper/default.nix
@@ -178,7 +178,7 @@ stdenv.mkDerivation {
       else throw "unknown emulation for platform: " + targetPlatform.config;
     in targetPlatform.platform.bfdEmulation or (fmt + "-" + arch);
 
-  propagatedBuildInputs = extraPackages;
+  depsTargetTargetPropagated = extraPackages;
 
   setupHook = ./setup-hook.sh;
 
diff --git a/pkgs/build-support/bintools-wrapper/setup-hook.sh b/pkgs/build-support/bintools-wrapper/setup-hook.sh
index 43f79ec5920..48a00b0b9b0 100644
--- a/pkgs/build-support/bintools-wrapper/setup-hook.sh
+++ b/pkgs/build-support/bintools-wrapper/setup-hook.sh
@@ -2,12 +2,20 @@
 #
 # See comments in cc-wrapper's setup hook. This works exactly the same way.
 
+set -u
+
+# Skip setup hook if we're neither a build-time dep, nor, temporarily, doing a
+# native compile.
+#
+# TODO(@Ericson2314): No native exception
+[[ -z ${crossConfig-} ]] || (( "$hostOffset" < 0 )) || return 0
+
 bintoolsWrapper_addLDVars () {
-    case $depOffset in
+    case $depHostOffset in
         -1) local role='BUILD_' ;;
         0)  local role='' ;;
         1)  local role='TARGET_' ;;
-        *)  echo "bintools-wrapper: Error: Cannot be used with $depOffset-offset deps, " >2;
+        *)  echo "bintools-wrapper: Error: Cannot be used with $depHostOffset-offset deps" >2;
             return 1 ;;
     esac
 
@@ -20,17 +28,29 @@ bintoolsWrapper_addLDVars () {
     fi
 }
 
-if [ -n "${crossConfig:-}" ]; then
-    export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_BUILD=1
-    role_pre='BUILD_'
-    role_post='_FOR_BUILD'
-else
-    export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_HOST=1
-    role_pre=""
-    role_post=''
-fi
+case $targetOffset in
+    -1)
+        export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_BUILD=1
+        role_pre='BUILD_'
+        role_post='_FOR_BUILD'
+        ;;
+    0)
+        export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_HOST=1
+        role_pre=''
+        role_post=''
+        ;;
+    1)
+        export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_TARGET=1
+        role_pre='TARGET_'
+        role_post='_FOR_TARGET'
+        ;;
+    *)
+        echo "cc-wrapper: used as improper sort of dependency" >2;
+        return 1
+        ;;
+esac
 
-envHooks+=(bintoolsWrapper_addLDVars)
+addEnvHooks "$targetOffset" bintoolsWrapper_addLDVars
 
 # shellcheck disable=SC2157
 if [ -n "@bintools_bin@" ]; then
@@ -65,3 +85,4 @@ done
 
 # No local scope in sourced file
 unset -v role_pre role_post cmd upper_case
+set +u
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index 218e9f6b957..5d878d219f1 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -201,7 +201,8 @@ stdenv.mkDerivation {
       ln -s $ccPath/${targetPrefix}ghdl $out/bin/${targetPrefix}ghdl
     '';
 
-  propagatedBuildInputs = [ bintools ] ++ extraPackages;
+  propagatedBuildInputs = [ bintools ];
+  depsTargetTargetPropagated = extraPackages;
 
   setupHook = ./setup-hook.sh;
 
diff --git a/pkgs/build-support/cc-wrapper/setup-hook.sh b/pkgs/build-support/cc-wrapper/setup-hook.sh
index a922193ad2e..29a7306b9b7 100644
--- a/pkgs/build-support/cc-wrapper/setup-hook.sh
+++ b/pkgs/build-support/cc-wrapper/setup-hook.sh
@@ -54,19 +54,26 @@
 # For more details, read the individual files where the mechanisms used to
 # accomplish this will be individually documented.
 
+set -u
+
+# Skip setup hook if we're neither a build-time dep, nor, temporarily, doing a
+# native compile.
+#
+# TODO(@Ericson2314): No native exception
+[[ -z ${crossConfig-} ]] || (( "$hostOffset" < 0 )) || return 0
 
 # It's fine that any other cc-wrapper will redefine this. Bash functions close
 # over no state, and there's no @-substitutions within, so any redefined
 # function is guaranteed to be exactly the same.
 ccWrapper_addCVars () {
-    # The `depOffset` describes how the platforms of the dependencies are slid
-    # relative to the depending package. It is brought into scope of the
-    # environment hook defined as the role of the dependency being applied.
-    case $depOffset in
+    # The `depHostOffset` describes how the host platform of the dependencies
+    # are slid relative to the depending package. It is brought into scope of
+    # the environment hook defined as the role of the dependency being applied.
+    case $depHostOffset in
         -1) local role='BUILD_' ;;
         0)  local role='' ;;
         1)  local role='TARGET_' ;;
-        *)  echo "cc-wrapper: Error: Cannot be used with $depOffset-offset deps, " >2;
+        *)  echo "cc-wrapper: Error: Cannot be used with $depHostOffset-offset deps" >2;
             return 1 ;;
     esac
 
@@ -87,20 +94,31 @@ ccWrapper_addCVars () {
 #
 # We also need to worry about what role is being added on *this* invocation of
 # setup-hook, which `role` tracks.
-if [ -n "${crossConfig:-}" ]; then
-    export NIX_CC_WRAPPER_@infixSalt@_TARGET_BUILD=1
-    role_pre='BUILD_'
-    role_post='_FOR_BUILD'
-else
-    export NIX_CC_WRAPPER_@infixSalt@_TARGET_HOST=1
-    role_pre=''
-    role_post=''
-fi
+case $targetOffset in
+    -1)
+        export NIX_CC_WRAPPER_@infixSalt@_TARGET_BUILD=1
+        role_pre='BUILD_'
+        role_post='_FOR_BUILD'
+        ;;
+    0)
+        export NIX_CC_WRAPPER_@infixSalt@_TARGET_HOST=1
+        role_pre=''
+        role_post=''
+        ;;
+    1)
+        export NIX_CC_WRAPPER_@infixSalt@_TARGET_TARGET=1
+        role_pre='TARGET_'
+        role_post='_FOR_TARGET'
+        ;;
+    *)
+        echo "cc-wrapper: used as improper sort of dependency" >2;
+        return 1
+        ;;
+esac
 
-# Eventually the exact sort of env-hook we create will depend on the role. This
-# is because based on what relative platform we are targeting, we use different
-# dependencies.
-envHooks+=(ccWrapper_addCVars)
+# We use the `targetOffset` to choose the right env hook to accumulate the right
+# sort of deps (those with that offset).
+addEnvHooks "$targetOffset" ccWrapper_addCVars
 
 # Note 1: these come *after* $out in the PATH (see setup.sh).
 # Note 2: phase separation makes this look useless to shellcheck.
@@ -131,3 +149,4 @@ export CXX${role_post}=@named_cxx@
 
 # No local scope in sourced file
 unset -v role_pre role_post
+set +u
diff --git a/pkgs/build-support/emacs/setup-hook.sh b/pkgs/build-support/emacs/setup-hook.sh
index defef45b55f..e1db3e828fd 100644
--- a/pkgs/build-support/emacs/setup-hook.sh
+++ b/pkgs/build-support/emacs/setup-hook.sh
@@ -4,4 +4,8 @@ addEmacsVars () {
   fi
 }
 
-envHooks+=(addEmacsVars)
+# If this is for a wrapper derivation, emacs and the dependencies are all
+# run-time dependencies. If this is for precompiling packages into bytecode,
+# emacs is a compile-time dependency of the package.
+addEnvHooks "$targetOffset" addEmacsVars
+addEnvHooks "$targetOffset" addEmacsVars
diff --git a/pkgs/build-support/gcc-wrapper-old/setup-hook.sh b/pkgs/build-support/gcc-wrapper-old/setup-hook.sh
index d8bdf858ae5..ad3ffeffbbb 100644
--- a/pkgs/build-support/gcc-wrapper-old/setup-hook.sh
+++ b/pkgs/build-support/gcc-wrapper-old/setup-hook.sh
@@ -1,4 +1,4 @@
-addCVars () {
+gccWrapperOld_addCVars () {
     if test -d $1/include; then
         export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -isystem $1/include"
     fi
@@ -12,7 +12,7 @@ addCVars () {
     fi
 }
 
-envHooks=(${envHooks[@]} addCVars)
+envBuildBuildHooks+=(gccWrapperOld_addCVars)
 
 # Note: these come *after* $out in the PATH (see setup.sh).
 
diff --git a/pkgs/build-support/setup-hooks/find-xml-catalogs.sh b/pkgs/build-support/setup-hooks/find-xml-catalogs.sh
index b742d5a8ffd..85364a61f61 100644
--- a/pkgs/build-support/setup-hooks/find-xml-catalogs.sh
+++ b/pkgs/build-support/setup-hooks/find-xml-catalogs.sh
@@ -18,5 +18,5 @@ if [ -z "$libxmlHookDone" ]; then
     # xmllint and xsltproc from looking in /etc/xml/catalog.
     export XML_CATALOG_FILES
     if [ -z "$XML_CATALOG_FILES" ]; then XML_CATALOG_FILES=" "; fi
-    envHooks+=(addXMLCatalogs)
+    addEnvHooks "$hostOffset" addXMLCatalogs
 fi
diff --git a/pkgs/build-support/setup-hooks/set-java-classpath.sh b/pkgs/build-support/setup-hooks/set-java-classpath.sh
index 047da91bc97..5d3548dc2e8 100644
--- a/pkgs/build-support/setup-hooks/set-java-classpath.sh
+++ b/pkgs/build-support/setup-hooks/set-java-classpath.sh
@@ -10,4 +10,4 @@ addPkgToClassPath () {
     done
 }
 
-envHooks+=(addPkgToClassPath)
+addEnvHooks "$targetOffset" addPkgToClassPath
diff --git a/pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh b/pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh
index 2fd2a2d6da6..96bf48cf123 100644
--- a/pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh
+++ b/pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh
@@ -2,4 +2,4 @@ setupDebugInfoDirs () {
     addToSearchPath NIX_DEBUG_INFO_DIRS $1/lib/debug
 }
 
-envHooks+=(setupDebugInfoDirs)
+addEnvHooks "$targetOffset" setupDebugInfoDirs
diff --git a/pkgs/build-support/setup-hooks/strip.sh b/pkgs/build-support/setup-hooks/strip.sh
index a33968ca18d..fc4c7bfbaf9 100644
--- a/pkgs/build-support/setup-hooks/strip.sh
+++ b/pkgs/build-support/setup-hooks/strip.sh
@@ -3,24 +3,45 @@
 fixupOutputHooks+=(_doStrip)
 
 _doStrip() {
-    if [ -z "$dontStrip" ]; then
+    # We don't bother to strip build platform code because it shouldn't make it
+    # to $out anyways---if it does, that's a bigger problem that a lack of
+    # stripping will help catch.
+    local -ra flags=(dontStripHost dontStripTarget)
+    local -ra stripCmds=(STRIP TARGET_STRIP)
+
+    # Optimization
+    if [[ "$STRIP" == "$TARGET_STRIP" ]]; then
+        dontStripTarget+=1
+    fi
+
+    local i
+    for i in ${!stripCmds[@]}; do
+        local -n flag="${flags[$i]}"
+        local -n stripCmd="${stripCmds[$i]}"
+
+        # `dontStrip` disables them all
+        if [[ "$dontStrip" || "$flag" ]] || ! type -f "$stripCmd" 2>/dev/null
+        then continue; fi
+
         stripDebugList=${stripDebugList:-lib lib32 lib64 libexec bin sbin}
         if [ -n "$stripDebugList" ]; then
-            stripDirs "$stripDebugList" "${stripDebugFlags:--S}"
+            stripDirs "$stripCmd" "$stripDebugList" "${stripDebugFlags:--S}"
         fi
 
         stripAllList=${stripAllList:-}
         if [ -n "$stripAllList" ]; then
-            stripDirs "$stripAllList" "${stripAllFlags:--s}"
+            stripDirs "$stripCmd" "$stripAllList" "${stripAllFlags:--s}"
         fi
-    fi
+    done
 }
 
 stripDirs() {
-    local dirs="$1"
-    local stripFlags="$2"
+    local cmd="$1"
+    local dirs="$2"
+    local stripFlags="$3"
     local dirsNew=
 
+    local d
     for d in ${dirs}; do
         if [ -d "$prefix/$d" ]; then
             dirsNew="${dirsNew} $prefix/$d "
@@ -29,8 +50,8 @@ stripDirs() {
     dirs=${dirsNew}
 
     if [ -n "${dirs}" ]; then
-        header "stripping (with flags $stripFlags) in$dirs"
-        find $dirs -type f -print0 | xargs -0 ${xargsFlags:--r} $STRIP $commonStripFlags $stripFlags 2>/dev/null || true
+        header "stripping (with command $cmd and flags $stripFlags) in$dirs"
+        find $dirs -type f -print0 | xargs -0 ${xargsFlags:--r} $cmd $commonStripFlags $stripFlags 2>/dev/null || true
         stopNest
     fi
 }
diff --git a/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh b/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh
index 79b8d5b73fa..25ac12996cc 100644
--- a/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh
+++ b/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh
@@ -6,7 +6,7 @@ find_gio_modules() {
     fi
 }
 
-envHooks+=(find_gio_modules)
+addEnvHooks "$targetOffset" find_gio_modules
 
 # Note: $gappsWrapperArgs still gets defined even if $dontWrapGApps is set.
 wrapGAppsHook() {
diff --git a/pkgs/data/icons/hicolor-icon-theme/setup-hook.sh b/pkgs/data/icons/hicolor-icon-theme/setup-hook.sh
index 05ab9b3d65d..29306cb316a 100644
--- a/pkgs/data/icons/hicolor-icon-theme/setup-hook.sh
+++ b/pkgs/data/icons/hicolor-icon-theme/setup-hook.sh
@@ -8,7 +8,8 @@ hicolorIconThemeHook() {
 	
 }
 
-envHooks+=(hicolorIconThemeHook)
+# I think this is meant to be a runtime dep
+addEnvHooks "$hostOffset" hicolorIconThemeHook
 
 # Remove icon cache
 hicolorPreFixupPhase() {
diff --git a/pkgs/desktops/gnome-3/core/grilo/setup-hook.sh b/pkgs/desktops/gnome-3/core/grilo/setup-hook.sh
index 3291e38addb..9337c520a20 100644
--- a/pkgs/desktops/gnome-3/core/grilo/setup-hook.sh
+++ b/pkgs/desktops/gnome-3/core/grilo/setup-hook.sh
@@ -4,4 +4,4 @@ make_grilo_find_plugins() {
     fi
 }
 
-envHooks+=(make_grilo_find_plugins)
+addEnvHooks "$hostOffset" make_grilo_find_plugins
diff --git a/pkgs/desktops/gnustep/make/setup-hook.sh b/pkgs/desktops/gnustep/make/setup-hook.sh
index 71618ef960f..53138901116 100644
--- a/pkgs/desktops/gnustep/make/setup-hook.sh
+++ b/pkgs/desktops/gnustep/make/setup-hook.sh
@@ -74,4 +74,4 @@ addEnvVars() {
 	addToSearchPath NIX_GNUSTEP_SYSTEM_DOC_INFO "$tmp"
     fi
 }
-envHooks=(${envHooks[@]} addEnvVars)
+addEnvHooks "$targetOffset" addEnvVars
diff --git a/pkgs/development/compilers/chicken/setup-hook.sh b/pkgs/development/compilers/chicken/setup-hook.sh
index d7f28539dc6..b0d9b53b537 100644
--- a/pkgs/development/compilers/chicken/setup-hook.sh
+++ b/pkgs/development/compilers/chicken/setup-hook.sh
@@ -4,4 +4,4 @@ addChickenRepositoryPath() {
     export CHICKEN_INCLUDE_PATH="$1/share;$CHICKEN_INCLUDE_PATH"
 }
 
-envHooks=(${envHooks[@]} addChickenRepositoryPath)
+addEnvHooks "$targetOffset" addChickenRepositoryPath
diff --git a/pkgs/development/compilers/gcc/4.5/default.nix b/pkgs/development/compilers/gcc/4.5/default.nix
index 36fde924e9b..a312276b33e 100644
--- a/pkgs/development/compilers/gcc/4.5/default.nix
+++ b/pkgs/development/compilers/gcc/4.5/default.nix
@@ -229,11 +229,22 @@ stdenv.mkDerivation ({
   inherit noSysDirs profiledCompiler staticCompiler langJava
     libcCross crossMingw;
 
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [ texinfo which gettext ]
     ++ optional (perl != null) perl;
 
-  buildInputs = [ gmp mpfr libmpc libelf ]
-    ++ (optional (ppl != null) ppl)
+  # For building runtime libs
+  depsBuildTarget =
+    if hostPlatform == buildPlatform then [
+      targetPackages.stdenv.cc.bintools # newly-built gcc will be used
+    ] else assert targetPlatform == hostPlatform; [ # build != host == target
+      stdenv.cc
+    ];
+
+  buildInputs = [
+    gmp mpfr libmpc libelf
+    targetPackages.stdenv.cc.bintools # For linking code at run-time
+  ] ++ (optional (ppl != null) ppl)
     ++ (optional (cloogppl != null) cloogppl)
     ++ (optional (zlib != null) zlib)
     ++ (optional langJava boehmgc)
@@ -245,11 +256,7 @@ stdenv.mkDerivation ({
     ;
 
   # TODO(@Ericson2314): Always pass "--target" and always prefix.
-  configurePlatforms =
-    # TODO(@Ericson2314): Figure out what's going wrong with Arm
-    if hostPlatform == targetPlatform && targetPlatform.isArm
-    then []
-    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+  configurePlatforms = [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
 
   configureFlags =
     # Basic dependencies
@@ -314,56 +321,9 @@ stdenv.mkDerivation ({
 
   /* For cross-built gcc (build != host == target) */
   crossAttrs = {
-    AR_FOR_BUILD = "ar";
-    AS_FOR_BUILD = "as";
-    LD_FOR_BUILD = "ld";
-    NM_FOR_BUILD = "nm";
-    OBJCOPY_FOR_BUILD = "objcopy";
-    OBJDUMP_FOR_BUILD = "objdump";
-    RANLIB_FOR_BUILD = "ranlib";
-    SIZE_FOR_BUILD = "size";
-    STRINGS_FOR_BUILD = "strings";
-    STRIP_FOR_BUILD = "strip";
-    CC_FOR_BUILD = "gcc";
-    CXX_FOR_BUILD = "g++";
-
-    AR = "${targetPlatform.config}-ar";
-    AS = "${targetPlatform.config}-as";
-    LD = "${targetPlatform.config}-ld";
-    NM = "${targetPlatform.config}-nm";
-    OBJCOPY = "${targetPlatform.config}-objcopy";
-    OBJDUMP = "${targetPlatform.config}-objdump";
-    RANLIB = "${targetPlatform.config}-ranlib";
-    SIZE = "${targetPlatform.config}-size";
-    STRINGS = "${targetPlatform.config}-strings";
-    STRIP = "${targetPlatform.config}-strip";
-    CC = "${targetPlatform.config}-gcc";
-    CXX = "${targetPlatform.config}-g++";
-
-    AR_FOR_TARGET = "${targetPlatform.config}-ar";
-    AS_FOR_TARGET = "${targetPlatform.config}-as";
-    LD_FOR_TARGET = "${targetPlatform.config}-ld";
-    NM_FOR_TARGET = "${targetPlatform.config}-nm";
-    OBJCOPY_FOR_TARGET = "${targetPlatform.config}-objcopy";
-    OBJDUMP_FOR_TARGET = "${targetPlatform.config}-objdump";
-    RANLIB_FOR_TARGET = "${targetPlatform.config}-ranlib";
-    SIZE_FOR_TARGET = "${targetPlatform.config}-size";
-    STRINGS_FOR_TARGET = "${targetPlatform.config}-strings";
-    STRIP_FOR_TARGET = "${targetPlatform.config}-strip";
-    CC_FOR_TARGET = "${targetPlatform.config}-gcc";
-    CXX_FOR_TARGET = "${targetPlatform.config}-g++";
-
     dontStrip = true;
   };
 
-  NIX_BUILD_BINTOOLS = buildPackages.stdenv.cc.bintools;
-  NIX_BUILD_CC = buildPackages.stdenv.cc;
-
-  # Needed for the cross compilation to work
-  AR = "ar";
-  LD = "ld";
-  CC = "gcc";
-
   # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
   # library headers and binaries, regarless of the language being compiled.
   #
diff --git a/pkgs/development/compilers/gcc/4.8/default.nix b/pkgs/development/compilers/gcc/4.8/default.nix
index e626abc50d1..91daeadba70 100644
--- a/pkgs/development/compilers/gcc/4.8/default.nix
+++ b/pkgs/development/compilers/gcc/4.8/default.nix
@@ -267,6 +267,7 @@ stdenv.mkDerivation ({
   inherit noSysDirs staticCompiler langJava
     libcCross crossMingw;
 
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [ texinfo which gettext ]
     ++ (optional (perl != null) perl)
     ++ (optional javaAwtGtk pkgconfig);
@@ -297,11 +298,7 @@ stdenv.mkDerivation ({
   dontDisableStatic = true;
 
   # TODO(@Ericson2314): Always pass "--target" and always prefix.
-  configurePlatforms =
-    # TODO(@Ericson2314): Figure out what's going wrong with Arm
-    if hostPlatform == targetPlatform && targetPlatform.isArm
-    then []
-    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+  configurePlatforms = [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
 
   configureFlags =
     # Basic dependencies
@@ -397,57 +394,12 @@ stdenv.mkDerivation ({
 
   /* For cross-built gcc (build != host == target) */
   crossAttrs =  {
-    AR_FOR_BUILD = "ar";
-    AS_FOR_BUILD = "as";
-    LD_FOR_BUILD = "ld";
-    NM_FOR_BUILD = "nm";
-    OBJCOPY_FOR_BUILD = "objcopy";
-    OBJDUMP_FOR_BUILD = "objdump";
-    RANLIB_FOR_BUILD = "ranlib";
-    SIZE_FOR_BUILD = "size";
-    STRINGS_FOR_BUILD = "strings";
-    STRIP_FOR_BUILD = "strip";
-    CC_FOR_BUILD = "gcc";
-    CXX_FOR_BUILD = "g++";
-
-    AR = "${targetPlatform.config}-ar";
-    AS = "${targetPlatform.config}-as";
-    LD = "${targetPlatform.config}-ld";
-    NM = "${targetPlatform.config}-nm";
-    OBJCOPY = "${targetPlatform.config}-objcopy";
-    OBJDUMP = "${targetPlatform.config}-objdump";
-    RANLIB = "${targetPlatform.config}-ranlib";
-    SIZE = "${targetPlatform.config}-size";
-    STRINGS = "${targetPlatform.config}-strings";
-    STRIP = "${targetPlatform.config}-strip";
-    CC = "${targetPlatform.config}-gcc";
-    CXX = "${targetPlatform.config}-g++";
-
-    AR_FOR_TARGET = "${targetPlatform.config}-ar";
-    AS_FOR_TARGET = "${targetPlatform.config}-as";
-    LD_FOR_TARGET = "${targetPlatform.config}-ld";
-    NM_FOR_TARGET = "${targetPlatform.config}-nm";
-    OBJCOPY_FOR_TARGET = "${targetPlatform.config}-objcopy";
-    OBJDUMP_FOR_TARGET = "${targetPlatform.config}-objdump";
-    RANLIB_FOR_TARGET = "${targetPlatform.config}-ranlib";
-    SIZE_FOR_TARGET = "${targetPlatform.config}-size";
-    STRINGS_FOR_TARGET = "${targetPlatform.config}-strings";
-    STRIP_FOR_TARGET = "${targetPlatform.config}-strip";
-    CC_FOR_TARGET = "${targetPlatform.config}-gcc";
-    CXX_FOR_TARGET = "${targetPlatform.config}-g++";
-
     dontStrip = true;
     buildFlags = "";
   };
 
-  NIX_BUILD_BINTOOLS = buildPackages.stdenv.cc.bintools;
-  NIX_BUILD_CC = buildPackages.stdenv.cc;
-
-  # Needed for the cross compilation to work
-  AR = "ar";
-  LD = "ld";
   # http://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
-  CC = if stdenv.system == "x86_64-solaris" then "gcc -m64" else "gcc";
+  ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
   # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
   # library headers and binaries, regarless of the language being compiled.
diff --git a/pkgs/development/compilers/gcc/4.9/default.nix b/pkgs/development/compilers/gcc/4.9/default.nix
index 621c45cdff3..844e0a7bebf 100644
--- a/pkgs/development/compilers/gcc/4.9/default.nix
+++ b/pkgs/development/compilers/gcc/4.9/default.nix
@@ -262,12 +262,23 @@ stdenv.mkDerivation ({
   inherit noSysDirs staticCompiler langJava
     libcCross crossMingw;
 
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [ texinfo which gettext ]
     ++ (optional (perl != null) perl)
     ++ (optional javaAwtGtk pkgconfig);
 
-  buildInputs = [ gmp mpfr libmpc libelf ]
-    ++ (optional (cloog != null) cloog)
+  # For building runtime libs
+  depsBuildTarget =
+    if hostPlatform == buildPlatform then [
+      targetPackages.stdenv.cc.bintools # newly-built gcc will be used
+    ] else assert targetPlatform == hostPlatform; [ # build != host == target
+      stdenv.cc
+    ];
+
+  buildInputs = [
+    gmp mpfr libmpc libelf
+    targetPackages.stdenv.cc.bintools # For linking code at run-time
+  ] ++ (optional (cloog != null) cloog)
     ++ (optional (isl != null) isl)
     ++ (optional (zlib != null) zlib)
     ++ (optionals langJava [ boehmgc zip unzip ])
@@ -296,11 +307,7 @@ stdenv.mkDerivation ({
   dontDisableStatic = true;
 
   # TODO(@Ericson2314): Always pass "--target" and always prefix.
-  configurePlatforms =
-    # TODO(@Ericson2314): Figure out what's going wrong with Arm
-    if hostPlatform == targetPlatform && targetPlatform.isArm
-    then []
-    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+  configurePlatforms = [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
 
   configureFlags =
     # Basic dependencies
@@ -395,57 +402,12 @@ stdenv.mkDerivation ({
 
   /* For cross-built gcc (build != host == target) */
   crossAttrs = {
-    AR_FOR_BUILD = "ar";
-    AS_FOR_BUILD = "as";
-    LD_FOR_BUILD = "ld";
-    NM_FOR_BUILD = "nm";
-    OBJCOPY_FOR_BUILD = "objcopy";
-    OBJDUMP_FOR_BUILD = "objdump";
-    RANLIB_FOR_BUILD = "ranlib";
-    SIZE_FOR_BUILD = "size";
-    STRINGS_FOR_BUILD = "strings";
-    STRIP_FOR_BUILD = "strip";
-    CC_FOR_BUILD = "gcc";
-    CXX_FOR_BUILD = "g++";
-
-    AR = "${targetPlatform.config}-ar";
-    AS = "${targetPlatform.config}-as";
-    LD = "${targetPlatform.config}-ld";
-    NM = "${targetPlatform.config}-nm";
-    OBJCOPY = "${targetPlatform.config}-objcopy";
-    OBJDUMP = "${targetPlatform.config}-objdump";
-    RANLIB = "${targetPlatform.config}-ranlib";
-    SIZE = "${targetPlatform.config}-size";
-    STRINGS = "${targetPlatform.config}-strings";
-    STRIP = "${targetPlatform.config}-strip";
-    CC = "${targetPlatform.config}-gcc";
-    CXX = "${targetPlatform.config}-g++";
-
-    AR_FOR_TARGET = "${targetPlatform.config}-ar";
-    AS_FOR_TARGET = "${targetPlatform.config}-as";
-    LD_FOR_TARGET = "${targetPlatform.config}-ld";
-    NM_FOR_TARGET = "${targetPlatform.config}-nm";
-    OBJCOPY_FOR_TARGET = "${targetPlatform.config}-objcopy";
-    OBJDUMP_FOR_TARGET = "${targetPlatform.config}-objdump";
-    RANLIB_FOR_TARGET = "${targetPlatform.config}-ranlib";
-    SIZE_FOR_TARGET = "${targetPlatform.config}-size";
-    STRINGS_FOR_TARGET = "${targetPlatform.config}-strings";
-    STRIP_FOR_TARGET = "${targetPlatform.config}-strip";
-    CC_FOR_TARGET = "${targetPlatform.config}-gcc";
-    CXX_FOR_TARGET = "${targetPlatform.config}-g++";
-
     dontStrip = true;
     buildFlags = "";
   };
 
-  NIX_BUILD_BINTOOLS = buildPackages.stdenv.cc.bintools;
-  NIX_BUILD_CC = buildPackages.stdenv.cc;
-
-  # Needed for the cross compilation to work
-  AR = "ar";
-  LD = "ld";
   # http://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
-  CC = if stdenv.system == "x86_64-solaris" then "gcc -m64" else "gcc";
+  ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
   # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
   # library headers and binaries, regarless of the language being compiled.
diff --git a/pkgs/development/compilers/gcc/5/default.nix b/pkgs/development/compilers/gcc/5/default.nix
index 709e87c3445..148409bee9b 100644
--- a/pkgs/development/compilers/gcc/5/default.nix
+++ b/pkgs/development/compilers/gcc/5/default.nix
@@ -49,9 +49,6 @@ assert libelf != null -> zlib != null;
 # Make sure we get GNU sed.
 assert hostPlatform.isDarwin -> gnused != null;
 
-# Need c++filt on darwin
-assert hostPlatform.isDarwin -> targetPackages.stdenv.cc.bintools or null != null;
-
 # The go frontend is written in c++
 assert langGo -> langCC;
 
@@ -277,17 +274,27 @@ stdenv.mkDerivation ({
   inherit noSysDirs staticCompiler langJava
     libcCross crossMingw;
 
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [ texinfo which gettext ]
     ++ (optional (perl != null) perl)
     ++ (optional javaAwtGtk pkgconfig);
 
-  buildInputs = [ gmp mpfr libmpc libelf ]
-    ++ (optional (isl != null) isl)
+  # For building runtime libs
+  depsBuildTarget =
+    if hostPlatform == buildPlatform then [
+      targetPackages.stdenv.cc.bintools # newly-built gcc will be used
+    ] else assert targetPlatform == hostPlatform; [ # build != host == target
+      stdenv.cc
+    ];
+
+  buildInputs = [
+    gmp mpfr libmpc libelf
+    targetPackages.stdenv.cc.bintools # For linking code at run-time
+  ] ++ (optional (isl != null) isl)
     ++ (optional (zlib != null) zlib)
     ++ (optionals langJava [ boehmgc zip unzip ])
     ++ (optionals javaAwtGtk ([ gtk2 libart_lgpl ] ++ xlibs))
     ++ (optionals (targetPlatform != hostPlatform) [targetPackages.stdenv.cc.bintools])
-    ++ (optionals (buildPlatform != hostPlatform) [buildPackages.stdenv.cc])
     ++ (optionals langAda [gnatboot])
     ++ (optionals langVhdl [gnat])
 
@@ -309,11 +316,7 @@ stdenv.mkDerivation ({
   dontDisableStatic = true;
 
   # TODO(@Ericson2314): Always pass "--target" and always prefix.
-  configurePlatforms =
-    # TODO(@Ericson2314): Figure out what's going wrong with Arm
-    if hostPlatform == targetPlatform && targetPlatform.isArm
-    then []
-    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+  configurePlatforms = [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
 
   configureFlags =
     # Basic dependencies
@@ -404,57 +407,12 @@ stdenv.mkDerivation ({
 
   /* For cross-built gcc (build != host == target) */
   crossAttrs = {
-    AR_FOR_BUILD = "ar";
-    AS_FOR_BUILD = "as";
-    LD_FOR_BUILD = "ld";
-    NM_FOR_BUILD = "nm";
-    OBJCOPY_FOR_BUILD = "objcopy";
-    OBJDUMP_FOR_BUILD = "objdump";
-    RANLIB_FOR_BUILD = "ranlib";
-    SIZE_FOR_BUILD = "size";
-    STRINGS_FOR_BUILD = "strings";
-    STRIP_FOR_BUILD = "strip";
-    CC_FOR_BUILD = "gcc";
-    CXX_FOR_BUILD = "g++";
-
-    AR = "${targetPlatform.config}-ar";
-    AS = "${targetPlatform.config}-as";
-    LD = "${targetPlatform.config}-ld";
-    NM = "${targetPlatform.config}-nm";
-    OBJCOPY = "${targetPlatform.config}-objcopy";
-    OBJDUMP = "${targetPlatform.config}-objdump";
-    RANLIB = "${targetPlatform.config}-ranlib";
-    SIZE = "${targetPlatform.config}-size";
-    STRINGS = "${targetPlatform.config}-strings";
-    STRIP = "${targetPlatform.config}-strip";
-    CC = "${targetPlatform.config}-gcc";
-    CXX = "${targetPlatform.config}-g++";
-
-    AR_FOR_TARGET = "${targetPlatform.config}-ar";
-    AS_FOR_TARGET = "${targetPlatform.config}-as";
-    LD_FOR_TARGET = "${targetPlatform.config}-ld";
-    NM_FOR_TARGET = "${targetPlatform.config}-nm";
-    OBJCOPY_FOR_TARGET = "${targetPlatform.config}-objcopy";
-    OBJDUMP_FOR_TARGET = "${targetPlatform.config}-objdump";
-    RANLIB_FOR_TARGET = "${targetPlatform.config}-ranlib";
-    SIZE_FOR_TARGET = "${targetPlatform.config}-size";
-    STRINGS_FOR_TARGET = "${targetPlatform.config}-strings";
-    STRIP_FOR_TARGET = "${targetPlatform.config}-strip";
-    CC_FOR_TARGET = "${targetPlatform.config}-gcc";
-    CXX_FOR_TARGET = "${targetPlatform.config}-g++";
-
     dontStrip = true;
     buildFlags = "";
   };
 
-  NIX_BUILD_BINTOOLS = buildPackages.stdenv.cc.bintools;
-  NIX_BUILD_CC = buildPackages.stdenv.cc;
-
-  # Needed for the cross compilation to work
-  AR = "ar";
-  LD = "ld";
   # http://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
-  CC = if stdenv.system == "x86_64-solaris" then "gcc -m64" else "gcc";
+  ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
   # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
   # library headers and binaries, regarless of the language being compiled.
diff --git a/pkgs/development/compilers/gcc/6/default.nix b/pkgs/development/compilers/gcc/6/default.nix
index 33a034adf66..c6114b7e639 100644
--- a/pkgs/development/compilers/gcc/6/default.nix
+++ b/pkgs/development/compilers/gcc/6/default.nix
@@ -49,9 +49,6 @@ assert libelf != null -> zlib != null;
 # Make sure we get GNU sed.
 assert hostPlatform.isDarwin -> gnused != null;
 
-# Need c++filt on darwin
-assert hostPlatform.isDarwin -> targetPackages.stdenv.cc.bintools or null != null;
-
 # The go frontend is written in c++
 assert langGo -> langCC;
 
@@ -276,12 +273,23 @@ stdenv.mkDerivation ({
   inherit noSysDirs staticCompiler langJava
     libcCross crossMingw;
 
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [ texinfo which gettext ]
     ++ (optional (perl != null) perl)
     ++ (optional javaAwtGtk pkgconfig);
 
-  buildInputs = [ gmp mpfr libmpc libelf ]
-    ++ (optional (isl != null) isl)
+  # For building runtime libs
+  depsBuildTarget =
+    if hostPlatform == buildPlatform then [
+      targetPackages.stdenv.cc.bintools # newly-built gcc will be used
+    ] else assert targetPlatform == hostPlatform; [ # build != host == target
+      stdenv.cc
+    ];
+
+  buildInputs = [
+    gmp mpfr libmpc libelf
+    targetPackages.stdenv.cc.bintools # For linking code at run-time
+  ] ++ (optional (isl != null) isl)
     ++ (optional (zlib != null) zlib)
     ++ (optionals langJava [ boehmgc zip unzip ])
     ++ (optionals javaAwtGtk ([ gtk2 libart_lgpl ] ++ xlibs))
@@ -311,11 +319,7 @@ stdenv.mkDerivation ({
   dontDisableStatic = true;
 
   # TODO(@Ericson2314): Always pass "--target" and always prefix.
-  configurePlatforms =
-    # TODO(@Ericson2314): Figure out what's going wrong with Arm
-    if hostPlatform == targetPlatform && targetPlatform.isArm
-    then []
-    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+  configurePlatforms = [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
 
   configureFlags =
     # Basic dependencies
@@ -405,57 +409,12 @@ stdenv.mkDerivation ({
 
   /* For cross-built gcc (build != host == target) */
   crossAttrs = {
-    AR_FOR_BUILD = "ar";
-    AS_FOR_BUILD = "as";
-    LD_FOR_BUILD = "ld";
-    NM_FOR_BUILD = "nm";
-    OBJCOPY_FOR_BUILD = "objcopy";
-    OBJDUMP_FOR_BUILD = "objdump";
-    RANLIB_FOR_BUILD = "ranlib";
-    SIZE_FOR_BUILD = "size";
-    STRINGS_FOR_BUILD = "strings";
-    STRIP_FOR_BUILD = "strip";
-    CC_FOR_BUILD = "gcc";
-    CXX_FOR_BUILD = "g++";
-
-    AR = "${targetPlatform.config}-ar";
-    AS = "${targetPlatform.config}-as";
-    LD = "${targetPlatform.config}-ld";
-    NM = "${targetPlatform.config}-nm";
-    OBJCOPY = "${targetPlatform.config}-objcopy";
-    OBJDUMP = "${targetPlatform.config}-objdump";
-    RANLIB = "${targetPlatform.config}-ranlib";
-    SIZE = "${targetPlatform.config}-size";
-    STRINGS = "${targetPlatform.config}-strings";
-    STRIP = "${targetPlatform.config}-strip";
-    CC = "${targetPlatform.config}-gcc";
-    CXX = "${targetPlatform.config}-g++";
-
-    AR_FOR_TARGET = "${targetPlatform.config}-ar";
-    AS_FOR_TARGET = "${targetPlatform.config}-as";
-    LD_FOR_TARGET = "${targetPlatform.config}-ld";
-    NM_FOR_TARGET = "${targetPlatform.config}-nm";
-    OBJCOPY_FOR_TARGET = "${targetPlatform.config}-objcopy";
-    OBJDUMP_FOR_TARGET = "${targetPlatform.config}-objdump";
-    RANLIB_FOR_TARGET = "${targetPlatform.config}-ranlib";
-    SIZE_FOR_TARGET = "${targetPlatform.config}-size";
-    STRINGS_FOR_TARGET = "${targetPlatform.config}-strings";
-    STRIP_FOR_TARGET = "${targetPlatform.config}-strip";
-    CC_FOR_TARGET = "${targetPlatform.config}-gcc";
-    CXX_FOR_TARGET = "${targetPlatform.config}-g++";
-
     dontStrip = true;
     buildFlags = "";
   };
 
-  NIX_BUILD_BINTOOLS = buildPackages.stdenv.cc.bintools;
-  NIX_BUILD_CC = buildPackages.stdenv.cc;
-
-  # Needed for the cross compilation to work
-  AR = "ar";
-  LD = "ld";
   # http://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
-  CC = if stdenv.system == "x86_64-solaris" then "gcc -m64" else "gcc";
+  ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
   # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
   # library headers and binaries, regarless of the language being compiled.
diff --git a/pkgs/development/compilers/gcc/7/default.nix b/pkgs/development/compilers/gcc/7/default.nix
index 291ec944b55..c20546b59e8 100644
--- a/pkgs/development/compilers/gcc/7/default.nix
+++ b/pkgs/development/compilers/gcc/7/default.nix
@@ -50,9 +50,6 @@ assert libelf != null -> zlib != null;
 # Make sure we get GNU sed.
 assert hostPlatform.isDarwin -> gnused != null;
 
-# Need c++filt on darwin
-assert hostPlatform.isDarwin -> targetPackages.stdenv.cc.bintools or null != null;
-
 # The go frontend is written in c++
 assert langGo -> langCC;
 
@@ -273,12 +270,23 @@ stdenv.mkDerivation ({
   inherit noSysDirs staticCompiler langJava
     libcCross crossMingw;
 
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [ texinfo which gettext ]
     ++ (optional (perl != null) perl)
     ++ (optional javaAwtGtk pkgconfig);
 
-  buildInputs = [ gmp mpfr libmpc libelf flex ]
-    ++ (optional (isl != null) isl)
+  # For building runtime libs
+  depsBuildTarget =
+    if hostPlatform == buildPlatform then [
+      targetPackages.stdenv.cc.bintools # newly-built gcc will be used
+    ] else assert targetPlatform == hostPlatform; [ # build != host == target
+      stdenv.cc
+    ];
+
+  buildInputs = [
+    gmp mpfr libmpc libelf flex
+    targetPackages.stdenv.cc.bintools # For linking code at run-time
+  ] ++ (optional (isl != null) isl)
     ++ (optional (zlib != null) zlib)
     ++ (optionals langJava [ boehmgc zip unzip ])
     ++ (optionals javaAwtGtk ([ gtk2 libart_lgpl ] ++ xlibs))
@@ -304,11 +312,7 @@ stdenv.mkDerivation ({
   dontDisableStatic = true;
 
   # TODO(@Ericson2314): Always pass "--target" and always prefix.
-  configurePlatforms =
-    # TODO(@Ericson2314): Figure out what's going wrong with Arm
-    if hostPlatform == targetPlatform && targetPlatform.isArm
-    then []
-    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+  configurePlatforms = [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
 
   configureFlags =
     # Basic dependencies
@@ -399,57 +403,12 @@ stdenv.mkDerivation ({
 
   /* For cross-built gcc (build != host == target) */
   crossAttrs = {
-    AR_FOR_BUILD = "ar";
-    AS_FOR_BUILD = "as";
-    LD_FOR_BUILD = "ld";
-    NM_FOR_BUILD = "nm";
-    OBJCOPY_FOR_BUILD = "objcopy";
-    OBJDUMP_FOR_BUILD = "objdump";
-    RANLIB_FOR_BUILD = "ranlib";
-    SIZE_FOR_BUILD = "size";
-    STRINGS_FOR_BUILD = "strings";
-    STRIP_FOR_BUILD = "strip";
-    CC_FOR_BUILD = "gcc";
-    CXX_FOR_BUILD = "g++";
-
-    AR = "${targetPlatform.config}-ar";
-    AS = "${targetPlatform.config}-as";
-    LD = "${targetPlatform.config}-ld";
-    NM = "${targetPlatform.config}-nm";
-    OBJCOPY = "${targetPlatform.config}-objcopy";
-    OBJDUMP = "${targetPlatform.config}-objdump";
-    RANLIB = "${targetPlatform.config}-ranlib";
-    SIZE = "${targetPlatform.config}-size";
-    STRINGS = "${targetPlatform.config}-strings";
-    STRIP = "${targetPlatform.config}-strip";
-    CC = "${targetPlatform.config}-gcc";
-    CXX = "${targetPlatform.config}-g++";
-
-    AR_FOR_TARGET = "${targetPlatform.config}-ar";
-    AS_FOR_TARGET = "${targetPlatform.config}-as";
-    LD_FOR_TARGET = "${targetPlatform.config}-ld";
-    NM_FOR_TARGET = "${targetPlatform.config}-nm";
-    OBJCOPY_FOR_TARGET = "${targetPlatform.config}-objcopy";
-    OBJDUMP_FOR_TARGET = "${targetPlatform.config}-objdump";
-    RANLIB_FOR_TARGET = "${targetPlatform.config}-ranlib";
-    SIZE_FOR_TARGET = "${targetPlatform.config}-size";
-    STRINGS_FOR_TARGET = "${targetPlatform.config}-strings";
-    STRIP_FOR_TARGET = "${targetPlatform.config}-strip";
-    CC_FOR_TARGET = "${targetPlatform.config}-gcc";
-    CXX_FOR_TARGET = "${targetPlatform.config}-g++";
-
     dontStrip = true;
     buildFlags = "";
   };
 
-  NIX_BUILD_BINTOOLS = buildPackages.stdenv.cc.bintools;
-  NIX_BUILD_CC = buildPackages.stdenv.cc;
-
-  # Needed for the cross compilation to work
-  AR = "ar";
-  LD = "ld";
   # http://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
-  CC = if stdenv.system == "x86_64-solaris" then "gcc -m64" else "gcc";
+  ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
   # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
   # library headers and binaries, regarless of the language being compiled.
diff --git a/pkgs/development/compilers/gcc/snapshot/default.nix b/pkgs/development/compilers/gcc/snapshot/default.nix
index e8668712e2e..c571487361b 100644
--- a/pkgs/development/compilers/gcc/snapshot/default.nix
+++ b/pkgs/development/compilers/gcc/snapshot/default.nix
@@ -50,9 +50,6 @@ assert libelf != null -> zlib != null;
 # Make sure we get GNU sed.
 assert hostPlatform.isDarwin -> gnused != null;
 
-# Need c++filt on darwin
-assert hostPlatform.isDarwin -> targetPackages.stdenv.cc.bintools or null != null;
-
 # The go frontend is written in c++
 assert langGo -> langCC;
 
@@ -260,12 +257,23 @@ stdenv.mkDerivation ({
   inherit noSysDirs staticCompiler langJava
     libcCross crossMingw;
 
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [ texinfo which gettext ]
     ++ (optional (perl != null) perl)
     ++ (optional javaAwtGtk pkgconfig);
 
-  buildInputs = [ gmp mpfr libmpc libelf flex ]
-    ++ (optional (isl != null) isl)
+  # For building runtime libs
+  depsBuildTarget =
+    if hostPlatform == buildPlatform then [
+      targetPackages.stdenv.cc.bintools # newly-built gcc will be used
+    ] else assert targetPlatform == hostPlatform; [ # build != host == target
+      stdenv.cc
+    ];
+
+  buildInputs = [
+    gmp mpfr libmpc libelf flex
+    targetPackages.stdenv.cc.bintools # For linking code at run-time
+  ] ++ (optional (isl != null) isl)
     ++ (optional (zlib != null) zlib)
     ++ (optionals langJava [ boehmgc zip unzip ])
     ++ (optionals javaAwtGtk ([ gtk2 libart_lgpl ] ++ xlibs))
@@ -291,11 +299,7 @@ stdenv.mkDerivation ({
   dontDisableStatic = true;
 
   # TODO(@Ericson2314): Always pass "--target" and always prefix.
-  configurePlatforms =
-    # TODO(@Ericson2314): Figure out what's going wrong with Arm
-    if hostPlatform == targetPlatform && targetPlatform.isArm
-    then []
-    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+  configurePlatforms = [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
 
   configureFlags =
     # Basic dependencies
@@ -386,57 +390,12 @@ stdenv.mkDerivation ({
 
   /* For cross-built gcc (build != host == target) */
   crossAttrs = {
-    AR_FOR_BUILD = "ar";
-    AS_FOR_BUILD = "as";
-    LD_FOR_BUILD = "ld";
-    NM_FOR_BUILD = "nm";
-    OBJCOPY_FOR_BUILD = "objcopy";
-    OBJDUMP_FOR_BUILD = "objdump";
-    RANLIB_FOR_BUILD = "ranlib";
-    SIZE_FOR_BUILD = "size";
-    STRINGS_FOR_BUILD = "strings";
-    STRIP_FOR_BUILD = "strip";
-    CC_FOR_BUILD = "gcc";
-    CXX_FOR_BUILD = "g++";
-
-    AR = "${targetPlatform.config}-ar";
-    AS = "${targetPlatform.config}-as";
-    LD = "${targetPlatform.config}-ld";
-    NM = "${targetPlatform.config}-nm";
-    OBJCOPY = "${targetPlatform.config}-objcopy";
-    OBJDUMP = "${targetPlatform.config}-objdump";
-    RANLIB = "${targetPlatform.config}-ranlib";
-    SIZE = "${targetPlatform.config}-size";
-    STRINGS = "${targetPlatform.config}-strings";
-    STRIP = "${targetPlatform.config}-strip";
-    CC = "${targetPlatform.config}-gcc";
-    CXX = "${targetPlatform.config}-g++";
-
-    AR_FOR_TARGET = "${targetPlatform.config}-ar";
-    AS_FOR_TARGET = "${targetPlatform.config}-as";
-    LD_FOR_TARGET = "${targetPlatform.config}-ld";
-    NM_FOR_TARGET = "${targetPlatform.config}-nm";
-    OBJCOPY_FOR_TARGET = "${targetPlatform.config}-objcopy";
-    OBJDUMP_FOR_TARGET = "${targetPlatform.config}-objdump";
-    RANLIB_FOR_TARGET = "${targetPlatform.config}-ranlib";
-    SIZE_FOR_TARGET = "${targetPlatform.config}-size";
-    STRINGS_FOR_TARGET = "${targetPlatform.config}-strings";
-    STRIP_FOR_TARGET = "${targetPlatform.config}-strip";
-    CC_FOR_TARGET = "${targetPlatform.config}-gcc";
-    CXX_FOR_TARGET = "${targetPlatform.config}-g++";
-
     dontStrip = true;
     buildFlags = "";
   };
 
-  NIX_BUILD_BINTOOLS = buildPackages.stdenv.cc.bintools;
-  NIX_BUILD_CC = buildPackages.stdenv.cc;
-
-  # Needed for the cross compilation to work
-  AR = "ar";
-  LD = "ld";
   # http://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
-  CC = if stdenv.system == "x86_64-solaris" then "gcc -m64" else "gcc";
+  ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
   # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
   # library headers and binaries, regarless of the language being compiled.
diff --git a/pkgs/development/compilers/go/setup-hook.sh b/pkgs/development/compilers/go/setup-hook.sh
index 1b91c8312b8..7dce15eeb10 100644
--- a/pkgs/development/compilers/go/setup-hook.sh
+++ b/pkgs/development/compilers/go/setup-hook.sh
@@ -2,4 +2,4 @@ addToGoPath() {
     addToSearchPath GOPATH $1/share/go
 }
 
-envHooks=(${envHooks[@]} addToGoPath)
+addEnvHooks "$targetOffset" addToGoPath
diff --git a/pkgs/development/compilers/haxe/setup-hook.sh b/pkgs/development/compilers/haxe/setup-hook.sh
index 21cc0206859..e6496107a5e 100644
--- a/pkgs/development/compilers/haxe/setup-hook.sh
+++ b/pkgs/development/compilers/haxe/setup-hook.sh
@@ -4,4 +4,4 @@ addHaxeLibPath() {
   fi
 }
 
-envHooks+=(addHaxeLibPath)
+addEnvHooks "$targetOffset" addHaxeLibPath
diff --git a/pkgs/development/compilers/sbcl/default.nix b/pkgs/development/compilers/sbcl/default.nix
index b800d71198a..cd3120ed831 100644
--- a/pkgs/development/compilers/sbcl/default.nix
+++ b/pkgs/development/compilers/sbcl/default.nix
@@ -91,7 +91,7 @@ stdenv.mkDerivation rec {
 
   # Specifying $SBCL_HOME is only truly needed with `purgeNixReferences = true`.
   setupHook = writeText "setupHook.sh" ''
-    envHooks+=(_setSbclHome)
+    addEnvHooks "$targetOffset" _setSbclHome
     _setSbclHome() {
       export SBCL_HOME='@out@/lib/sbcl/'
     }
diff --git a/pkgs/development/haskell-modules/generic-builder.nix b/pkgs/development/haskell-modules/generic-builder.nix
index c633310a37a..c0c8e46fbb0 100644
--- a/pkgs/development/haskell-modules/generic-builder.nix
+++ b/pkgs/development/haskell-modules/generic-builder.nix
@@ -222,8 +222,8 @@ stdenv.mkDerivation ({
     setupCompileFlags="${concatStringsSep " " setupCompileFlags}"
     configureFlags="${concatStringsSep " " defaultConfigureFlags} $configureFlags"
 
-    # nativePkgs defined in stdenv/setup.hs
-    for p in "''${nativePkgs[@]}"; do
+    # host.*Pkgs defined in stdenv/setup.hs
+    for p in "''${pkgsHostHost[@]}" "''${pkgsHostTarget[@]}"; do
       if [ -d "$p/lib/${ghc.name}/package.conf.d" ]; then
         cp -f "$p/lib/${ghc.name}/package.conf.d/"*.conf $packageConfDir/
         continue
diff --git a/pkgs/development/idris-modules/build-idris-package.nix b/pkgs/development/idris-modules/build-idris-package.nix
index 9dfa3430ed8..66eddd0e360 100644
--- a/pkgs/development/idris-modules/build-idris-package.nix
+++ b/pkgs/development/idris-modules/build-idris-package.nix
@@ -18,7 +18,8 @@
       fi
     }
 
-    envHooks+=(addIdrisLibs)
+    # All run-time deps
+    addEnvHooks 0 addIdrisLibs
   '';
 
   buildPhase = ''
diff --git a/pkgs/development/idris-modules/with-packages.nix b/pkgs/development/idris-modules/with-packages.nix
index d2b09808ec1..d4638670f69 100644
--- a/pkgs/development/idris-modules/with-packages.nix
+++ b/pkgs/development/idris-modules/with-packages.nix
@@ -14,7 +14,7 @@
       fi
     }
 
-    envHooks+=(installIdrisLib)
+    envHostTargetHooks+=(installIdrisLib)
   '';
 
   unpackPhase = ''
diff --git a/pkgs/development/interpreters/elixir/setup-hook.sh b/pkgs/development/interpreters/elixir/setup-hook.sh
index 2ed3b2e6454..501eca3cf02 100644
--- a/pkgs/development/interpreters/elixir/setup-hook.sh
+++ b/pkgs/development/interpreters/elixir/setup-hook.sh
@@ -2,4 +2,4 @@ addErlLibPath() {
     addToSearchPath ERL_LIBS $1/lib/elixir/lib
 }
 
-envHooks+=(addErlLibPath)
+addEnvHooks "$hostOffset" addErlLibPath
diff --git a/pkgs/development/interpreters/erlang/setup-hook.sh b/pkgs/development/interpreters/erlang/setup-hook.sh
index 68c0f762dfc..3962d154ba9 100644
--- a/pkgs/development/interpreters/erlang/setup-hook.sh
+++ b/pkgs/development/interpreters/erlang/setup-hook.sh
@@ -2,4 +2,4 @@ addErlangLibPath() {
     addToSearchPath ERL_LIBS $1/lib/erlang/lib
 }
 
-envHooks+=(addErlangLibPath)
+addEnvHooks "$hostOffset" addErlangLibPath
diff --git a/pkgs/development/interpreters/guile/setup-hook-2.0.sh b/pkgs/development/interpreters/guile/setup-hook-2.0.sh
index fd1dc944ed4..c7fb4f70fc6 100644
--- a/pkgs/development/interpreters/guile/setup-hook-2.0.sh
+++ b/pkgs/development/interpreters/guile/setup-hook-2.0.sh
@@ -10,4 +10,4 @@ addGuileLibPath () {
     fi
 }
 
-envHooks+=(addGuileLibPath)
+addEnvHooks "$hostOffset" addGuileLibPath
diff --git a/pkgs/development/interpreters/guile/setup-hook-2.2.sh b/pkgs/development/interpreters/guile/setup-hook-2.2.sh
index 86c1e0d3e4a..73e700bde02 100644
--- a/pkgs/development/interpreters/guile/setup-hook-2.2.sh
+++ b/pkgs/development/interpreters/guile/setup-hook-2.2.sh
@@ -10,4 +10,4 @@ addGuileLibPath () {
     fi
 }
 
-envHooks+=(addGuileLibPath)
+addEnvHooks "$hostOffset" addGuileLibPath
diff --git a/pkgs/development/interpreters/guile/setup-hook.sh b/pkgs/development/interpreters/guile/setup-hook.sh
index c1d19e579ed..bf04fee1e89 100644
--- a/pkgs/development/interpreters/guile/setup-hook.sh
+++ b/pkgs/development/interpreters/guile/setup-hook.sh
@@ -5,4 +5,4 @@ addGuileLibPath () {
     fi
 }
 
-envHooks+=(addGuileLibPath)
+addEnvHooks "$hostOffset" addGuileLibPath
diff --git a/pkgs/development/interpreters/jruby/default.nix b/pkgs/development/interpreters/jruby/default.nix
index ff192c07286..2224a13ba7c 100644
--- a/pkgs/development/interpreters/jruby/default.nix
+++ b/pkgs/development/interpreters/jruby/default.nix
@@ -36,7 +36,7 @@ jruby = stdenv.mkDerivation rec {
          addToSearchPath GEM_PATH \$1/${passthru.gemPath}
        }
 
-       envHooks+=(addGemPath)
+       addEnvHooks "$hostOffset" addGemPath
      EOF
   '';
 
diff --git a/pkgs/development/interpreters/perl/setup-hook.sh b/pkgs/development/interpreters/perl/setup-hook.sh
index a8656b8531d..7909412806c 100644
--- a/pkgs/development/interpreters/perl/setup-hook.sh
+++ b/pkgs/development/interpreters/perl/setup-hook.sh
@@ -2,4 +2,4 @@ addPerlLibPath () {
     addToSearchPath PERL5LIB $1/lib/perl5/site_perl
 }
 
-envHooks+=(addPerlLibPath)
+addEnvHooks "$hostOffset" addPerlLibPath
diff --git a/pkgs/development/interpreters/python/setup-hook.sh b/pkgs/development/interpreters/python/setup-hook.sh
index 35726280a75..77ec9e9ac0b 100644
--- a/pkgs/development/interpreters/python/setup-hook.sh
+++ b/pkgs/development/interpreters/python/setup-hook.sh
@@ -12,7 +12,7 @@ toPythonPath() {
     echo $result
 }
 
-envHooks+=(addPythonPath)
+addEnvHooks "$hostOffset" addPythonPath
 
 # Determinism: The interpreter is patched to write null timestamps when compiling python files.
 # This way python doesn't try to update them when we freeze timestamps in nix store.
diff --git a/pkgs/development/interpreters/ruby/default.nix b/pkgs/development/interpreters/ruby/default.nix
index d664c00bc31..478c2b45b26 100644
--- a/pkgs/development/interpreters/ruby/default.nix
+++ b/pkgs/development/interpreters/ruby/default.nix
@@ -142,7 +142,7 @@ let
             addToSearchPath GEM_PATH \$1/${passthru.gemPath}
           }
 
-          envHooks+=(addGemPath)
+          addEnvHooks "$hostOffset" addGemPath
           EOF
         '' + opString useRailsExpress ''
           rbConfig=$(find $out/lib/ruby -name rbconfig.rb)
diff --git a/pkgs/development/libraries/SDL/setup-hook.sh b/pkgs/development/libraries/SDL/setup-hook.sh
index 3696e743a07..20382f18f52 100644
--- a/pkgs/development/libraries/SDL/setup-hook.sh
+++ b/pkgs/development/libraries/SDL/setup-hook.sh
@@ -4,8 +4,4 @@ addSDLPath () {
   fi
 }
 
-if test -n "$crossConfig"; then
-  crossEnvHooks+=(addSDLPath)
-else
-  envHooks+=(addSDLPath)
-fi
+addEnvHooks "$hostOffset" addSDLPath
diff --git a/pkgs/development/libraries/SDL2/setup-hook.sh b/pkgs/development/libraries/SDL2/setup-hook.sh
index 5a26440f37b..3acce9d473c 100644
--- a/pkgs/development/libraries/SDL2/setup-hook.sh
+++ b/pkgs/development/libraries/SDL2/setup-hook.sh
@@ -4,8 +4,4 @@ addSDL2Path () {
   fi
 }
 
-if test -n "$crossConfig"; then
-  crossEnvHooks+=(addSDL2Path)
-else
-  envHooks+=(addSDL2Path)
-fi
+addEnvHooks "$hostOffset" addSDL2Path
diff --git a/pkgs/development/libraries/gdk-pixbuf/setup-hook.sh b/pkgs/development/libraries/gdk-pixbuf/setup-hook.sh
index ba7ab82f50b..5a7dcd79299 100644
--- a/pkgs/development/libraries/gdk-pixbuf/setup-hook.sh
+++ b/pkgs/development/libraries/gdk-pixbuf/setup-hook.sh
@@ -14,4 +14,4 @@ findGdkPixbufLoaders() {
 
 }
 
-envHooks+=(findGdkPixbufLoaders)
+addEnvHooks "$hostOffset" findGdkPixbufLoaders
diff --git a/pkgs/development/libraries/glib/setup-hook.sh b/pkgs/development/libraries/glib/setup-hook.sh
index c5cf293902c..98341376fdf 100644
--- a/pkgs/development/libraries/glib/setup-hook.sh
+++ b/pkgs/development/libraries/glib/setup-hook.sh
@@ -5,7 +5,7 @@ make_glib_find_gsettings_schemas() {
         addToSearchPath GSETTINGS_SCHEMAS_PATH "$1/share/gsettings-schemas/"*
     fi
 }
-envHooks+=(make_glib_find_gsettings_schemas)
+addEnvHooks "$hostOffset" make_glib_find_gsettings_schemas
 
 # Install gschemas, if any, in a package-specific directory
 glibPreInstallPhase() {
diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix
index 5af914d179b..cfec3209b98 100644
--- a/pkgs/development/libraries/glibc/common.nix
+++ b/pkgs/development/libraries/glibc/common.nix
@@ -141,7 +141,7 @@ stdenv.mkDerivation ({
 
   outputs = [ "out" "bin" "dev" "static" ];
 
-  nativeBuildInputs = lib.optional (cross != null) buildPackages.stdenv.cc;
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   buildInputs = lib.optionals withGd [ gd libpng ];
 
   # Needed to install share/zoneinfo/zone.tab.  Set to impure /bin/sh to
diff --git a/pkgs/development/libraries/gmp/6.x.nix b/pkgs/development/libraries/gmp/6.x.nix
index e3bacc86d58..dce052f8baa 100644
--- a/pkgs/development/libraries/gmp/6.x.nix
+++ b/pkgs/development/libraries/gmp/6.x.nix
@@ -19,8 +19,8 @@ let self = stdenv.mkDerivation rec {
   outputs = [ "out" "dev" "info" ];
   passthru.static = self.out;
 
-  nativeBuildInputs = [ m4 ]
-    ++ stdenv.lib.optional (buildPlatform != hostPlatform) buildPackages.stdenv.cc;
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ m4 ];
 
   configureFlags =
     # Build a "fat binary", with routines for several sub-architectures
diff --git a/pkgs/development/libraries/gobject-introspection/setup-hook.sh b/pkgs/development/libraries/gobject-introspection/setup-hook.sh
index 583d8475ec3..6d3488a6622 100644
--- a/pkgs/development/libraries/gobject-introspection/setup-hook.sh
+++ b/pkgs/development/libraries/gobject-introspection/setup-hook.sh
@@ -11,7 +11,7 @@ make_gobject_introspection_find_gir_files() {
     fi
 }
 
-envHooks+=(make_gobject_introspection_find_gir_files)
+addEnvHooks "$hostOffset" make_gobject_introspection_find_gir_files
 
 _multioutMoveGlibGir() {
   moveToOutput share/gir-1.0 "${!outputDev}"
diff --git a/pkgs/development/libraries/grantlee/5/setup-hook.sh b/pkgs/development/libraries/grantlee/5/setup-hook.sh
index aaa64868dc9..b51cb4a3190 100644
--- a/pkgs/development/libraries/grantlee/5/setup-hook.sh
+++ b/pkgs/development/libraries/grantlee/5/setup-hook.sh
@@ -10,8 +10,4 @@ _grantleeEnvHook() {
         propagatedUserEnvPkgs+=" $1"
     fi
 }
-if [ "$crossEnv" ]; then
-    crossEnvHooks+=(_grantleeEnvHook)
-else
-    envHooks+=(_grantleeEnvHook)
-fi
+addEnvHooks "$hostOffset" _grantleeEnvHook
diff --git a/pkgs/development/libraries/gstreamer/core/setup-hook.sh b/pkgs/development/libraries/gstreamer/core/setup-hook.sh
index 3dd7812ece6..b8c741af578 100644
--- a/pkgs/development/libraries/gstreamer/core/setup-hook.sh
+++ b/pkgs/development/libraries/gstreamer/core/setup-hook.sh
@@ -5,5 +5,5 @@ addGstreamer1LibPath () {
     fi
 }
 
-envHooks+=(addGstreamer1LibPath)
+addEnvHooks "$hostOffset" addGstreamer1LibPath
 
diff --git a/pkgs/development/libraries/gstreamer/legacy/gstreamer/setup-hook.sh b/pkgs/development/libraries/gstreamer/legacy/gstreamer/setup-hook.sh
index e89aeda5bc1..65ce2611251 100644
--- a/pkgs/development/libraries/gstreamer/legacy/gstreamer/setup-hook.sh
+++ b/pkgs/development/libraries/gstreamer/legacy/gstreamer/setup-hook.sh
@@ -5,4 +5,4 @@ addGstreamerLibPath () {
     fi
 }
 
-envHooks+=(addGstreamerLibPath)
+addEnvHooks "$hostOffset" addGstreamerLibPath
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 c1b1e21852c..88091e78a0c 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
@@ -2,7 +2,7 @@ _ecmEnvHook() {
     addToSearchPath XDG_DATA_DIRS "$1/share"
     addToSearchPath XDG_CONFIG_DIRS "$1/etc/xdg"
 }
-envHooks+=(_ecmEnvHook)
+addEnvHooks "$targetOffset" _ecmEnvHook
 
 _ecmPreConfigureHook() {
     # Because we need to use absolute paths here, we must set *all* the paths.
diff --git a/pkgs/development/libraries/kde-frameworks/kdoctools/default.nix b/pkgs/development/libraries/kde-frameworks/kdoctools/default.nix
index 661e89e3078..0a600fe8d05 100644
--- a/pkgs/development/libraries/kde-frameworks/kdoctools/default.nix
+++ b/pkgs/development/libraries/kde-frameworks/kdoctools/default.nix
@@ -8,10 +8,18 @@
 mkDerivation {
   name = "kdoctools";
   meta = { maintainers = [ lib.maintainers.ttuegel ]; };
-  nativeBuildInputs = [ extra-cmake-modules ];
-  propagatedNativeBuildInputs = [ perl perlPackages.URI ];
+  nativeBuildInputs = [
+    extra-cmake-modules
+    # The build system insists on having native Perl.
+    perl perlPackages.URI
+  ];
+  propagatedBuildInputs = [
+    # kdoctools at runtime actually needs Perl for the platform kdoctools is
+    # running on, not necessarily native perl.
+    perl perlPackages.URI
+    qtbase
+  ];
   buildInputs = [ karchive ki18n ];
-  propagatedBuildInputs = [ qtbase ];
   outputs = [ "out" "dev" ];
   patches = [ ./kdoctools-no-find-docbook-xml.patch ];
   cmakeFlags = [
diff --git a/pkgs/development/libraries/kde-frameworks/kdoctools/setup-hook.sh b/pkgs/development/libraries/kde-frameworks/kdoctools/setup-hook.sh
index 5cfffbd622d..2928d9b34db 100644
--- a/pkgs/development/libraries/kde-frameworks/kdoctools/setup-hook.sh
+++ b/pkgs/development/libraries/kde-frameworks/kdoctools/setup-hook.sh
@@ -2,4 +2,4 @@ addXdgData() {
     addToSearchPath XDG_DATA_DIRS "$1/share"
 }
 
-envHooks+=(addXdgData)
+addEnvHooks "$targetOffset" addXdgData
diff --git a/pkgs/development/libraries/libopcodes/default.nix b/pkgs/development/libraries/libopcodes/default.nix
index 7ffc40f1494..d6d6989761b 100644
--- a/pkgs/development/libraries/libopcodes/default.nix
+++ b/pkgs/development/libraries/libopcodes/default.nix
@@ -19,7 +19,8 @@ stdenv.mkDerivation rec {
     find . ../include/opcode -type f -exec sed {} -i -e 's/"bfd.h"/<bfd.h>/' \;
   '';
 
-  nativeBuildInputs = [ autoreconfHook264 bison buildPackages.stdenv.cc ];
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ autoreconfHook264 bison ];
   buildInputs = [ libiberty ];
   # dis-asm.h includes bfd.h
   propagatedBuildInputs = [ libbfd ];
diff --git a/pkgs/development/libraries/librep/setup-hook.sh b/pkgs/development/libraries/librep/setup-hook.sh
index 420d63d6c51..4d875b69330 100644
--- a/pkgs/development/libraries/librep/setup-hook.sh
+++ b/pkgs/development/libraries/librep/setup-hook.sh
@@ -2,4 +2,4 @@ addRepDLLoadPath () {
     addToSearchPath REP_DL_LOAD_PATH $1/lib/rep
 }
 
-envHooks+=(addRepDLLoadPath)
+addEnvHooks "$hostOffset" addRepDLLoadPath
diff --git a/pkgs/development/libraries/ncurses/default.nix b/pkgs/development/libraries/ncurses/default.nix
index 9aade8b9672..79414f016d3 100644
--- a/pkgs/development/libraries/ncurses/default.nix
+++ b/pkgs/development/libraries/ncurses/default.nix
@@ -37,10 +37,11 @@ stdenv.mkDerivation rec {
   # Only the C compiler, and explicitly not C++ compiler needs this flag on solaris:
   CFLAGS = lib.optionalString stdenv.isSunOS "-D_XOPEN_SOURCE_EXTENDED";
 
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [
     pkgconfig
   ] ++ lib.optionals (buildPlatform != hostPlatform) [
-    buildPackages.ncurses buildPackages.stdenv.cc
+    buildPackages.ncurses
   ];
   buildInputs = lib.optional (mouseSupport && stdenv.isLinux) gpm;
 
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 8ec7eeda8ae..754a75cbef4 100644
--- a/pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh
+++ b/pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh
@@ -42,11 +42,7 @@ qtEnvHook() {
         propagatedUserEnvPkgs+=" $1"
     fi
 }
-if [ "$crossConfig" ]; then
-   crossEnvHooks+=(qtEnvHook)
-else
-   envHooks+=(qtEnvHook)
-fi
+envHostTargetHooks+=(qtEnvHook)
 
 postPatchMkspecs() {
     local bin="${!outputBin}"
diff --git a/pkgs/development/libraries/rep-gtk/setup-hook.sh b/pkgs/development/libraries/rep-gtk/setup-hook.sh
index 420d63d6c51..4d875b69330 100644
--- a/pkgs/development/libraries/rep-gtk/setup-hook.sh
+++ b/pkgs/development/libraries/rep-gtk/setup-hook.sh
@@ -2,4 +2,4 @@ addRepDLLoadPath () {
     addToSearchPath REP_DL_LOAD_PATH $1/lib/rep
 }
 
-envHooks+=(addRepDLLoadPath)
+addEnvHooks "$hostOffset" addRepDLLoadPath
diff --git a/pkgs/development/libraries/slib/setup-hook.sh b/pkgs/development/libraries/slib/setup-hook.sh
index 62b72d6dc0a..3c7e91e8188 100644
--- a/pkgs/development/libraries/slib/setup-hook.sh
+++ b/pkgs/development/libraries/slib/setup-hook.sh
@@ -10,4 +10,4 @@ addSlibPath () {
     fi
 }
 
-envHooks+=(addSlibPath)
+addEnvHooks "$hostOffset" addSlibPath
diff --git a/pkgs/development/lisp-modules/clwrapper/setup-hook.sh b/pkgs/development/lisp-modules/clwrapper/setup-hook.sh
index 7ac8c70d59f..eb6052d58db 100644
--- a/pkgs/development/lisp-modules/clwrapper/setup-hook.sh
+++ b/pkgs/development/lisp-modules/clwrapper/setup-hook.sh
@@ -31,7 +31,7 @@ collectNixLispLDLP () {
 
 export NIX_LISP_COMMAND NIX_LISP CL_SOURCE_REGISTRY NIX_LISP_ASDF
 
-envHooks+=(addASDFPaths setLisp collectNixLispLDLP)
+addEnvHooks "$targetOffset" addASDFPaths setLisp collectNixLispLDLP
 
 mkdir -p "$HOME"/.cache/common-lisp || HOME="$TMP/.temp-$USER-home"
 mkdir -p "$HOME"/.cache/common-lisp
diff --git a/pkgs/development/ocaml-modules/eliom/setup-hook.sh b/pkgs/development/ocaml-modules/eliom/setup-hook.sh
index 096d8f8bf63..9868ab93f79 100644
--- a/pkgs/development/ocaml-modules/eliom/setup-hook.sh
+++ b/pkgs/development/ocaml-modules/eliom/setup-hook.sh
@@ -2,4 +2,4 @@ addOcsigenDistilleryTemplate() {
     addToSearchPathWithCustomDelimiter : ELIOM_DISTILLERY_PATH $1/eliom-distillery-templates
 }
 
-envHooks+=(addOcsigenDistilleryTemplate)
+addEnvHooks "$hostOffset" addOcsigenDistilleryTemplate
diff --git a/pkgs/development/ocaml-modules/ocamlmake/setup-hook.sh b/pkgs/development/ocaml-modules/ocamlmake/setup-hook.sh
index a93a7250beb..6d950437016 100644
--- a/pkgs/development/ocaml-modules/ocamlmake/setup-hook.sh
+++ b/pkgs/development/ocaml-modules/ocamlmake/setup-hook.sh
@@ -2,4 +2,4 @@ addOcamlMakefile () {
     export OCAMLMAKEFILE="@out@/include/OCamlMakefile"
 }
 
-envHooks+=(addOcamlMakefile)
+addEnvHooks "$targetOffset" addOcamlMakefile
diff --git a/pkgs/development/tools/build-managers/cmake/setup-hook.sh b/pkgs/development/tools/build-managers/cmake/setup-hook.sh
index 614e0031421..a92d54b3f14 100755
--- a/pkgs/development/tools/build-managers/cmake/setup-hook.sh
+++ b/pkgs/development/tools/build-managers/cmake/setup-hook.sh
@@ -72,11 +72,7 @@ if [ -z "$dontUseCmakeConfigure" -a -z "$configurePhase" ]; then
     configurePhase=cmakeConfigurePhase
 fi
 
-if [ -n "$crossConfig" ]; then
-    crossEnvHooks+=(addCMakeParams)
-else
-    envHooks+=(addCMakeParams)
-fi
+addEnvHooks "$targetOffset" addCMakeParams
 
 makeCmakeFindLibs(){
   isystem_seen=
diff --git a/pkgs/development/tools/misc/automake/setup-hook.sh b/pkgs/development/tools/misc/automake/setup-hook.sh
index 5cd8c6229f6..292632b7cbc 100644
--- a/pkgs/development/tools/misc/automake/setup-hook.sh
+++ b/pkgs/development/tools/misc/automake/setup-hook.sh
@@ -2,4 +2,4 @@ addAclocals () {
     addToSearchPathWithCustomDelimiter : ACLOCAL_PATH $1/share/aclocal
 }
 
-envHooks+=(addAclocals)
+addEnvHooks "$hostOffset" addAclocals
diff --git a/pkgs/development/tools/misc/binutils/default.nix b/pkgs/development/tools/misc/binutils/default.nix
index 1b016652699..31c86c785c2 100644
--- a/pkgs/development/tools/misc/binutils/default.nix
+++ b/pkgs/development/tools/misc/binutils/default.nix
@@ -65,7 +65,8 @@ stdenv.mkDerivation rec {
 
   outputs = [ "out" "info" "man" ];
 
-  nativeBuildInputs = [ bison buildPackages.stdenv.cc ];
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ bison ];
   buildInputs = [ zlib ];
 
   inherit noSysDirs;
@@ -90,11 +91,7 @@ stdenv.mkDerivation rec {
     else "-static-libgcc";
 
   # TODO(@Ericson2314): Always pass "--target" and always targetPrefix.
-  configurePlatforms =
-    # TODO(@Ericson2314): Figure out what's going wrong with Arm
-    if hostPlatform == targetPlatform && targetPlatform.isArm
-    then []
-    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+  configurePlatforms = [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
 
   configureFlags = [
     "--enable-targets=all" "--enable-64-bit-bfd"
diff --git a/pkgs/development/tools/misc/pkgconfig/setup-hook.sh b/pkgs/development/tools/misc/pkgconfig/setup-hook.sh
index 1c153976a34..34a9b9f1173 100644
--- a/pkgs/development/tools/misc/pkgconfig/setup-hook.sh
+++ b/pkgs/development/tools/misc/pkgconfig/setup-hook.sh
@@ -3,8 +3,4 @@ addPkgConfigPath () {
     addToSearchPath PKG_CONFIG_PATH $1/share/pkgconfig
 }
 
-if test -n "$crossConfig"; then
-    crossEnvHooks+=(addPkgConfigPath)
-else
-    envHooks+=(addPkgConfigPath)
-fi
+addEnvHooks "$targetOffset" addPkgConfigPath
diff --git a/pkgs/development/tools/ocaml/findlib/default.nix b/pkgs/development/tools/ocaml/findlib/default.nix
index 846546ae769..186b78ce3f3 100644
--- a/pkgs/development/tools/ocaml/findlib/default.nix
+++ b/pkgs/development/tools/ocaml/findlib/default.nix
@@ -40,7 +40,7 @@ stdenv.mkDerivation rec {
         fi
     }
 
-    envHooks+=(addOCamlPath)
+    addEnvHooks "$targetOffset" addOCamlPath
   '';
 
   meta = {
diff --git a/pkgs/development/web/nodejs/setup-hook.sh b/pkgs/development/web/nodejs/setup-hook.sh
index e1f4d9089f3..18368588c2a 100644
--- a/pkgs/development/web/nodejs/setup-hook.sh
+++ b/pkgs/development/web/nodejs/setup-hook.sh
@@ -2,4 +2,4 @@ addNodePath () {
     addToSearchPath NODE_PATH $1/lib/node_modules
 }
 
-envHooks+=(addNodePath)
+addEnvHooks "$hostOffset" addNodePath
diff --git a/pkgs/os-specific/darwin/apple-sdk/framework-setup-hook.sh b/pkgs/os-specific/darwin/apple-sdk/framework-setup-hook.sh
index 04d8e878f4f..b0d5915fc1f 100644
--- a/pkgs/os-specific/darwin/apple-sdk/framework-setup-hook.sh
+++ b/pkgs/os-specific/darwin/apple-sdk/framework-setup-hook.sh
@@ -39,4 +39,4 @@ useSystemCoreFoundationFramework () {
   export NIX_COREFOUNDATION_RPATH=/System/Library/Frameworks
 }
 
-envHooks+=(useSystemCoreFoundationFramework)
+addEnvHooks "$hostOffset" useSystemCoreFoundationFramework
diff --git a/pkgs/os-specific/darwin/apple-sdk/security-setup-hook.sh b/pkgs/os-specific/darwin/apple-sdk/security-setup-hook.sh
index f31adaa0d74..ed9bdbd912d 100644
--- a/pkgs/os-specific/darwin/apple-sdk/security-setup-hook.sh
+++ b/pkgs/os-specific/darwin/apple-sdk/security-setup-hook.sh
@@ -7,4 +7,4 @@ noDeprecatedDeclarations() {
   fi
 }
 
-envHooks+=(noDeprecatedDeclarations)
+addEnvHooks "$hostOffset" noDeprecatedDeclarations
diff --git a/pkgs/os-specific/linux/busybox/default.nix b/pkgs/os-specific/linux/busybox/default.nix
index bcb24d127cc..73c945fa0ba 100644
--- a/pkgs/os-specific/linux/busybox/default.nix
+++ b/pkgs/os-specific/linux/busybox/default.nix
@@ -95,7 +95,7 @@ stdenv.mkDerivation rec {
     makeFlagsArray+=("CC=${stdenv.cc.targetPrefix}gcc -isystem ${musl}/include -B${musl}/lib -L${musl}/lib")
   '';
 
-  nativeBuildInputs = lib.optional (hostPlatform != buildPlatform) buildPackages.stdenv.cc;
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
 
   buildInputs = lib.optionals (enableStatic && !useMusl) [ stdenv.cc.libc stdenv.cc.libc.static ];
 
diff --git a/pkgs/os-specific/linux/kernel-headers/4.4.nix b/pkgs/os-specific/linux/kernel-headers/4.4.nix
index 0ef5280d13b..e8e041f48eb 100644
--- a/pkgs/os-specific/linux/kernel-headers/4.4.nix
+++ b/pkgs/os-specific/linux/kernel-headers/4.4.nix
@@ -24,7 +24,8 @@ stdenvNoCC.mkDerivation {
 
   # It may look odd that we use `stdenvNoCC`, and yet explicit depend on a cc.
   # We do this so we have a build->build, not build->host, C compiler.
-  nativeBuildInputs = [ buildPackages.stdenv.cc perl ];
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ perl ];
 
   extraIncludeDirs = lib.optional hostPlatform.isPowerPC ["ppc"];
 
diff --git a/pkgs/servers/x11/xorg/builder.sh b/pkgs/servers/x11/xorg/builder.sh
index bb3e5ac4283..5a832cb14d5 100644
--- a/pkgs/servers/x11/xorg/builder.sh
+++ b/pkgs/servers/x11/xorg/builder.sh
@@ -16,13 +16,8 @@ postInstall() {
 
     echo "propagating requisites $requires"
 
-    if test -n "$crossConfig"; then
-        local pkgs=("${crossPkgs[@]}")
-    else
-        local pkgs=("${nativePkgs[@]}")
-    fi
     for r in $requires; do
-        for p in "${pkgs[@]}"; do
+        for p in "${pkgsHostHost[@]}" "${pkgsHostTarget[@]}"; do
             if test -e $p/lib/pkgconfig/$r.pc; then
                 echo "  found requisite $r in $p"
                 propagatedBuildInputs+=" $p"
diff --git a/pkgs/shells/bash/4.4.nix b/pkgs/shells/bash/4.4.nix
index b4a2ba55388..5635c6a73be 100644
--- a/pkgs/shells/bash/4.4.nix
+++ b/pkgs/shells/bash/4.4.nix
@@ -68,10 +68,10 @@ stdenv.mkDerivation rec {
   ];
 
   # Note: Bison is needed because the patches above modify parse.y.
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
   nativeBuildInputs = [bison]
     ++ optional (texinfo != null) texinfo
-    ++ optional hostPlatform.isDarwin binutils
-    ++ optional (hostPlatform != buildPlatform) buildPackages.stdenv.cc;
+    ++ optional hostPlatform.isDarwin binutils;
 
   buildInputs = optional interactive readline70;
 
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
index eb8545c6999..2d702ab389e 100644
--- a/pkgs/stdenv/generic/make-derivation.nix
+++ b/pkgs/stdenv/generic/make-derivation.nix
@@ -14,11 +14,27 @@ rec {
   mkDerivation =
     { name ? ""
 
-    , nativeBuildInputs ? []
-    , buildInputs ? []
+    # These types of dependencies are all exhaustively documented in
+    # the "Specifying Dependencies" section of the "Standard
+    # Environment" chapter of the Nixpkgs manual.
 
-    , propagatedNativeBuildInputs ? []
-    , propagatedBuildInputs ? []
+    # TODO(@Ericson2314): Stop using legacy dep attribute names
+
+    #                           host offset -> target offset
+    , depsBuildBuild              ? [] # -1 -> -1
+    , depsBuildBuildPropagated    ? [] # -1 -> -1
+    , nativeBuildInputs           ? [] # -1 ->  0  N.B. Legacy name
+    , propagatedNativeBuildInputs ? [] # -1 ->  0  N.B. Legacy name
+    , depsBuildTarget             ? [] # -1 ->  1
+    , depsBuildTargetPropagated   ? [] # -1 ->  1
+
+    , depsHostHost                ? [] #  0 ->  0
+    , depsHostHostPropagated      ? [] #  0 ->  0
+    , buildInputs                 ? [] #  0 ->  1  N.B. Legacy name
+    , propagatedBuildInputs       ? [] #  0 ->  1  N.B. Legacy name
+
+    , depsTargetTarget            ? [] #  1 ->  1
+    , depsTargetTargetPropagated  ? [] #  1 ->  1
 
     , configureFlags ? []
     , # Target is not included by default because most programs don't care.
@@ -56,15 +72,35 @@ rec {
       inherit erroneousHardeningFlags hardeningDisable hardeningEnable supportedHardeningFlags;
     })
     else let
-      dependencies = map lib.chooseDevOutputs [
-        (map (drv: drv.nativeDrv or drv) nativeBuildInputs
-           ++ lib.optional separateDebugInfo ../../build-support/setup-hooks/separate-debug-info.sh
-           ++ lib.optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh)
-        (map (drv: drv.crossDrv or drv) buildInputs)
+      dependencies = map (map lib.chooseDevOutputs) [
+        [
+          (map (drv: drv.__spliced.buildBuild or drv) depsBuildBuild)
+          (map (drv: drv.nativeDrv or drv) nativeBuildInputs
+             ++ lib.optional separateDebugInfo ../../build-support/setup-hooks/separate-debug-info.sh
+             ++ lib.optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh)
+          (map (drv: drv.__spliced.buildTarget or drv) depsBuildTarget)
+        ]
+        [
+          (map (drv: drv.__spliced.hostHost or drv) depsHostHost)
+          (map (drv: drv.crossDrv or drv) buildInputs)
+        ]
+        [
+          (map (drv: drv.__spliced.targetTarget or drv) depsTargetTarget)
+        ]
       ];
-      propagatedDependencies = map lib.chooseDevOutputs [
-        (map (drv: drv.nativeDrv or drv) propagatedNativeBuildInputs)
-        (map (drv: drv.crossDrv or drv) propagatedBuildInputs)
+      propagatedDependencies = map (map lib.chooseDevOutputs) [
+        [
+          (map (drv: drv.__spliced.buildBuild or drv) depsBuildBuildPropagated)
+          (map (drv: drv.nativeDrv or drv) propagatedNativeBuildInputs)
+          (map (drv: drv.__spliced.buildTarget or drv) depsBuildTargetPropagated)
+        ]
+        [
+          (map (drv: drv.__spliced.hostHost or drv) depsHostHostPropagated)
+          (map (drv: drv.crossDrv or drv) propagatedBuildInputs)
+        ]
+        [
+          (map (drv: drv.__spliced.targetTarget or drv) depsTargetTargetPropagated)
+        ]
       ];
 
       outputs' =
@@ -105,11 +141,19 @@ rec {
           userHook = config.stdenv.userHook or null;
           __ignoreNulls = true;
 
-          nativeBuildInputs = lib.elemAt dependencies 0;
-          buildInputs = lib.elemAt dependencies 1;
+          depsBuildBuild              = lib.elemAt (lib.elemAt dependencies 0) 0;
+          nativeBuildInputs           = lib.elemAt (lib.elemAt dependencies 0) 1;
+          depsBuildTarget             = lib.elemAt (lib.elemAt dependencies 0) 2;
+          depsHostBuild               = lib.elemAt (lib.elemAt dependencies 1) 0;
+          buildInputs                 = lib.elemAt (lib.elemAt dependencies 1) 1;
+          depsTargetTarget            = lib.elemAt (lib.elemAt dependencies 2) 0;
 
-          propagatedNativeBuildInputs = lib.elemAt propagatedDependencies 0;
-          propagatedBuildInputs = lib.elemAt propagatedDependencies 1;
+          depsBuildBuildPropagated    = lib.elemAt (lib.elemAt propagatedDependencies 0) 0;
+          propagatedNativeBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 0) 1;
+          depsBuildTargetPropagated   = lib.elemAt (lib.elemAt propagatedDependencies 0) 2;
+          depsHostBuildPropagated     = lib.elemAt (lib.elemAt propagatedDependencies 1) 0;
+          propagatedBuildInputs       = lib.elemAt (lib.elemAt propagatedDependencies 1) 1;
+          depsTargetTargetPropagated  = lib.elemAt (lib.elemAt propagatedDependencies 2) 0;
 
           # This parameter is sometimes a string, sometimes null, and sometimes a list, yuck
           configureFlags = let inherit (lib) optional elem; in
diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh
index 686ed68cede..d2c67cce81a 100644
--- a/pkgs/stdenv/generic/setup.sh
+++ b/pkgs/stdenv/generic/setup.sh
@@ -300,11 +300,83 @@ runHook preHook
 runHook addInputsHook
 
 
-# Recursively find all build inputs.
+# Package accumulators
+
+# shellcheck disable=SC2034
+declare -a pkgsBuildBuild pkgsBuildHost pkgsBuildTarget
+declare -a pkgsHostHost pkgsHostTarget
+declare -a pkgsTargetTarget
+
+declare -ra pkgBuildAccumVars=(pkgsBuildBuild pkgsBuildHost pkgsBuildTarget)
+declare -ra pkgHostAccumVars=(pkgsHostHost pkgsHostTarget)
+declare -ra pkgTargetAccumVars=(pkgsTargetTarget)
+
+declare -ra pkgAccumVarVars=(pkgBuildAccumVars pkgHostAccumVars pkgTargetAccumVars)
+
+
+# Hooks
+
+declare -a envBuildBuildHooks envBuildHostHooks envBuildTargetHooks
+declare -a envHostHostHooks envHostTargetHooks
+declare -a envTargetTargetHooks
+
+declare -ra pkgBuildHookVars=(envBuildBuildHook envBuildHostHook envBuildTargetHook)
+declare -ra pkgHostHookVars=(envHostHostHook envHostTargetHook)
+declare -ra pkgTargetHookVars=(envTargetTargetHook)
+
+declare -ra pkgHookVarVars=(pkgBuildHookVars pkgHostHookVars pkgTargetHookVars)
+
+# Add env hooks for all sorts of deps with the specified host offset.
+addEnvHooks() {
+    local depHostOffset="$1"
+    shift
+    local pkgHookVarsSlice="${pkgHookVarVars[$depHostOffset + 1]}[@]"
+    local pkgHookVar
+    for pkgHookVar in "${!pkgHookVarsSlice}"; do
+        eval "${pkgHookVar}s"'+=("$@")'
+    done
+}
+
+
+# Propagated dep files
+
+declare -ra propagatedBuildDepFiles=(
+    propagated-build-build-deps
+    propagated-native-build-inputs # Legacy name for back-compat
+    propagated-build-target-deps
+)
+declare -ra propagatedHostDepFiles=(
+    propagated-host-host-deps
+    propagated-build-inputs # Legacy name for back-compat
+)
+declare -ra propagatedTargetDepFiles=(
+    propagated-target-target-deps
+)
+declare -ra propagatedDepFilesVars=(
+    propagatedBuildDepFiles
+    propagatedHostDepFiles
+    propagatedTargetDepFiles
+)
+
+# Platform offsets: build = -1, host = 0, target = 1
+declare -ra allPlatOffsets=(-1 0 1)
+
+
+# Mutually-recursively find all build inputs. See the dependency section of the
+# stdenv chapter of the Nixpkgs manual for the specification this algorithm
+# implements.
 findInputs() {
-    local pkg="$1"; shift
-    local var="$1"; shift
-    local propagatedBuildInputsFiles=("$@")
+    local -r pkg="$1"
+    local -ri hostOffset="$2"
+    local -ri targetOffset="$3"
+
+    # Sanity check
+    (( "$hostOffset" <= "$targetOffset" )) || exit -1
+
+    local varVar="${pkgAccumVarVars[$hostOffset + 1]}"
+    local varRef="$varVar[\$targetOffset - \$hostOffset]"
+    local var="${!varRef}"
+    unset -v varVar varRef
 
     # TODO(@Ericson2314): Restore using associative array once Darwin
     # nix-shell doesn't use impure bash. This should replace the O(n)
@@ -324,21 +396,106 @@ findInputs() {
         exit 1
     fi
 
-    local file
-    for file in "${propagatedBuildInputsFiles[@]}"; do
-        file="$pkg/nix-support/$file"
-        [[ -f "$file" ]] || continue
-
-        local pkgNext
-        for pkgNext in $(< "$file"); do
-            findInputs "$pkgNext" "$var" "${propagatedBuildInputsFiles[@]}"
+    # The current package's host and target offset together
+    # provide a <=-preserving homomorphism from the relative
+    # offsets to current offset
+    function mapOffset() {
+        local -ri inputOffset="$1"
+        if (( "$inputOffset" <= 0 )); then
+            local -ri outputOffset="$inputOffset + $hostOffset"
+        else
+            local -ri outputOffset="$inputOffset - 1 + $targetOffset"
+        fi
+        echo "$outputOffset"
+    }
+
+    # Host offset relative to that of the package whose immediate
+    # dependencies we are currently exploring.
+    local -i relHostOffset
+    for relHostOffset in "${allPlatOffsets[@]}"; do
+        # `+ 1` so we start at 0 for valid index
+        local files="${propagatedDepFilesVars[$relHostOffset + 1]}"
+
+        # Host offset relative to the package currently being
+        # built---as absolute an offset as will be used.
+        local -i hostOffsetNext
+        hostOffsetNext="$(mapOffset relHostOffset)"
+
+        # Ensure we're in bounds relative to the package currently
+        # being built.
+        [[ "${allPlatOffsets[*]}" = *"$hostOffsetNext"*  ]] || continue
+
+        # Target offset relative to the *host* offset of the package
+        # whose immediate dependencies we are currently exploring.
+        local -i relTargetOffset
+        for relTargetOffset in "${allPlatOffsets[@]}"; do
+            (( "$relHostOffset" <= "$relTargetOffset" )) || continue
+
+            local fileRef="${files}[$relTargetOffset - $relHostOffset]"
+            local file="${!fileRef}"
+            unset -v fileRef
+
+            # Target offset relative to the package currently being
+            # built.
+            local -i targetOffsetNext
+            targetOffsetNext="$(mapOffset relTargetOffset)"
+
+            # Once again, ensure we're in bounds relative to the
+            # package currently being built.
+            [[ "${allPlatOffsets[*]}" = *"$targetOffsetNext"* ]] || continue
+
+            [[ -f "$pkg/nix-support/$file" ]] || continue
+
+            local pkgNext
+            for pkgNext in $(< "$pkg/nix-support/$file"); do
+                findInputs "$pkgNext" "$hostOffsetNext" "$targetOffsetNext"
+            done
         done
     done
 }
 
+# Make sure all are at least defined as empty
+: ${depsBuildBuild=} ${depsBuildBuildPropagated=}
+: ${nativeBuildInputs=} ${propagatedNativeBuildInputs=} ${defaultNativeBuildInputs=}
+: ${depsBuildTarget=} ${depsBuildTargetPropagated=}
+: ${depsHostHost=} ${depsHostHostPropagated=}
+: ${buildInputs=} ${propagatedBuildInputs=} ${defaultBuildInputs=}
+: ${depsTargetTarget=} ${depsTargetTargetPropagated=}
+
+for pkg in $depsBuildBuild $depsBuildBuildPropagated; do
+    findInputs "$pkg" -1 -1
+done
+for pkg in $nativeBuildInputs $propagatedNativeBuildInputs; do
+    findInputs "$pkg" -1  0
+done
+for pkg in $depsBuildTarget $depsBuildTargetPropagated; do
+    findInputs "$pkg" -1  1
+done
+for pkg in $depsHostHost $depsHostHostPropagated; do
+    findInputs "$pkg"  0  0
+done
+for pkg in $buildInputs $propagatedBuildInputs ; do
+    findInputs "$pkg"  0  1
+done
+for pkg in $depsTargetTarget $depsTargetTargetPropagated; do
+    findInputs "$pkg"  1  1
+done
+# Default inputs must be processed last
+for pkg in $defaultNativeBuildInputs; do
+    findInputs "$pkg" -1  0
+done
+for pkg in $defaultBuildInputs; do
+    findInputs "$pkg"  0  1
+done
+
 # Add package to the future PATH and run setup hooks
 activatePackage() {
     local pkg="$1"
+    local -ri hostOffset="$2"
+    local -ri targetOffset="$3"
+
+    # Sanity check
+    (( "$hostOffset" <= "$targetOffset" )) || exit -1
 
     if [ -f "$pkg" ]; then
         local oldOpts="$(shopt -po nounset)"
@@ -347,11 +504,18 @@ activatePackage() {
         eval "$oldOpts"
     fi
 
-    if [ -d "$pkg/bin" ]; then
+    # Only dependencies whose host platform is guaranteed to match the
+    # build platform are included here. That would be `depsBuild*`,
+    # and legacy `nativeBuildInputs`, in general. If we aren't cross
+    # compiling, however, everything can be put on the PATH. To ease
+    # the transition, we do include everything in thatcase.
+    #
+    # TODO(@Ericson2314): Don't special-case native compilation
+    if [[ ( -z "${crossConfig-}" ||  "$hostOffset" -le -1 ) && -d "$pkg/bin" ]]; then
         addToSearchPath _PATH "$pkg/bin"
     fi
 
-    if [ -f "$pkg/nix-support/setup-hook" ]; then
+    if [[ -f "$pkg/nix-support/setup-hook" ]]; then
         local oldOpts="$(shopt -po nounset)"
         set +u
         source "$pkg/nix-support/setup-hook"
@@ -359,67 +523,72 @@ activatePackage() {
     fi
 }
 
-declare -a nativePkgs crossPkgs
-if [ -z "${crossConfig:-}" ]; then
-    # Not cross-compiling - both buildInputs (and variants like propagatedBuildInputs)
-    # are handled identically to nativeBuildInputs
-    for i in ${nativeBuildInputs:-} ${buildInputs:-} \
-             ${defaultNativeBuildInputs:-} ${defaultBuildInputs:-} \
-             ${propagatedNativeBuildInputs:-} ${propagatedBuildInputs:-}; do
-        findInputs "$i" nativePkgs propagated-native-build-inputs propagated-build-inputs
-    done
-else
-    for i in ${nativeBuildInputs:-} ${defaultNativeBuildInputs:-} ${propagatedNativeBuildInputs:-}; do
-        findInputs "$i" nativePkgs propagated-native-build-inputs
-    done
-    for i in ${buildInputs:-} ${defaultBuildInputs:-} ${propagatedBuildInputs:-}; do
-        findInputs "$i" crossPkgs propagated-build-inputs
+_activatePkgs() {
+    local -i hostOffset targetOffset
+    local pkg
+
+    for hostOffset in "${allPlatOffsets[@]}"; do
+        local pkgsVar="${pkgAccumVarVars[$hostOffset + 1]}"
+        for targetOffset in "${allPlatOffsets[@]}"; do
+            (( "$hostOffset" <= "$targetOffset" )) || continue
+            local pkgsRef="${pkgsVar}[$targetOffset - $hostOffset]"
+            local pkgsSlice="${!pkgsRef}[@]"
+            for pkg in ${!pkgsSlice+"${!pkgsSlice}"}; do
+                activatePackage "$pkg" "$hostOffset" "$targetOffset"
+            done
+        done
     done
-fi
-
-for i in ${nativePkgs+"${nativePkgs[@]}"} ${crossPkgs+"${crossPkgs[@]}"}; do
-    activatePackage "$i"
-done
+}
 
+# Run the package setup hooks and build _PATH
+_activatePkgs
 
 # Set the relevant environment variables to point to the build inputs
 # found above.
 #
-# These `depOffset`s tell the env hook what sort of dependency
-# (ignoring propagatedness) is being passed to the env hook. In a real
-# language, we'd append a closure with this information to the
-# relevant env hook array, but bash doesn't have closures, so it's
-# easier to just pass this in.
-
-_addToNativeEnv() {
-    local pkg="$1"
-    if [[ -n "${crossConfig:-}" ]]; then
-        local -i depOffset=-1
-    else
-        local -i depOffset=0
-    fi
-
-    # Run the package-specific hooks set by the setup-hook scripts.
-    runHook envHook "$pkg"
-}
-
-# Old bash empty array hack
-for i in ${nativePkgs+"${nativePkgs[@]}"}; do
-    _addToNativeEnv "$i"
-done
-
-_addToCrossEnv() {
-    local pkg="$1"
-    local -i depOffset=0
-
-    # Run the package-specific hooks set by the setup-hook scripts.
-    runHook crossEnvHook "$pkg"
+# These `depOffset`s, beyond indexing the arrays, also tell the env
+# hook what sort of dependency (ignoring propagatedness) is being
+# passed to the env hook. In a real language, we'd append a closure
+# with this information to the relevant env hook array, but bash
+# doesn't have closures, so it's easier to just pass this in.
+_addToEnv() {
+    local -i depHostOffset depTargetOffset
+    local pkg
+
+    for depHostOffset in "${allPlatOffsets[@]}"; do
+        local hookVar="${pkgHookVarVars[$depHostOffset + 1]}"
+        local pkgsVar="${pkgAccumVarVars[$depHostOffset + 1]}"
+        for depTargetOffset in "${allPlatOffsets[@]}"; do
+            (( "$depHostOffset" <= "$depTargetOffset" )) || continue
+            local hookRef="${hookVar}[$depTargetOffset - $depHostOffset]"
+            if [[ -z "${crossConfig-}" ]]; then
+                # Apply environment hooks to all packages during native
+                # compilation to ease the transition.
+                #
+                # TODO(@Ericson2314): Don't special-case native compilation
+                for pkg in \
+                    ${pkgsBuildBuild+"${pkgsBuildBuild[@]}"} \
+                    ${pkgsBuildHost+"${pkgsBuildHost[@]}"} \
+                    ${pkgsBuildTarget+"${pkgsBuildTarget[@]}"} \
+                    ${pkgsHostHost+"${pkgsHostHost[@]}"} \
+                    ${pkgsHostTarget+"${pkgsHostTarget[@]}"} \
+                    ${pkgsTargetTarget+"${pkgsTargetTarget[@]}"}
+                do
+                    runHook "${!hookRef}" "$pkg"
+                done
+            else
+                local pkgsRef="${pkgsVar}[$depTargetOffset - $depHostOffset]"
+                local pkgsSlice="${!pkgsRef}[@]"
+                for pkg in ${!pkgsSlice+"${!pkgsSlice}"}; do
+                    runHook "${!hookRef}" "$pkg"
+                done
+            fi
+        done
+    done
 }
 
-# Old bash empty array hack
-for i in ${crossPkgs+"${crossPkgs[@]}"}; do
-    _addToCrossEnv "$i"
-done
+# Run the package-specific hooks set by the setup-hook scripts.
+_addToEnv
 
 
 _addRpathPrefix "$out"
@@ -882,6 +1051,7 @@ installPhase() {
 # propagated-build-inputs.
 fixupPhase() {
     # Make sure everything is writable so "strip" et al. work.
+    local output
     for output in $outputs; do
         if [ -e "${!output}" ]; then chmod -R u+w "${!output}"; fi
     done
@@ -895,19 +1065,35 @@ fixupPhase() {
     done
 
 
-    # Propagate build inputs and setup hook into the development output.
+    # Propagate dependencies & setup hook into the development output.
+    declare -ra flatVars=(
+        # Build
+        depsBuildBuildPropagated
+        propagatedNativeBuildInputs
+        depsBuildTargetPropagated
+        # Host
+        depsHostHostPropagated
+        propagatedBuildInputs
+        # Target
+        depsTargetTargetPropagated
+    )
+    declare -ra flatFiles=(
+        "${propagatedBuildDepFiles[@]}"
+        "${propagatedHostDepFiles[@]}"
+        "${propagatedTargetDepFiles[@]}"
+    )
 
-    if [ -n "${propagatedBuildInputs:-}" ]; then
-        mkdir -p "${!outputDev}/nix-support"
-        # shellcheck disable=SC2086
-        printWords $propagatedBuildInputs > "${!outputDev}/nix-support/propagated-build-inputs"
-    fi
+    local propagatedInputsIndex
+    for propagatedInputsIndex in "${!flatVars[@]}"; do
+        local propagatedInputsSlice="${flatVars[$propagatedInputsIndex]}[@]"
+        local propagatedInputsFile="${flatFiles[$propagatedInputsIndex]}"
+
+        [[ "${!propagatedInputsSlice}" ]] || continue
 
-    if [ -n "${propagatedNativeBuildInputs:-}" ]; then
         mkdir -p "${!outputDev}/nix-support"
         # shellcheck disable=SC2086
-        printWords $propagatedNativeBuildInputs > "${!outputDev}/nix-support/propagated-native-build-inputs"
-    fi
+        printWords ${!propagatedInputsSlice} > "${!outputDev}/nix-support/$propagatedInputsFile"
+    done
 
 
     if [ -n "${setupHook:-}" ]; then
diff --git a/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix b/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix
index 8aaf4993108..02cbac0f278 100644
--- a/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix
+++ b/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix
@@ -193,6 +193,7 @@ rec {
         nuke-refs $out/bin/*
         nuke-refs $out/lib/*
         nuke-refs $out/libexec/gcc/*/*/*
+        nuke-refs $out/lib/gcc/*/*/*
 
         mkdir $out/.pack
         mv $out/* $out/.pack
diff --git a/pkgs/tools/text/sgml/opensp/setup-hook.sh b/pkgs/tools/text/sgml/opensp/setup-hook.sh
index 52da517a8cb..753a3ea6428 100644
--- a/pkgs/tools/text/sgml/opensp/setup-hook.sh
+++ b/pkgs/tools/text/sgml/opensp/setup-hook.sh
@@ -18,5 +18,5 @@ if test -z "$sgmlHookDone"; then
     export ftp_proxy=http://nodtd.invalid/
 
     export SGML_CATALOG_FILES
-    envHooks+=(addSGMLCatalogs)
+    addEnvHooks "$targetOffset" addSGMLCatalogs
 fi
diff --git a/pkgs/tools/typesetting/tex/tetex/setup-hook.sh b/pkgs/tools/typesetting/tex/tetex/setup-hook.sh
index 9c5424e881e..5faef7fe5df 100644
--- a/pkgs/tools/typesetting/tex/tetex/setup-hook.sh
+++ b/pkgs/tools/typesetting/tex/tetex/setup-hook.sh
@@ -4,4 +4,4 @@ addTeXMFPath () {
     fi
 }
 
-envHooks+=(addTeXMFPath)
+addEnvHooks "$targetOffset" addTeXMFPath
diff --git a/pkgs/tools/typesetting/tex/texlive/setup-hook.sh b/pkgs/tools/typesetting/tex/texlive/setup-hook.sh
index 9c5424e881e..5faef7fe5df 100644
--- a/pkgs/tools/typesetting/tex/texlive/setup-hook.sh
+++ b/pkgs/tools/typesetting/tex/texlive/setup-hook.sh
@@ -4,4 +4,4 @@ addTeXMFPath () {
     fi
 }
 
-envHooks+=(addTeXMFPath)
+addEnvHooks "$targetOffset" addTeXMFPath
diff --git a/pkgs/top-level/splice.nix b/pkgs/top-level/splice.nix
index ea81b110080..1fde08d1d48 100644
--- a/pkgs/top-level/splice.nix
+++ b/pkgs/top-level/splice.nix
@@ -24,25 +24,52 @@
 lib: pkgs: actuallySplice:
 
 let
-  defaultBuildScope = pkgs.buildPackages // pkgs.buildPackages.xorg;
+  defaultBuildBuildScope = pkgs.buildPackages.buildPackages // pkgs.buildPackages.buildPackages.xorg;
+  defaultBuildHostScope = pkgs.buildPackages // pkgs.buildPackages.xorg;
+  defaultBuildTargetScope =
+    if pkgs.targetPlatform == pkgs.hostPlatform
+    then defaultBuildHostScope
+    else assert pkgs.hostPlatform == pkgs.buildPlatform; defaultHostTargetScope;
+  defaultHostHostScope = {}; # unimplemented
   # TODO(@Ericson2314): we shouldn't preclude run-time fetching by removing
   # these attributes. We should have a more general solution for selecting
   # whether `nativeDrv` or `crossDrv` is the default in `defaultScope`.
   pkgsWithoutFetchers = lib.filterAttrs (n: _: !lib.hasPrefix "fetch" n) pkgs;
-  defaultRunScope = pkgsWithoutFetchers // pkgs.xorg;
+  targetPkgsWithoutFetchers = lib.filterAttrs (n: _: !lib.hasPrefix "fetch" n) pkgs.targetPackages;
+  defaultHostTargetScope = pkgsWithoutFetchers // pkgs.xorg;
+  defaultTargetTargetScope = targetPkgsWithoutFetchers // targetPkgsWithoutFetchers.xorg or {};
 
-  splicer = buildPkgs: runPkgs: let
-    mash = buildPkgs // runPkgs;
+  splicer = pkgsBuildBuild: pkgsBuildHost: pkgsBuildTarget:
+            pkgsHostHost: pkgsHostTarget:
+            pkgsTargetTarget: let
+    mash =
+      # Other pkgs sets
+      pkgsBuildBuild // pkgsBuildTarget // pkgsHostHost // pkgsTargetTarget
+      # The same pkgs sets one probably intends
+      // pkgsBuildHost // pkgsHostTarget;
     merge = name: {
       inherit name;
       value = let
         defaultValue = mash.${name};
         # `or {}` is for the non-derivation attsert splicing case, where `{}` is the identity.
-        buildValue = buildPkgs.${name} or {};
-        runValue = runPkgs.${name} or {};
+        valueBuildBuild = pkgsBuildBuild.${name} or {};
+        valueBuildHost = pkgsBuildHost.${name} or {};
+        valueBuildTarget = pkgsBuildTarget.${name} or {};
+        valueHostHost = throw "`valueHostHost` unimplemented: pass manually rather than relying on splicer.";
+        valueHostTarget = pkgsHostTarget.${name} or {};
+        valueTargetTarget = pkgsTargetTarget.${name} or {};
         augmentedValue = defaultValue
-          // (lib.optionalAttrs (buildPkgs ? ${name}) { nativeDrv = buildValue; })
-          // (lib.optionalAttrs (runPkgs ? ${name}) { crossDrv = runValue; });
+          # TODO(@Ericson2314): Stop using old names after transition period
+          // (lib.optionalAttrs (pkgsBuildHost ? ${name}) { nativeDrv = valueBuildHost; })
+          // (lib.optionalAttrs (pkgsHostTarget ? ${name}) { crossDrv = valueHostTarget; })
+          // {
+            __spliced =
+                 (lib.optionalAttrs (pkgsBuildBuild ? ${name}) { buildBuild = valueBuildBuild; })
+              // (lib.optionalAttrs (pkgsBuildTarget ? ${name}) { buildTarget = valueBuildTarget; })
+              // { hostHost = valueHostHost; }
+              // (lib.optionalAttrs (pkgsTargetTarget ? ${name}) { targetTarget = valueTargetTarget;
+          });
+        };
         # Get the set of outputs of a derivation. If one derivation fails to
         # evaluate we don't want to diverge the entire splice, so we fall back
         # on {}
@@ -55,10 +82,15 @@ let
       in
         # The derivation along with its outputs, which we recur
         # on to splice them together.
-        if lib.isDerivation defaultValue then augmentedValue
-          // splicer (tryGetOutputs buildValue) (getOutputs runValue)
+        if lib.isDerivation defaultValue then augmentedValue // splicer
+          (tryGetOutputs valueBuildBuild) (tryGetOutputs valueBuildHost) (tryGetOutputs valueBuildTarget)
+          (tryGetOutputs valueHostHost) (getOutputs valueHostTarget)
+          (tryGetOutputs valueTargetTarget)
         # Just recur on plain attrsets
-        else if lib.isAttrs defaultValue then splicer buildValue runValue
+        else if lib.isAttrs defaultValue then splicer
+          valueBuildBuild valueBuildHost valueBuildTarget
+          {} valueHostTarget
+          valueTargetTarget
         # Don't be fancy about non-derivations. But we could have used used
         # `__functor__` for functions instead.
         else defaultValue;
@@ -67,11 +99,16 @@ let
 
   splicedPackages =
     if actuallySplice
-    then splicer defaultBuildScope defaultRunScope // {
-      # These should never be spliced under any circumstances
-      inherit (pkgs) pkgs buildPackages targetPackages
-        buildPlatform targetPlatform hostPlatform;
-    }
+    then
+      splicer
+        defaultBuildBuildScope defaultBuildHostScope defaultBuildTargetScope
+        defaultHostHostScope defaultHostTargetScope
+        defaultTargetTargetScope
+      // {
+        # These should never be spliced under any circumstances
+        inherit (pkgs) pkgs buildPackages targetPackages
+          buildPlatform targetPlatform hostPlatform;
+      }
     else pkgs // pkgs.xorg;
 
 in