about summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/build-fhs-chrootenv/default.nix48
-rw-r--r--pkgs/build-support/build-fhs-chrootenv/destroy.sh.in22
-rw-r--r--pkgs/build-support/build-fhs-chrootenv/init.sh.in22
-rw-r--r--pkgs/build-support/build-fhs-chrootenv/load.sh.in13
-rw-r--r--pkgs/build-support/build-fhs-chrootenv/mount.sh.in34
-rw-r--r--pkgs/build-support/build-fhs-chrootenv/umount.sh.in6
-rwxr-xr-xpkgs/build-support/build-fhs-userenv/chroot-user.rb38
-rw-r--r--pkgs/build-support/build-fhs-userenv/default.nix31
-rw-r--r--pkgs/build-support/build-fhs-userenv/env.nix (renamed from pkgs/build-support/build-fhs-chrootenv/env.nix)106
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix1
-rw-r--r--pkgs/build-support/docker/default.nix4
-rwxr-xr-xpkgs/build-support/fetchgit/nix-prefetch-git73
-rw-r--r--pkgs/build-support/gcc-cross-wrapper/builder.sh1
-rw-r--r--pkgs/build-support/gcc-cross-wrapper/default.nix4
-rw-r--r--pkgs/build-support/grsecurity/default.nix191
-rw-r--r--pkgs/build-support/grsecurity/flavors.nix17
-rw-r--r--pkgs/build-support/libredirect/libredirect.c7
-rw-r--r--pkgs/build-support/rust/default.nix9
-rwxr-xr-xpkgs/build-support/rust/fetch-cargo-deps2
-rw-r--r--pkgs/build-support/rust/fetchcargo.nix4
-rw-r--r--pkgs/build-support/setup-hooks/make-wrapper.sh2
-rw-r--r--pkgs/build-support/setup-hooks/separate-debug-info.sh4
-rw-r--r--pkgs/build-support/trivial-builders.nix19
-rw-r--r--pkgs/build-support/vm/default.nix66
-rw-r--r--pkgs/build-support/vm/windows/controller/default.nix4
25 files changed, 233 insertions, 495 deletions
diff --git a/pkgs/build-support/build-fhs-chrootenv/default.nix b/pkgs/build-support/build-fhs-chrootenv/default.nix
deleted file mode 100644
index dfce8edcb23d..000000000000
--- a/pkgs/build-support/build-fhs-chrootenv/default.nix
+++ /dev/null
@@ -1,48 +0,0 @@
-{ stdenv } : { env, extraInstallCommands ? "" } :
-
-let
-  # References to shell scripts that set up or tear down the environment
-  initSh    = ./init.sh.in;
-  mountSh   = ./mount.sh.in;
-  loadSh    = ./load.sh.in;
-  umountSh  = ./umount.sh.in;
-  destroySh = ./destroy.sh.in;
-
-  name = env.pname;
-
-in stdenv.mkDerivation {
-  name = "${name}-chrootenv";
-  preferLocalBuild = true;
-  buildCommand = ''
-    mkdir -p $out/bin
-    cd $out/bin
-
-    sed -e "s|@chrootEnv@|${env}|g" \
-        -e "s|@name@|${name}|g" \
-        -e "s|@shell@|${stdenv.shell}|g" \
-        ${initSh} > init-${name}-chrootenv
-    chmod +x init-${name}-chrootenv
-
-    sed -e "s|@shell@|${stdenv.shell}|g" \
-        -e "s|@name@|${name}|g" \
-        ${mountSh} > mount-${name}-chrootenv
-    chmod +x mount-${name}-chrootenv
-
-    sed -e "s|@shell@|${stdenv.shell}|g" \
-        -e "s|@name@|${name}|g" \
-        ${loadSh} > load-${name}-chrootenv
-    chmod +x load-${name}-chrootenv
-
-    sed -e "s|@shell@|${stdenv.shell}|g" \
-        -e "s|@name@|${name}|g" \
-        ${umountSh} > umount-${name}-chrootenv
-    chmod +x umount-${name}-chrootenv
-
-    sed -e "s|@chrootEnv@|${env}|g" \
-        -e "s|@shell@|${stdenv.shell}|g" \
-        -e "s|@name@|${name}|g" \
-        ${destroySh} > destroy-${name}-chrootenv
-    chmod +x destroy-${name}-chrootenv
-    ${extraInstallCommands}
-  '';
-}
diff --git a/pkgs/build-support/build-fhs-chrootenv/destroy.sh.in b/pkgs/build-support/build-fhs-chrootenv/destroy.sh.in
deleted file mode 100644
index 015f742d85a5..000000000000
--- a/pkgs/build-support/build-fhs-chrootenv/destroy.sh.in
+++ /dev/null
@@ -1,22 +0,0 @@
-#! @shell@ -e
-
-chrootenvDest=/run/chrootenv/@name@
-
-# Remove bind mount points
-rmdir $chrootenvDest/{dev,nix/store,nix,proc,sys,host-etc,home,var,run,tmp}
-
-# Remove symlinks to the software that should be part of the chroot system profile
-for i in @chrootEnv@/*
-do
-    if [ "$i" != "@chrootEnv@/etc" ] && [ "$i" != "@chrootEnv@/var" ]
-    then
-        rm $chrootenvDest/$(basename $i)
-    fi
-done
-
-# Remove the remaining folders
-rm -Rf $chrootenvDest/{etc,root}
-rm -Rf /tmp/chrootenv-@name@
-
-# Remove the chroot environment folder
-rmdir $chrootenvDest
diff --git a/pkgs/build-support/build-fhs-chrootenv/init.sh.in b/pkgs/build-support/build-fhs-chrootenv/init.sh.in
deleted file mode 100644
index 9c85069a655c..000000000000
--- a/pkgs/build-support/build-fhs-chrootenv/init.sh.in
+++ /dev/null
@@ -1,22 +0,0 @@
-#! @shell@ -e
-
-chrootenvDest=/run/chrootenv/@name@
-
-# Create some mount points for stuff that must be bind mounted
-mkdir -p $chrootenvDest/{nix/store,dev,proc,sys,host-etc,host-tmp,home,var,run}
-
-# Symlink the software that should be part of the chroot system profile
-for i in @chrootEnv@/*
-do
-    if [ "$i" != "@chrootEnv@/var" ]
-    then
-        ln -s "$i" "$chrootenvDest"
-    fi
-done
-
-# Create root folder
-mkdir $chrootenvDest/root
-
-# Create tmp folder
-mkdir -m1777    $chrootenvDest/tmp
-mkdir -m1777 -p /tmp/chrootenv-@name@
diff --git a/pkgs/build-support/build-fhs-chrootenv/load.sh.in b/pkgs/build-support/build-fhs-chrootenv/load.sh.in
deleted file mode 100644
index f3a6d13e8ff7..000000000000
--- a/pkgs/build-support/build-fhs-chrootenv/load.sh.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#! @shell@ -e
-
-chrootenvDest=/run/chrootenv/@name@
-
-# Enter the LFS chroot environment
-sudo chroot --userspec "$USER:${GROUPS[0]}" --groups "${GROUPS[0]}" $chrootenvDest /usr/bin/env -i \
-     TERM="$TERM" \
-     DISPLAY="$DISPLAY" \
-     HOME="$HOME" \
-     XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
-     LANG="$LANG" \
-     SSL_CERT_FILE="$SSL_CERT_FILE" \
-     /bin/bash --login
diff --git a/pkgs/build-support/build-fhs-chrootenv/mount.sh.in b/pkgs/build-support/build-fhs-chrootenv/mount.sh.in
deleted file mode 100644
index 24b28aae78f7..000000000000
--- a/pkgs/build-support/build-fhs-chrootenv/mount.sh.in
+++ /dev/null
@@ -1,34 +0,0 @@
-#! @shell@ -e
-
-chrootenvDest=/run/chrootenv/@name@
-
-# Bind mount the Nix store
-mount --bind /nix/store $chrootenvDest/nix/store
-
-# Bind mount some kernel related stuff
-mount --bind /dev $chrootenvDest/dev
-mount --bind /dev/pts $chrootenvDest/dev/pts
-mount --bind /dev/shm $chrootenvDest/dev/shm
-mount --bind /proc $chrootenvDest/proc
-mount --bind /sys $chrootenvDest/sys
-
-# Bind mount home directories
-mount --bind /home $chrootenvDest/home
-
-# Bind mount state directories
-mount --bind /var $chrootenvDest/var
-mount --rbind /run $chrootenvDest/run
-
-# Bind mount the host system's /etc
-mount --bind /etc $chrootenvDest/host-etc
-
-# Bind mount the host system's /tmp
-mount --bind /tmp $chrootenvDest/host-tmp
-
-# Bind mount /tmp
-mount --bind /tmp/chrootenv-@name@ $chrootenvDest/tmp
-
-# Expose sockets in /tmp
-for i in /tmp/.*-unix; do
-  ln -s "/host-tmp/$(basename "$i")" "$chrootenvDest/$i"
-done
diff --git a/pkgs/build-support/build-fhs-chrootenv/umount.sh.in b/pkgs/build-support/build-fhs-chrootenv/umount.sh.in
deleted file mode 100644
index 27000cff10a9..000000000000
--- a/pkgs/build-support/build-fhs-chrootenv/umount.sh.in
+++ /dev/null
@@ -1,6 +0,0 @@
-#! @shell@ -e
-
-chrootenvDest=/run/chrootenv/@name@
-
-# Unmount all (r)bind mounts
-umount -l $chrootenvDest/{dev/pts,dev/shm,dev,nix/store,proc,sys,host-etc,host-tmp,home,var,tmp,run}
diff --git a/pkgs/build-support/build-fhs-userenv/chroot-user.rb b/pkgs/build-support/build-fhs-userenv/chroot-user.rb
index 250e6a908434..e3b268d57af6 100755
--- a/pkgs/build-support/build-fhs-userenv/chroot-user.rb
+++ b/pkgs/build-support/build-fhs-userenv/chroot-user.rb
@@ -2,16 +2,15 @@
 
 # Bind mounts hierarchy: from => to (relative)
 # If 'to' is nil, path will be the same
-mounts = { '/nix/store' => nil,
-           '/dev' => nil,
+mounts = { '/' => 'host',
            '/proc' => nil,
            '/sys' => nil,
-           '/etc' => 'host-etc',
-           '/tmp' => 'host-tmp',
-           '/home' => nil,
+           '/nix' => nil,
+           '/tmp' => nil,
            '/var' => nil,
            '/run' => nil,
-           '/root' => nil,
+           '/dev' => nil,
+           '/home' => nil,
          }
 
 # Propagate environment variables
@@ -62,12 +61,15 @@ $mount = make_fcall 'mount', [Fiddle::TYPE_VOIDP,
                     Fiddle::TYPE_INT
 
 # Read command line args
-abort "Usage: chrootenv swdir program args..." unless ARGV.length >= 2
-swdir = Pathname.new ARGV[0]
-execp = ARGV.drop 1
+abort "Usage: chrootenv program args..." unless ARGV.length >= 1
+execp = ARGV
 
 # Populate extra mounts
 if not ENV["CHROOTENV_EXTRA_BINDS"].nil?
+  $stderr.puts "CHROOTENV_EXTRA_BINDS is discussed for deprecation."
+  $stderr.puts "If you have a usecase, please drop a note in issue #16030."
+  $stderr.puts "Notice that we now bind-mount host FS to '/host' and symlink all directories from it to '/' by default."
+
   for extra in ENV["CHROOTENV_EXTRA_BINDS"].split(':')
     paths = extra.split('=')
     if not paths.empty?
@@ -132,24 +134,6 @@ if $cpid == 0
   Dir.chroot root
   Dir.chdir '/'
 
-  # Symlink swdir hierarchy
-  mount_dirs = Set.new mounts.map { |_, v| Pathname.new v }
-  link_swdir = lambda do |swdir, prefix|
-    swdir.find do |path|
-      rel = prefix.join path.relative_path_from(swdir)
-      # Don't symlink anything in binded or symlinked directories
-      Find.prune if mount_dirs.include? rel or rel.symlink?
-      if not rel.directory?
-        # File does not exist; make a symlink and bail out
-        rel.make_symlink path
-        Find.prune
-      end
-      # Recursively follow symlinks
-      link_swdir.call path.readlink, rel if path.symlink?
-    end
-  end
-  link_swdir.call swdir, Pathname.new('')
-
   # New environment
   new_env = Hash[ envvars.map { |x| [x, ENV[x]] } ]
 
diff --git a/pkgs/build-support/build-fhs-userenv/default.nix b/pkgs/build-support/build-fhs-userenv/default.nix
index 94c72e29a225..233db39788b0 100644
--- a/pkgs/build-support/build-fhs-userenv/default.nix
+++ b/pkgs/build-support/build-fhs-userenv/default.nix
@@ -1,28 +1,29 @@
-{ runCommand, lib, writeText, writeScriptBin, stdenv, ruby } :
-{ env, runScript ? "bash", extraBindMounts ? [], extraInstallCommands ? "", meta ? {}, passthru ? {} } :
+{ callPackage, runCommand, lib, writeScript, stdenv, coreutils, ruby }:
+
+let buildFHSEnv = callPackage ./env.nix { }; in
+
+args@{ name, runScript ? "bash", extraBindMounts ? [], extraInstallCommands ? "", meta ? {}, passthru ? {}, ... }:
 
 let
-  name = env.pname;
+  env = buildFHSEnv (removeAttrs args [ "runScript" "extraBindMounts" "extraInstallCommands" "meta" "passthru" ]);
 
   # Sandboxing script
-  chroot-user = writeScriptBin "chroot-user" ''
+  chroot-user = writeScript "chroot-user" ''
     #! ${ruby}/bin/ruby
     ${builtins.readFile ./chroot-user.rb}
   '';
 
-  init = run: writeText "${name}-init" ''
-    source /etc/profile
-
-    # Make /tmp directory
-    mkdir -m 1777 /tmp
-
-    # Expose sockets in /tmp
-    for i in /host-tmp/.*-unix; do
-      ln -s "$i" "/tmp/$(basename "$i")"
+  init = run: writeScript "${name}-init" ''
+    #! ${stdenv.shell}
+    for i in ${env}/* /host/*; do
+      path="/''${i##*/}"
+      [ -e "$path" ] || ${coreutils}/bin/ln -s "$i" "$path"
     done
 
     [ -d "$1" ] && [ -r "$1" ] && cd "$1"
     shift
+
+    source /etc/profile
     exec ${run} "$@"
   '';
 
@@ -32,7 +33,7 @@ in runCommand name {
     env = runCommand "${name}-shell-env" {
       shellHook = ''
         export CHROOTENV_EXTRA_BINDS="${lib.concatStringsSep ":" extraBindMounts}:$CHROOTENV_EXTRA_BINDS"
-        exec ${chroot-user}/bin/chroot-user ${env} bash ${init "bash"} "$(pwd)"
+        exec ${chroot-user} ${init "bash"} "$(pwd)"
       '';
     } ''
       echo >&2 ""
@@ -46,7 +47,7 @@ in runCommand name {
   cat <<EOF >$out/bin/${name}
   #! ${stdenv.shell}
   export CHROOTENV_EXTRA_BINDS="${lib.concatStringsSep ":" extraBindMounts}:\$CHROOTENV_EXTRA_BINDS"
-  exec ${chroot-user}/bin/chroot-user ${env} bash ${init runScript} "\$(pwd)" "\$@"
+  exec ${chroot-user} ${init runScript} "\$(pwd)" "\$@"
   EOF
   chmod +x $out/bin/${name}
   ${extraInstallCommands}
diff --git a/pkgs/build-support/build-fhs-chrootenv/env.nix b/pkgs/build-support/build-fhs-userenv/env.nix
index 01d75727f0bf..1dc71987f543 100644
--- a/pkgs/build-support/build-fhs-chrootenv/env.nix
+++ b/pkgs/build-support/build-fhs-userenv/env.nix
@@ -1,7 +1,7 @@
-{ nixpkgs, nixpkgs_i686, system
-} :
+{ stdenv, buildEnv, writeText, pkgs, pkgsi686Linux, system }:
+
 { name, profile ? ""
-, pkgs ? null, targetPkgs ? pkgs: [], multiPkgs ? pkgs: []
+, targetPkgs ? pkgs: [], multiPkgs ? pkgs: []
 , extraBuildCommands ? "", extraBuildCommandsMulti ? ""
 , extraOutputsToInstall ? []
 }:
@@ -22,38 +22,32 @@
 # /lib will link to /lib32
 
 let
-  isMultiBuild  = pkgs == null && multiPkgs != null && system == "x86_64-linux";
+  is64Bit = system == "x86_64-linux";
+  isMultiBuild  = multiPkgs != null && is64Bit;
   isTargetBuild = !isMultiBuild;
 
-  # support deprecated "pkgs" option.
-  targetPkgs' =
-    if pkgs != null
-      then builtins.trace "buildFHSEnv: 'pkgs' option is deprecated, use 'targetPkgs'" (pkgs': pkgs)
-      else targetPkgs;
-
   # list of packages (usually programs) which are only be installed for the
   # host's architecture
-  targetPaths = targetPkgs' nixpkgs ++ (if multiPkgs == null then [] else multiPkgs nixpkgs);
+  targetPaths = targetPkgs pkgs ++ (if multiPkgs == null then [] else multiPkgs pkgs);
 
   # list of packages which are installed for both x86 and x86_64 on x86_64
   # systems
-  multiPaths = if isMultiBuild
-                  then multiPkgs nixpkgs_i686
-                  else [];
+  multiPaths = multiPkgs pkgsi686Linux;
 
   # base packages of the chroot
-  # these match the host's architecture, gcc/glibc_multi are used for multilib
+  # these match the host's architecture, glibc_multi is used for multilib
   # builds.
-  chosenGcc = if isMultiBuild then nixpkgs.gcc_multi else nixpkgs.gcc;
-  basePkgs = with nixpkgs;
+  basePkgs = with pkgs;
     [ (if isMultiBuild then glibc_multi else glibc)
-      chosenGcc
-      bashInteractive coreutils less shadow su
+      (toString gcc.cc.lib) bashInteractive coreutils less shadow su
       gawk diffutils findutils gnused gnugrep
       gnutar gzip bzip2 xz glibcLocales
     ];
+  baseMultiPkgs = with pkgsi686Linux;
+    [ (toString gcc.cc.lib)
+    ];
 
-  etcProfile = nixpkgs.writeText "profile" ''
+  etcProfile = writeText "profile" ''
     export PS1='${name}-chrootenv:\u@\h:\w\$ '
     export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive'
     export LD_LIBRARY_PATH='/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32'
@@ -68,7 +62,7 @@ let
   '';
 
   # Compose /etc for the chroot environment
-  etcPkg = nixpkgs.stdenv.mkDerivation {
+  etcPkg = stdenv.mkDerivation {
     name         = "${name}-chrootenv-etc";
     buildCommand = ''
       mkdir -p $out/etc
@@ -78,38 +72,38 @@ let
       ln -s ${etcProfile} profile
 
       # compatibility with NixOS
-      ln -s /host-etc/static static
+      ln -s /host/etc/static static
 
       # symlink some NSS stuff
-      ln -s /host-etc/passwd passwd
-      ln -s /host-etc/group group
-      ln -s /host-etc/shadow shadow
-      ln -s /host-etc/hosts hosts
-      ln -s /host-etc/resolv.conf resolv.conf
-      ln -s /host-etc/nsswitch.conf nsswitch.conf
+      ln -s /host/etc/passwd passwd
+      ln -s /host/etc/group group
+      ln -s /host/etc/shadow shadow
+      ln -s /host/etc/hosts hosts
+      ln -s /host/etc/resolv.conf resolv.conf
+      ln -s /host/etc/nsswitch.conf nsswitch.conf
 
       # symlink sudo and su stuff
-      ln -s /host-etc/login.defs login.defs
-      ln -s /host-etc/sudoers sudoers
-      ln -s /host-etc/sudoers.d sudoers.d
+      ln -s /host/etc/login.defs login.defs
+      ln -s /host/etc/sudoers sudoers
+      ln -s /host/etc/sudoers.d sudoers.d
 
       # symlink other core stuff
-      ln -s /host-etc/localtime localtime
-      ln -s /host-etc/machine-id machine-id
-      ln -s /host-etc/os-release os-release
+      ln -s /host/etc/localtime localtime
+      ln -s /host/etc/machine-id machine-id
+      ln -s /host/etc/os-release os-release
 
       # symlink PAM stuff
-      ln -s /host-etc/pam.d pam.d
+      ln -s /host/etc/pam.d pam.d
 
       # symlink fonts stuff
-      ln -s /host-etc/fonts fonts
+      ln -s /host/etc/fonts fonts
 
       # symlink ALSA stuff
-      ln -s /host-etc/asound.conf asound.conf
+      ln -s /host/etc/asound.conf asound.conf
 
       # symlink SSL certs
       mkdir -p ssl
-      ln -s /host-etc/ssl/certs ssl/certs
+      ln -s /host/etc/ssl/certs ssl/certs
 
       # symlink /etc/mtab -> /proc/mounts (compat for old userspace progs)
       ln -s /proc/mounts mtab
@@ -117,26 +111,25 @@ let
   };
 
   # Composes a /usr-like directory structure
-  staticUsrProfileTarget = nixpkgs.buildEnv {
+  staticUsrProfileTarget = buildEnv {
     name = "${name}-usr-target";
     paths = [ etcPkg ] ++ basePkgs ++ targetPaths;
-    extraOutputsToInstall = [ "lib" "out" ] ++ extraOutputsToInstall;
+    extraOutputsToInstall = [ "out" "lib" "bin" ] ++ extraOutputsToInstall;
     ignoreCollisions = true;
   };
 
-  staticUsrProfileMulti = nixpkgs.buildEnv {
-    name = "system-profile-multi";
-    paths = multiPaths;
-    extraOutputsToInstall = [ "lib" "out" ] ++ extraOutputsToInstall;
+  staticUsrProfileMulti = buildEnv {
+    name = "${name}-usr-multi";
+    paths = baseMultiPkgs ++ multiPaths;
+    extraOutputsToInstall = [ "out" "lib" ] ++ extraOutputsToInstall;
     ignoreCollisions = true;
   };
 
   # setup library paths only for the targeted architecture
   setupLibDirs_target = ''
-    mkdir -m0755 lib
-
-    # copy content of targetPaths
-    cp -rsHf ${staticUsrProfileTarget}/lib/* lib/
+    # link content of targetPaths
+    cp -rsHf ${staticUsrProfileTarget}/lib lib
+    ln -s lib lib${if is64Bit then "64" else "32"}
   '';
 
   # setup /lib, /lib32 and /lib64
@@ -154,18 +147,8 @@ let
     # copy content of targetPaths (64bit libs)
     cp -rsHf ${staticUsrProfileTarget}/lib/* lib64/ && chmod u+w -R lib64/
 
-    # most 64bit only libs put their stuff into /lib
-    # some pkgs (like gcc_multi) put 32bit libs into /lib and 64bit libs into /lib64
-    # by overwriting these we will hopefully catch all these cases
-    # in the end /lib32 should only contain 32bit and /lib64 only 64bit libs
-    cp -rsHf ${staticUsrProfileTarget}/lib64/* lib64/ && chmod u+w -R lib64/
-
-    # copy gcc libs
-    cp -rsHf ${chosenGcc.cc.lib}/lib/*   lib32/
-    cp -rsHf ${chosenGcc.cc.lib}/lib64/* lib64/
-
     # symlink 32-bit ld-linux.so
-    ln -s ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/
+    ln -Ls ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/
   '';
 
   setupLibDirs = if isTargetBuild then setupLibDirs_target
@@ -195,7 +178,7 @@ let
     done
   '';
 
-in nixpkgs.stdenv.mkDerivation {
+in stdenv.mkDerivation {
   name         = "${name}-fhs";
   buildCommand = ''
     mkdir -p $out
@@ -207,7 +190,4 @@ in nixpkgs.stdenv.mkDerivation {
     ${if isMultiBuild then extraBuildCommandsMulti else ""}
   '';
   preferLocalBuild = true;
-  passthru = {
-    pname = name;
-  };
 }
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index da114fdb347f..a37c806905fd 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -96,6 +96,7 @@ stdenv.mkDerivation {
       echo "-L${libc_lib}/lib" > $out/nix-support/libc-ldflags
 
       echo "${libc_lib}" > $out/nix-support/orig-libc
+      echo "${libc_dev}" > $out/nix-support/orig-libc-dev
     ''
 
     + (if nativeTools then ''
diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix
index 5ead82dee8b5..4c5378ea73f3 100644
--- a/pkgs/build-support/docker/default.nix
+++ b/pkgs/build-support/docker/default.nix
@@ -1,5 +1,5 @@
 { stdenv, lib, callPackage, runCommand, writeReferencesToFile, writeText, vmTools, writeScript
-, docker, shadow, utillinux, coreutils, jshon, e2fsprogs, goPackages, pigz }:
+, docker, shadow, utillinux, coreutils, jshon, e2fsprogs, go, pigz }:
 
 # WARNING: this API is unstable and may be subject to backwards-incompatible changes in the future.
   
@@ -10,7 +10,7 @@ rec {
   # We need to sum layer.tar, not a directory, hence tarsum instead of nix-hash.
   # And we cannot untar it, because then we cannot preserve permissions ecc.
   tarsum = runCommand "tarsum" {
-    buildInputs = [ goPackages.go ];
+    buildInputs = [ go ];
   } ''
     mkdir tarsum
     cd tarsum
diff --git a/pkgs/build-support/fetchgit/nix-prefetch-git b/pkgs/build-support/fetchgit/nix-prefetch-git
index 21359e060eca..9b330d821f85 100755
--- a/pkgs/build-support/fetchgit/nix-prefetch-git
+++ b/pkgs/build-support/fetchgit/nix-prefetch-git
@@ -12,6 +12,10 @@ fetchSubmodules=
 builder=
 branchName=$NIX_PREFETCH_GIT_BRANCH_NAME
 
+# ENV params
+out=${out:-}
+http_proxy=${http_proxy:-}
+
 # populated by clone_user_rev()
 fullRev=
 humanReadableRev=
@@ -64,7 +68,7 @@ for arg; do
             --builder) builder=true;;
             --help) usage; exit;;
             *)
-                argi=$(($argi + 1))
+                : $((++argi))
                 case $argi in
                     1) url=$arg;;
                     2) rev=$arg;;
@@ -76,7 +80,7 @@ for arg; do
     else
         case $argfun in
             set_*)
-                var=$(echo $argfun | sed 's,^set_,,')
+                var=${argfun#set_}
                 eval $var=$arg
                 ;;
         esac
@@ -92,8 +96,8 @@ fi
 init_remote(){
     local url=$1
     git init
-    git remote add origin $url
-    ( [ -n "$http_proxy" ] && git config http.proxy $http_proxy ) || true
+    git remote add origin "$url"
+    ( [ -n "$http_proxy" ] && git config http.proxy "$http_proxy" ) || true
 }
 
 # Return the reference of an hash if it exists on the remote repository.
@@ -116,12 +120,13 @@ url_to_name(){
     local url=$1
     local ref=$2
     # basename removes the / and .git suffixes
-    local base=$(basename "$url" .git)
+    local base
+    base=$(basename "$url" .git)
 
     if [[ $ref =~ ^[a-z0-9]+$ ]]; then
         echo "$base-${ref:0:7}"
     else
-        echo $base
+        echo "$base"
     fi
 }
 
@@ -131,11 +136,11 @@ checkout_hash(){
     local ref="$2"
 
     if test -z "$hash"; then
-        hash=$(hash_from_ref $ref)
+        hash=$(hash_from_ref "$ref")
     fi
 
     git fetch -t ${builder:+--progress} origin || return 1
-    git checkout -b $branchName $hash || return 1
+    git checkout -b "$branchName" "$hash" || return 1
 }
 
 # Fetch only a branch/tag and checkout it.
@@ -152,13 +157,13 @@ checkout_ref(){
     fi
 
     if test -z "$ref"; then
-        ref=$(ref_from_hash $hash)
+        ref=$(ref_from_hash "$hash")
     fi
 
     if test -n "$ref"; then
         # --depth option is ignored on http repository.
         git fetch ${builder:+--progress} --depth 1 origin +"$ref" || return 1
-        git checkout -b $branchName FETCH_HEAD || return 1
+        git checkout -b "$branchName" FETCH_HEAD || return 1
     else
         return 1
     fi
@@ -171,27 +176,32 @@ init_submodules(){
 
     # list submodule directories and their hashes
     git submodule status |
-    while read l; do
+    while read -r l; do
+        local hash
+        local dir
+        local name
+        local url
+
         # checkout each submodule
-        local hash=$(echo $l | awk '{print substr($1,2)}')
-        local dir=$(echo $l | awk '{print $2}')
-        local name=$(
+        hash=$(echo "$l" | awk '{print substr($1,2)}')
+        dir=$(echo "$l" | awk '{print $2}')
+        name=$(
             git config -f .gitmodules --get-regexp submodule\..*\.path |
             sed -n "s,^\(.*\)\.path $dir\$,\\1,p")
-        local url=$(git config --get ${name}.url)
+        url=$(git config --get "${name}.url")
 
         clone "$dir" "$url" "$hash" ""
     done
 }
 
 clone(){
-    local top=$(pwd)
+    local top=$PWD
     local dir="$1"
     local url="$2"
     local hash="$3"
     local ref="$4"
 
-    cd $dir
+    cd "$dir"
 
     # Initialize the repository.
     init_remote "$url"
@@ -208,9 +218,8 @@ clone(){
         init_submodules
     fi
 
-    if [ -z "$builder" -a -f .topdeps ]; then
-        if tg help 2>&1 > /dev/null
-        then
+    if [ -z "$builder" ] && [ -f .topdeps ]; then
+        if tg help &>/dev/null; then
             echo "populating TopGit branches..."
             tg remote --populate origin
         else
@@ -219,7 +228,7 @@ clone(){
         fi
     fi
 
-    cd $top
+    cd "$top"
 }
 
 # Remove all remote branches, remove tags not reachable from HEAD, do a full
@@ -236,14 +245,14 @@ make_deterministic_repo(){
         .git/refs/remotes/origin/HEAD .git/config
 
     # Remove all remote branches.
-    git branch -r | while read branch; do
+    git branch -r | while read -r branch; do
         git branch -rD "$branch" >&2
     done
 
     # Remove tags not reachable from HEAD. If we're exactly on a tag, don't
     # delete it.
     maybe_tag=$(git tag --points-at HEAD)
-    git tag --contains HEAD | while read tag; do
+    git tag --contains HEAD | while read -r tag; do
         if [ "$tag" != "$maybe_tag" ]; then
             git tag -d "$tag" >&2
         fi
@@ -270,7 +279,7 @@ _clone_user_rev() {
         HEAD|refs/*)
             clone "$dir" "$url" "" "$rev" 1>&2;;
         *)
-            if test -z "$(echo $rev | tr -d 0123456789abcdef)"; then
+            if test -z "$(echo "$rev" | tr -d 0123456789abcdef)"; then
                 clone "$dir" "$url" "$rev" "" 1>&2
             else
                 echo 1>&2 "Bad commit hash or bad reference."
@@ -278,9 +287,9 @@ _clone_user_rev() {
             fi;;
     esac
 
-    fullRev="$(cd $dir && (git rev-parse $rev 2> /dev/null || git rev-parse refs/heads/$branchName) | tail -n1)"
-    humanReadableRev="$(cd $dir && (git describe $fullRev 2> /dev/null || git describe --tags $fullRev 2> /dev/null || echo -- none --))"
-    commitDate="$(cd $dir && git show --no-patch --pretty=%ci $fullRev)"
+    fullRev="$(cd "$dir" && (git rev-parse "$rev" 2> /dev/null || git rev-parse "refs/heads/$branchName") | tail -n1)"
+    humanReadableRev="$(cd "$dir" && (git describe "$fullRev" 2> /dev/null || git describe --tags "$fullRev" 2> /dev/null || echo -- none --))"
+    commitDate="$(cd "$dir" && git show --no-patch --pretty=%ci "$fullRev")"
 
     # Allow doing additional processing before .git removal
     eval "$NIX_PREFETCH_GIT_CHECKOUT_HOOK"
@@ -288,7 +297,7 @@ _clone_user_rev() {
         echo "removing \`.git'..." >&2
         find "$dir" -name .git -print0 | xargs -0 rm -rf
     else
-        find "$dir" -name .git | while read gitdir; do
+        find "$dir" -name .git | while read -r gitdir; do
             make_deterministic_repo "$(readlink -f "$gitdir/..")"
         done
     fi
@@ -299,6 +308,7 @@ clone_user_rev() {
         _clone_user_rev "$@"
     else
         errfile="$(mktemp "${TMPDIR:-/tmp}/git-checkout-err-XXXXXXXX")"
+        # shellcheck disable=SC2064
         trap "rm -rf \"$errfile\"" EXIT
         _clone_user_rev "$@" 2> "$errfile" || (
             status="$?"
@@ -343,7 +353,7 @@ fi
 
 if test -n "$builder"; then
     test -n "$out" -a -n "$url" -a -n "$rev" || usage
-    mkdir -p $out
+    mkdir -p "$out"
     clone_user_rev "$out" "$url" "$rev"
 else
     if test -z "$hashType"; then
@@ -365,6 +375,7 @@ else
     if test -z "$finalPath"; then
 
         tmpPath="$(mktemp -d "${TMPDIR:-/tmp}/git-checkout-tmp-XXXXXXXX")"
+        # shellcheck disable=SC2064
         trap "rm -rf \"$tmpPath\"" EXIT
 
         tmpFile="$tmpPath/$(url_to_name "$url" "$rev")"
@@ -374,7 +385,7 @@ else
         clone_user_rev "$tmpFile" "$url" "$rev"
 
         # Compute the hash.
-        hash=$(nix-hash --type $hashType --base32 $tmpFile)
+        hash=$(nix-hash --type $hashType --base32 "$tmpFile")
 
         # Add the downloaded file to the Nix store.
         finalPath=$(nix-store --add-fixed --recursive "$hashType" "$tmpFile")
@@ -389,6 +400,6 @@ else
     print_results "$hash"
 
     if test -n "$PRINT_PATH"; then
-        echo $finalPath
+        echo "$finalPath"
     fi
 fi
diff --git a/pkgs/build-support/gcc-cross-wrapper/builder.sh b/pkgs/build-support/gcc-cross-wrapper/builder.sh
index c6bc2a7c8bf9..9396ace84f11 100644
--- a/pkgs/build-support/gcc-cross-wrapper/builder.sh
+++ b/pkgs/build-support/gcc-cross-wrapper/builder.sh
@@ -111,6 +111,7 @@ chmod +x "$out/bin/$crossConfig-ld"
 # Glibc.
 test -n "$gcc" && echo $gcc > $out/nix-support/orig-cc
 test -n "$libc" && echo $libc > $out/nix-support/orig-libc
+test -n "$libc_dev" && echo $libc_dev > $out/nix-support/orig-libc-dev
 
 doSubstitute "$addFlags" "$out/nix-support/add-flags"
 
diff --git a/pkgs/build-support/gcc-cross-wrapper/default.nix b/pkgs/build-support/gcc-cross-wrapper/default.nix
index d3494b83a87b..505d80a6b2ac 100644
--- a/pkgs/build-support/gcc-cross-wrapper/default.nix
+++ b/pkgs/build-support/gcc-cross-wrapper/default.nix
@@ -44,7 +44,9 @@ stdenv.mkDerivation {
   ldWrapper = ./ld-wrapper.sh;
   utils = ./utils.sh;
   addFlags = ./add-flags;
-  inherit nativeTools nativeLibc nativePrefix gcc libc binutils;
+  inherit nativeTools nativeLibc nativePrefix gcc binutils;
+  libc = if libc ? out then libc.out else libc;
+  libc_dev = if libc ? dev then libc.dev else libc;
   crossConfig = if cross != null then cross.config else null;
   osxMinVersion = cross.osxMinVersion or null;
   gccLibs = if gcc != null then gccLibs else null;
diff --git a/pkgs/build-support/grsecurity/default.nix b/pkgs/build-support/grsecurity/default.nix
index 7777b6000628..8713f2d22c45 100644
--- a/pkgs/build-support/grsecurity/default.nix
+++ b/pkgs/build-support/grsecurity/default.nix
@@ -1,158 +1,33 @@
-{ grsecOptions, lib, pkgs }:
-
-with lib;
-
-let
-  cfg = {
-    kernelPatch = grsecOptions.kernelPatch;
-    config = {
-      mode = "auto";
-      sysctl = false;
-      denyChrootCaps = false;
-      denyChrootChmod = false;
-      denyUSB = false;
-      restrictProc = false;
-      restrictProcWithGroup = true;
-      unrestrictProcGid = 121; # Ugh, an awful hack. See grsecurity NixOS gid
-      disableRBAC = false;
-      disableSimultConnect = false;
-      redistKernel = true;
-      verboseVersion = false;
-      kernelExtraConfig = "";
-    } // grsecOptions.config;
-  };
-
-  vals = rec {
-
-    mkKernel = patch:
-        {
-          inherit patch;
-          inherit (patch) kernel patches grversion revision;
-        };
-
-    grKernel = mkKernel cfg.kernelPatch;
-
-    ## -- grsecurity configuration ---------------------------------------------
-
-    grsecPrioCfg =
-      if cfg.config.priority == "security" then
-        "GRKERNSEC_CONFIG_PRIORITY_SECURITY y"
-      else
-        "GRKERNSEC_CONFIG_PRIORITY_PERF y";
-
-    grsecSystemCfg =
-      if cfg.config.system == "desktop" then
-        "GRKERNSEC_CONFIG_DESKTOP y"
-      else
-        "GRKERNSEC_CONFIG_SERVER y";
-
-    grsecVirtCfg =
-      if cfg.config.virtualisationConfig == null then
-        "GRKERNSEC_CONFIG_VIRT_NONE y"
-      else if cfg.config.virtualisationConfig == "host" then
-        "GRKERNSEC_CONFIG_VIRT_HOST y"
-      else
-        "GRKERNSEC_CONFIG_VIRT_GUEST y";
-
-    grsecHwvirtCfg = if cfg.config.virtualisationConfig == null then "" else
-      if cfg.config.hardwareVirtualisation == true then
-        "GRKERNSEC_CONFIG_VIRT_EPT y"
-      else
-        "GRKERNSEC_CONFIG_VIRT_SOFT y";
-
-    grsecVirtswCfg =
-      let virtCfg = opt: "GRKERNSEC_CONFIG_VIRT_"+opt+" y";
-      in
-        if cfg.config.virtualisationConfig == null then ""
-        else if cfg.config.virtualisationSoftware == "xen"    then virtCfg "XEN"
-        else if cfg.config.virtualisationSoftware == "kvm"    then virtCfg "KVM"
-        else if cfg.config.virtualisationSoftware == "vmware" then virtCfg "VMWARE"
-        else                                                       virtCfg "VIRTUALBOX";
-
-    grsecMainConfig = if cfg.config.mode == "custom" then "" else ''
-      GRKERNSEC_CONFIG_AUTO y
-      ${grsecPrioCfg}
-      ${grsecSystemCfg}
-      ${grsecVirtCfg}
-      ${grsecHwvirtCfg}
-      ${grsecVirtswCfg}
-    '';
-
-    grsecConfig =
-      let boolToKernOpt = b: if b then "y" else "n";
-          # Disable RANDSTRUCT under virtualbox, as it has some kind of
-          # breakage with the vbox guest drivers
-          #randstruct = optionalString config.virtualisation.virtualbox.guest.enable
-          #  "GRKERNSEC_RANDSTRUCT n";
-
-          # Disable restricting links under the testing kernel, as something
-          # has changed causing it to fail miserably during boot.
-          #restrictLinks = optionalString cfg.testing
-          #  "GRKERNSEC_LINK n";
-      in ''
-        GRKERNSEC y
-        ${grsecMainConfig}
-
-        # Disable features rendered useless by redistributing the kernel
-        ${optionalString cfg.config.redistKernel ''
-          GRKERNSEC_RANDSTRUCT n
-          GRKERNSEC_HIDESYM n
-          ''}
-
-        # The paxmarks mechanism relies on ELF header markings, but the default
-        # grsecurity configuration only enables xattr markings
-        PAX_PT_PAX_FLAGS y
-
-        ${if cfg.config.restrictProc then
-            "GRKERNSEC_PROC_USER y"
-          else
-            optionalString cfg.config.restrictProcWithGroup ''
-              GRKERNSEC_PROC_USERGROUP y
-              GRKERNSEC_PROC_GID ${toString cfg.config.unrestrictProcGid}
-            ''
-        }
-
-        GRKERNSEC_SYSCTL ${boolToKernOpt cfg.config.sysctl}
-        GRKERNSEC_CHROOT_CAPS ${boolToKernOpt cfg.config.denyChrootCaps}
-        GRKERNSEC_CHROOT_CHMOD ${boolToKernOpt cfg.config.denyChrootChmod}
-        GRKERNSEC_DENYUSB ${boolToKernOpt cfg.config.denyUSB}
-        GRKERNSEC_NO_RBAC ${boolToKernOpt cfg.config.disableRBAC}
-        GRKERNSEC_NO_SIMULT_CONNECT ${boolToKernOpt cfg.config.disableSimultConnect}
-
-        ${cfg.config.kernelExtraConfig}
-      '';
-
-    ## -- grsecurity kernel packages -------------------------------------------
-
-    localver = grkern:
-      "-grsec" + optionalString cfg.config.verboseVersion
-         "-${grkern.grversion}-${grkern.revision}";
-
-    grsecurityOverrider = args: grkern: {
-      # additional build inputs for gcc plugins, required by some PaX/grsec features
-      nativeBuildInputs = args.nativeBuildInputs ++ (with pkgs; [ gmp libmpc mpfr ]);
-
-      preConfigure = (args.preConfigure or "") + ''
-        echo ${localver grkern} > localversion-grsec
-      '';
-    };
-
-    mkGrsecKern = grkern:
-      lowPrio (overrideDerivation (grkern.kernel.override (args: {
-        kernelPatches = args.kernelPatches ++ [ grkern.patch  ] ++ grkern.patches;
-        argsOverride = {
-          modDirVersion = "${grkern.kernel.modDirVersion}${localver grkern}";
-        };
-        extraConfig = grsecConfig;
-        features.grsecurity = true;
-        ignoreConfigErrors = true; # Too lazy to model the config options that work with grsecurity and don't for now
-      })) (args: grsecurityOverrider args grkern));
-
-    mkGrsecPkg = grkern: pkgs.linuxPackagesFor grkern (mkGrsecPkg grkern);
-
-    ## -- Kernel packages ------------------------------------------------------
-
-    grsecKernel  = mkGrsecKern grKernel;
-    grsecPackage = mkGrsecPkg grsecKernel;
-  };
-in vals
+{ stdenv
+, overrideDerivation
+
+# required for gcc plugins
+, gmp, libmpc, mpfr
+
+# the base kernel
+, kernel
+
+, grsecPatch
+, kernelPatches ? []
+
+, localver ? "-grsec"
+, modDirVersion ? "${kernel.version}${localver}"
+, extraConfig ? ""
+, ...
+} @ args:
+
+assert (kernel.version == grsecPatch.kver);
+
+overrideDerivation (kernel.override {
+  inherit modDirVersion;
+  kernelPatches = [ { inherit (grsecPatch) name patch; } ] ++ kernelPatches ++ (kernel.kernelPatches or []);
+  features = (kernel.features or {}) // { grsecurity = true; };
+  inherit extraConfig;
+  ignoreConfigErrors = true;
+}) (attrs: {
+  nativeBuildInputs = [ gmp libmpc mpfr ] ++ (attrs.nativeBuildInputs or []);
+  preConfigure = ''
+    echo ${localver} >localversion-grsec
+    ${attrs.preConfigure or ""}
+  '';
+})
diff --git a/pkgs/build-support/grsecurity/flavors.nix b/pkgs/build-support/grsecurity/flavors.nix
deleted file mode 100644
index 1281d60aa328..000000000000
--- a/pkgs/build-support/grsecurity/flavors.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-let
-  mkOpts = prio: sys: virt: swvirt: hwvirt:
-    { config.priority               = prio;
-      config.system                 = sys;
-      config.virtualisationConfig   = virt;
-      config.hardwareVirtualisation = hwvirt;
-      config.virtualisationSoftware = swvirt;
-    };
-in
-{
-  desktop =
-    mkOpts "performance" "desktop" "host" "kvm" true;
-  server  =
-    mkOpts "security" "server" "host" "kvm" true;
-  server_xen =
-    mkOpts "security" "server" "guest" "xen" true;
-}
diff --git a/pkgs/build-support/libredirect/libredirect.c b/pkgs/build-support/libredirect/libredirect.c
index e60319d09717..ed0d5b0043d5 100644
--- a/pkgs/build-support/libredirect/libredirect.c
+++ b/pkgs/build-support/libredirect/libredirect.c
@@ -137,3 +137,10 @@ int posix_spawn(pid_t * pid, const char * path,
     char buf[PATH_MAX];
     return posix_spawn_real(pid, rewrite(path, buf), file_actions, attrp, argv, envp);
 }
+
+int execv(const char *path, char *const argv[])
+{
+    int (*execv_real) (const char *path, char *const argv[]) = dlsym(RTLD_NEXT, "execv");
+    char buf[PATH_MAX];
+    return execv_real(rewrite(path, buf), argv);
+}
diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix
index 79e4366eebe1..bbea045f6371 100644
--- a/pkgs/build-support/rust/default.nix
+++ b/pkgs/build-support/rust/default.nix
@@ -1,15 +1,16 @@
-{ stdenv, cacert, git, cargo, rustRegistry }:
+{ stdenv, cacert, git, rust, rustRegistry }:
 { name, depsSha256
 , src ? null
 , srcs ? null
 , sourceRoot ? null
+, logLevel ? ""
 , buildInputs ? []
 , cargoUpdateHook ? ""
 , ... } @ args:
 
 let
   fetchDeps = import ./fetchcargo.nix {
-    inherit stdenv cacert git cargo rustRegistry;
+    inherit stdenv cacert git rust rustRegistry;
   };
 
   cargoDeps = fetchDeps {
@@ -22,7 +23,7 @@ in stdenv.mkDerivation (args // {
 
   patchRegistryDeps = ./patch-registry-deps;
 
-  buildInputs = [ git cargo cargo.rustc ] ++ buildInputs;
+  buildInputs = [ git rust.cargo rust.rustc ] ++ buildInputs;
 
   configurePhase = args.configurePhase or "true";
 
@@ -42,6 +43,8 @@ in stdenv.mkDerivation (args // {
     EOF
 
     export CARGO_HOME="$(realpath deps)"
+    export RUST_LOG=${logLevel}
+    export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
 
     # Let's find out which $indexHash cargo uses for file:///dev/null
     (cd $sourceRoot && cargo fetch &>/dev/null) || true
diff --git a/pkgs/build-support/rust/fetch-cargo-deps b/pkgs/build-support/rust/fetch-cargo-deps
index 4fbc53d1039e..54593994990f 100755
--- a/pkgs/build-support/rust/fetch-cargo-deps
+++ b/pkgs/build-support/rust/fetch-cargo-deps
@@ -147,7 +147,7 @@ EOF
             done
 
             # Create ad-hoc branches for the revs we need
-            echo "$revs" | while read rev; do
+            echo "$revs" | tr " " "\n" | while read -d " " rev; do
                 echo "Creating git branch b_$rev $rev"
                 git branch b_$rev $rev
             done
diff --git a/pkgs/build-support/rust/fetchcargo.nix b/pkgs/build-support/rust/fetchcargo.nix
index 518420002622..1b4983e32597 100644
--- a/pkgs/build-support/rust/fetchcargo.nix
+++ b/pkgs/build-support/rust/fetchcargo.nix
@@ -1,9 +1,9 @@
-{ stdenv, cacert, git, cargo, rustRegistry }:
+{ stdenv, cacert, git, rust, rustRegistry }:
 { name ? "cargo-deps", src, srcs, sourceRoot, sha256, cargoUpdateHook ? "" }:
 
 stdenv.mkDerivation {
   name = "${name}-fetch";
-  buildInputs = [ cargo git ];
+  buildInputs = [ rust.cargo rust.rustc git ];
   inherit src srcs sourceRoot rustRegistry cargoUpdateHook;
 
   phases = "unpackPhase installPhase";
diff --git a/pkgs/build-support/setup-hooks/make-wrapper.sh b/pkgs/build-support/setup-hooks/make-wrapper.sh
index 7d0f88abb855..d922db5ccf58 100644
--- a/pkgs/build-support/setup-hooks/make-wrapper.sh
+++ b/pkgs/build-support/setup-hooks/make-wrapper.sh
@@ -16,7 +16,7 @@ makeWrapper() {
             varName=${params[$((n + 1))]}
             value=${params[$((n + 2))]}
             n=$((n + 2))
-            echo "export $varName=$value" >> $wrapper
+            echo "export $varName=\"$value\"" >> $wrapper
         fi
 
         if test "$p" = "--unset"; then
diff --git a/pkgs/build-support/setup-hooks/separate-debug-info.sh b/pkgs/build-support/setup-hooks/separate-debug-info.sh
index 518be9647334..c90d2cd52013 100644
--- a/pkgs/build-support/setup-hooks/separate-debug-info.sh
+++ b/pkgs/build-support/setup-hooks/separate-debug-info.sh
@@ -6,8 +6,10 @@ dontStrip=1
 fixupOutputHooks+=(_separateDebugInfo)
 
 _separateDebugInfo() {
+    [ -e "$prefix" ] || return 0
+
     local dst="${debug:-$out}"
-    if [ "$prefix" = "$dst" ]; then return; fi
+    if [ "$prefix" = "$dst" ]; then return 0; fi
 
     dst="$dst/lib/debug/.build-id"
 
diff --git a/pkgs/build-support/trivial-builders.nix b/pkgs/build-support/trivial-builders.nix
index b0040cf18177..18e49105ae78 100644
--- a/pkgs/build-support/trivial-builders.nix
+++ b/pkgs/build-support/trivial-builders.nix
@@ -8,6 +8,7 @@ rec {
   runCommand = name: env: buildCommand:
     stdenv.mkDerivation ({
       inherit name buildCommand;
+      passAsFile = [ "buildCommand" ];
     } // env);
 
 
@@ -48,17 +49,15 @@ rec {
 
   # Create a forest of symlinks to the files in `paths'.
   symlinkJoin =
-    { name
-    , paths
-    , preferLocalBuild ? true
-    , allowSubstitutes ? false
-    , postBuild ? ""
-    , buildInputs ? []
-    , meta ? {}
-    }:
+    args@{ name
+         , paths
+         , preferLocalBuild ? true
+         , allowSubstitutes ? false
+         , postBuild ? ""
+         , ...
+         }:
     runCommand name
-      { inherit paths preferLocalBuild allowSubstitutes buildInputs meta;
-      }
+      (removeAttrs args [ "name" "postBuild" ])
       ''
         mkdir -p $out
         for i in $paths; do
diff --git a/pkgs/build-support/vm/default.nix b/pkgs/build-support/vm/default.nix
index 4718e2d72f6e..82cb72cb67ea 100644
--- a/pkgs/build-support/vm/default.nix
+++ b/pkgs/build-support/vm/default.nix
@@ -1182,6 +1182,30 @@ rec {
       packages = commonOpenSUSEPackages;
     };
 
+    opensuse132i386 = {
+      name = "opensuse-13.2-i586";
+      fullName = "openSUSE 13.2 (i586)";
+      packagesList = fetchurl {
+        url = mirror://opensuse/13.2/repo/oss/suse/repodata/485e4f44e3c3ef3133accb589480933c2fe48dedfc44a7e5f9d5437cd9122a99-primary.xml.gz;
+        sha256 = "0klzmk680as4sb6h1wl0ynj0dds3m70qim66wwbiqlnnp6xkf83y";
+      };
+      urlPrefix = mirror://opensuse/13.2/repo/oss/suse/;
+      archs = ["noarch" "i586"];
+      packages = commonOpenSUSEPackages;
+    };
+
+    opensuse132x86_64 = {
+      name = "opensuse-13.2-x86_64";
+      fullName = "openSUSE 13.2 (x86_64)";
+      packagesList = fetchurl {
+        url = mirror://opensuse/13.2/repo/oss/suse/repodata/485e4f44e3c3ef3133accb589480933c2fe48dedfc44a7e5f9d5437cd9122a99-primary.xml.gz;
+        sha256 = "0klzmk680as4sb6h1wl0ynj0dds3m70qim66wwbiqlnnp6xkf83y";
+      };
+      urlPrefix = mirror://opensuse/13.2/repo/oss/suse/;
+      archs = ["noarch" "x86_64"];
+      packages = commonOpenSUSEPackages;
+    };
+
     centos65i386 = {
       name = "centos-6.5-i386";
       fullName = "CentOS 6.5 (i386)";
@@ -1191,7 +1215,7 @@ rec {
       };
       urlPrefix = http://vault.centos.org/6.5/os/i386;
       archs = ["noarch" "i386"];
-      packages = commonCentOSPackages;
+      packages = commonCentOSPackages ++ [ "procps" ];
     };
 
     centos65x86_64 = {
@@ -1203,7 +1227,20 @@ rec {
       };
       urlPrefix = http://vault.centos.org/6.5/os/x86_64/;
       archs = ["noarch" "x86_64"];
-      packages = commonCentOSPackages;
+      packages = commonCentOSPackages ++ [ "procps" ];
+    };
+
+    # Note: no i386 release for 7.x
+    centos71x86_64 = {
+      name = "centos-7.1-x86_64";
+      fullName = "CentOS 7.1 (x86_64)";
+      packagesList = fetchurl {
+        url = http://vault.centos.org/7.1.1503/os/x86_64/repodata/1386c5af55bda40669bb5ed91e0a22796c3ed7325367506109b09ea2657f22bd-primary.xml.gz;
+        sha256 = "1g92gxjs57mh15hm0rsk6bbkwv3r4851xnaypdlhd95xanpwb1hk";
+      };
+      urlPrefix = http://vault.centos.org/7.1.1503/os/x86_64;
+      archs = ["noarch" "x86_64"];
+      packages = commonCentOSPackages ++ [ "procps-ng" ];
     };
 
   };
@@ -1795,44 +1832,44 @@ rec {
     debian70x86_64 = debian7x86_64;
 
     debian7i386 = {
-      name = "debian-7.9-wheezy-i386";
-      fullName = "Debian 7.9 Wheezy (i386)";
+      name = "debian-7.11-wheezy-i386";
+      fullName = "Debian 7.11 Wheezy (i386)";
       packagesList = fetchurl {
         url = mirror://debian/dists/wheezy/main/binary-i386/Packages.bz2;
-        sha256 = "a390176680327fd52d6aada6dd8eee051c94ce49d80f0a68dc90ef51b81c3169";
+        sha256 = "57ea423dc1c0cc082cae580360f8e7192c9fd60e2ef775a4ce7f48784277462d";
       };
       urlPrefix = mirror://debian;
       packages = commonDebianPackages;
     };
 
     debian7x86_64 = {
-      name = "debian-7.9-wheezy-amd64";
-      fullName = "Debian 7.9 Wheezy (amd64)";
+      name = "debian-7.11-wheezy-amd64";
+      fullName = "Debian 7.11 Wheezy (amd64)";
       packagesList = fetchurl {
         url = mirror://debian/dists/wheezy/main/binary-amd64/Packages.bz2;
-        sha256 = "818d78c648505f91cb99f269178d4f62b56d4209cd51bebbc9bf2bd31c8c7156";
+        sha256 = "b400e459ce2f8af8621182c3a9ea843f0df3dc2d5662e6c6204f9406f5ff2d41";
       };
       urlPrefix = mirror://debian;
       packages = commonDebianPackages;
     };
 
     debian8i386 = {
-      name = "debian-8.4-jessie-i386";
-      fullName = "Debian 8.4 Jessie (i386)";
+      name = "debian-8.5-jessie-i386";
+      fullName = "Debian 8.5 Jessie (i386)";
       packagesList = fetchurl {
         url = mirror://debian/dists/jessie/main/binary-i386/Packages.xz;
-        sha256 = "1j8swc1nzsi20vbcmya2sv0fzcnz7lhwb32lxabgcwm3xlkzlg58";
+        sha256 = "f87a1ee673b335c28cb6ac87be61d6ef20f32dd847835c2bb7d400a00a464c7f";
       };
       urlPrefix = mirror://debian;
       packages = commonDebianPackages;
     };
 
     debian8x86_64 = {
-      name = "debian-8.4-jessie-amd64";
-      fullName = "Debian 8.4 Jessie (amd64)";
+      name = "debian-8.5-jessie-amd64";
+      fullName = "Debian 8.5 Jessie (amd64)";
       packagesList = fetchurl {
         url = mirror://debian/dists/jessie/main/binary-amd64/Packages.xz;
-        sha256 = "0kipisyjkhczghzqj4a8y1n4az9c4c8lsj8sw7js13b053lpj6ga";
+        sha256 = "df6aea15d5547ae8dc6d7ceadc8bf6499bc5a3907d13231f811bf3c1c22474ef";
       };
       urlPrefix = mirror://debian;
       packages = commonDebianPackages;
@@ -1879,7 +1916,6 @@ rec {
     "patch"
     "perl"
     "pkgconfig"
-    "procps"
     "rpm"
     "rpm-build"
     "tar"
diff --git a/pkgs/build-support/vm/windows/controller/default.nix b/pkgs/build-support/vm/windows/controller/default.nix
index 1c8e6af83b86..06a0a2293064 100644
--- a/pkgs/build-support/vm/windows/controller/default.nix
+++ b/pkgs/build-support/vm/windows/controller/default.nix
@@ -71,8 +71,6 @@ let
     };
   };
 
-  shellEscape = x: "'${replaceChars ["'"] [("'\\'" + "'")] x}'";
-
   loopForever = "while :; do ${coreutils}/bin/sleep 1; done";
 
   initScript = writeScript "init.sh" (''
@@ -132,7 +130,7 @@ let
       -o StrictHostKeyChecking=no \
       -i /ssh.key \
       -l Administrator \
-      192.168.0.1 -- ${shellEscape command}
+      192.168.0.1 -- ${lib.escapeShellArg command}
   '') + optionalString (suspendTo != null) ''
     ${coreutils}/bin/touch /xchg/suspend_now
     ${loopForever}