about summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2018-02-22 17:28:51 +0100
committerEelco Dolstra <edolstra@gmail.com>2018-02-22 17:28:51 +0100
commitd12c9911dfcb336243c9d13b8bc7042be3f3d4b2 (patch)
treeb689c775feef38ad8c315999e0a761dfa694eb1e /pkgs/build-support
parentfab12188b855d9ac1f64f486ee38f1cf7d53c8f4 (diff)
parent186c76539855a8d1a3e76af0ff95b5de50aa48f8 (diff)
Merge remote-tracking branch 'origin/master' into nix-2.0
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/bintools-wrapper/default.nix1
-rw-r--r--pkgs/build-support/build-bazel-package/default.nix78
-rw-r--r--pkgs/build-support/docker/default.nix2
-rw-r--r--pkgs/build-support/emacs/buffer.nix3
-rw-r--r--pkgs/build-support/fetchurl/default.nix33
-rw-r--r--pkgs/build-support/kernel/modules-closure.nix4
-rw-r--r--pkgs/build-support/kernel/modules-closure.sh9
-rw-r--r--pkgs/build-support/release/debian-build.nix2
-rw-r--r--pkgs/build-support/rust/build-rust-crate.nix297
-rw-r--r--pkgs/build-support/rust/carnix.nix16
-rw-r--r--pkgs/build-support/rust/default-crate-overrides.nix11
-rw-r--r--pkgs/build-support/rust/default.nix30
-rw-r--r--pkgs/build-support/setup-hooks/auto-patchelf.sh174
-rw-r--r--pkgs/build-support/setup-hooks/gog-unpack.sh11
-rw-r--r--pkgs/build-support/vm/default.nix1
15 files changed, 518 insertions, 154 deletions
diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix
index bb0e6b82aa5d3..48fd8665cb47d 100644
--- a/pkgs/build-support/bintools-wrapper/default.nix
+++ b/pkgs/build-support/bintools-wrapper/default.nix
@@ -51,6 +51,7 @@ let
   # shell glob that ought to match it.
   dynamicLinker =
     /**/ if libc == null then null
+    else if targetPlatform.libc == "musl"             then "${libc_lib}/lib/ld-musl-*"
     else if targetPlatform.system == "i686-linux"     then "${libc_lib}/lib/ld-linux.so.2"
     else if targetPlatform.system == "x86_64-linux"   then "${libc_lib}/lib/ld-linux-x86-64.so.2"
     # ARM with a wildcard, which can be "" or "-armhf".
diff --git a/pkgs/build-support/build-bazel-package/default.nix b/pkgs/build-support/build-bazel-package/default.nix
new file mode 100644
index 0000000000000..349a7e5aa333b
--- /dev/null
+++ b/pkgs/build-support/build-bazel-package/default.nix
@@ -0,0 +1,78 @@
+{ stdenv, bazel }:
+
+args@{ name, bazelFlags ? [], bazelTarget, buildAttrs, fetchAttrs, ... }:
+
+let
+  fArgs = removeAttrs args [ "buildAttrs" "fetchAttrs" ];
+  fBuildAttrs = fArgs // buildAttrs;
+  fFetchAttrs = fArgs // removeAttrs fetchAttrs [ "sha256" ];
+
+in stdenv.mkDerivation (fBuildAttrs // {
+  inherit name bazelFlags bazelTarget;
+
+  deps = stdenv.mkDerivation (fFetchAttrs // {
+    name = "${name}-deps";
+    inherit bazelFlags bazelTarget;
+
+    nativeBuildInputs = fFetchAttrs.nativeBuildInputs or [] ++ [ bazel ];
+
+    preHook = fFetchAttrs.preHook or "" + ''
+      export bazelOut="$NIX_BUILD_TOP/output"
+      export HOME="$NIX_BUILD_TOP"
+    '';
+
+    buildPhase = fFetchAttrs.buildPhase or ''
+      runHook preBuild
+
+      bazel --output_base="$bazelOut" fetch $bazelFlags $bazelTarget
+
+      runHook postBuild
+    '';
+
+    installPhase = fFetchAttrs.installPhase or ''
+      runHook preInstall
+
+      # Patching markers to make them deterministic
+      for i in $bazelOut/external/\@*.marker; do
+        sed -i 's, -\?[0-9][0-9]*$, 1,' "$i"
+      done
+      # Patching symlinks to remove build directory reference
+      find $bazelOut/external -type l | while read symlink; do
+        ln -sf $(readlink "$symlink" | sed "s,$NIX_BUILD_TOP,NIX_BUILD_TOP,") "$symlink"
+      done
+
+      cp -r $bazelOut/external $out
+
+      runHook postInstall
+    '';
+
+    dontFixup = true;
+    outputHashMode = "recursive";
+    outputHashAlgo = "sha256";
+    outputHash = fetchAttrs.sha256;
+  });
+
+  nativeBuildInputs = fBuildAttrs.nativeBuildInputs or [] ++ [ (bazel.override { enableNixHacks = true; }) ];
+
+  preHook = fBuildAttrs.preHook or "" + ''
+    export bazelOut="$NIX_BUILD_TOP/output"
+    export HOME="$NIX_BUILD_TOP"
+  '';
+
+  preConfigure = ''
+    mkdir -p $bazelOut/external
+    cp -r $deps/* $bazelOut/external
+    chmod -R +w $bazelOut
+    find $bazelOut -type l | while read symlink; do
+      ln -sf $(readlink "$symlink" | sed "s,NIX_BUILD_TOP,$NIX_BUILD_TOP,") "$symlink"
+    done
+  '' + fBuildAttrs.preConfigure or "";
+
+  buildPhase = fBuildAttrs.buildPhase or ''
+    runHook preBuild
+
+    bazel --output_base="$bazelOut" build -j $NIX_BUILD_CORES $bazelFlags $bazelTarget
+
+    runHook postBuild
+  '';
+})
diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix
index 68b803f6e3ccf..c40b096e20886 100644
--- a/pkgs/build-support/docker/default.nix
+++ b/pkgs/build-support/docker/default.nix
@@ -476,8 +476,6 @@ rec {
         cp ${layer}/* temp/
         chmod ug+w temp/*
 
-        echo "$(dirname ${storeDir})" >> layerFiles
-        echo '${storeDir}' >> layerFiles
         for dep in $(cat $layerClosure); do
           find $dep >> layerFiles
         done
diff --git a/pkgs/build-support/emacs/buffer.nix b/pkgs/build-support/emacs/buffer.nix
index 75e660d021436..550163ddd6966 100644
--- a/pkgs/build-support/emacs/buffer.nix
+++ b/pkgs/build-support/emacs/buffer.nix
@@ -4,7 +4,8 @@
 { lib, writeText, inherit-local }:
 
 rec {
-  withPackages = pkgs: let
+  withPackages = pkgs': let
+      pkgs = builtins.filter (x: x != null) pkgs';
       extras = map (x: x.emacsBufferSetup pkgs) (builtins.filter (builtins.hasAttr "emacsBufferSetup") pkgs);
     in writeText "dir-locals.el" ''
       (require 'inherit-local "${inherit-local}/share/emacs/site-lisp/elpa/inherit-local-${inherit-local.version}/inherit-local.elc")
diff --git a/pkgs/build-support/fetchurl/default.nix b/pkgs/build-support/fetchurl/default.nix
index 3e47d4a4b6837..0bf529caa75ec 100644
--- a/pkgs/build-support/fetchurl/default.nix
+++ b/pkgs/build-support/fetchurl/default.nix
@@ -1,4 +1,4 @@
-{ stdenvNoCC, curl }: # Note that `curl' may be `null', in case of the native stdenvNoCC.
+{ lib, stdenvNoCC, curl }: # Note that `curl' may be `null', in case of the native stdenvNoCC.
 
 let
 
@@ -20,7 +20,7 @@ let
   # "gnu", etc.).
   sites = builtins.attrNames mirrors;
 
-  impureEnvVars = stdenvNoCC.lib.fetchers.proxyImpureEnvVars ++ [
+  impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
     # This variable allows the user to pass additional options to curl
     "NIX_CURL_FLAGS"
 
@@ -89,22 +89,28 @@ in
 , passthru ? {}
 }:
 
-assert builtins.isList urls;
-assert (urls == []) != (url == "");
 assert sha512 != "" -> builtins.compareVersions "1.11" builtins.nixVersion <= 0;
 
-
 let
 
-  hasHash = showURLs || (outputHash != "" && outputHashAlgo != "")
-    || sha1 != "" || sha256 != "" || sha512 != "";
-  urls_ = if urls != [] then urls else [url];
+  urls_ =
+    if urls != [] && url == "" then
+      (if lib.isList urls then urls
+       else throw "`urls` is not a list")
+    else if urls == [] && url != "" then [url]
+    else throw "fetchurl requires either `url` or `urls` to be set";
+
+  hash_ =
+    if md5 != "" then throw "fetchurl does not support md5 anymore, please use sha256 or sha512"
+    else if (outputHash != "" && outputHashAlgo != "") then { inherit outputHashAlgo outputHash; }
+    else if sha512 != "" then { outputHashAlgo = "sha512"; outputHash = sha512; }
+    else if sha256 != "" then { outputHashAlgo = "sha256"; outputHash = sha256; }
+    else if sha1   != "" then { outputHashAlgo = "sha1";   outputHash = sha1; }
+    else throw "fetchurl requires a hash for fixed-output derivation: ${lib.concatStringsSep ", " urls_}";
 
 in
 
-if md5 != "" then throw "fetchurl does not support md5 anymore, please use sha256 or sha512"
-else if (!hasHash) then throw "Specify hash for fetchurl fixed-output derivation: ${stdenvNoCC.lib.concatStringsSep ", " urls_}"
-else stdenvNoCC.mkDerivation {
+stdenvNoCC.mkDerivation {
   name =
     if showURLs then "urls"
     else if name != "" then name
@@ -121,10 +127,7 @@ else stdenvNoCC.mkDerivation {
   preferHashedMirrors = true;
 
   # New-style output content requirements.
-  outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else
-      if sha512 != "" then "sha512" else if sha256 != "" then "sha256" else "sha1";
-  outputHash = if outputHash != "" then outputHash else
-      if sha512 != "" then sha512 else if sha256 != "" then sha256 else sha1;
+  inherit (hash_) outputHashAlgo outputHash;
 
   outputHashMode = if (recursiveHash || executable) then "recursive" else "flat";
 
diff --git a/pkgs/build-support/kernel/modules-closure.nix b/pkgs/build-support/kernel/modules-closure.nix
index 9940e611124c9..a527770adcd7b 100644
--- a/pkgs/build-support/kernel/modules-closure.nix
+++ b/pkgs/build-support/kernel/modules-closure.nix
@@ -3,13 +3,13 @@
 # the modules identified by `rootModules', plus their dependencies.
 # Also generate an appropriate modules.dep.
 
-{ stdenvNoCC, kernel, nukeReferences, rootModules
+{ stdenvNoCC, kernel, firmware, nukeReferences, rootModules
 , kmod, allowMissing ? false }:
 
 stdenvNoCC.mkDerivation {
   name = kernel.name + "-shrunk";
   builder = ./modules-closure.sh;
   buildInputs = [ nukeReferences kmod ];
-  inherit kernel rootModules allowMissing;
+  inherit kernel firmware rootModules allowMissing;
   allowedReferences = ["out"];
 }
diff --git a/pkgs/build-support/kernel/modules-closure.sh b/pkgs/build-support/kernel/modules-closure.sh
index 8a31c760da07a..8287c1672d062 100644
--- a/pkgs/build-support/kernel/modules-closure.sh
+++ b/pkgs/build-support/kernel/modules-closure.sh
@@ -33,4 +33,13 @@ for module in $closure; do
     echo $target >> $out/insmod-list
 done
 
+mkdir -p $out/lib/firmware
+for module in $closure; do
+    for i in $(modinfo -F firmware $module); do
+        mkdir -p "$out/lib/firmware/$(dirname "$i")"
+        echo "firmware for $module: $i"
+        cp "$firmware/lib/firmware/$i" "$out/lib/firmware/$i" 2>/dev/null || if test -z "$allowMissing"; then exit 1; fi
+    done
+done
+
 depmod -b $out -a $version
diff --git a/pkgs/build-support/release/debian-build.nix b/pkgs/build-support/release/debian-build.nix
index f4bc3e73056dc..354d929c9b652 100644
--- a/pkgs/build-support/release/debian-build.nix
+++ b/pkgs/build-support/release/debian-build.nix
@@ -78,10 +78,10 @@ vmTools.runInLinuxImage (stdenv.mkDerivation (
         header "Generated DEB package: $i"
         dpkg-deb --info "$i"
         pkgName=$(dpkg-deb -W "$i" | awk '{print $1}')
-        dpkg -i "$i"
         echo "file deb $i" >> $out/nix-support/hydra-build-products
         stopNest
       done
+      dpkg -i $out/debs/*.deb
 
       for i in $extraDebs; do
         echo "file deb-extra $(ls $i/debs/*.deb | sort | head -1)" >> $out/nix-support/hydra-build-products
diff --git a/pkgs/build-support/rust/build-rust-crate.nix b/pkgs/build-support/rust/build-rust-crate.nix
index e36fab36bf975..8a9a07fd7a8ff 100644
--- a/pkgs/build-support/rust/build-rust-crate.nix
+++ b/pkgs/build-support/rust/build-rust-crate.nix
@@ -6,44 +6,16 @@
 
 { lib, buildPlatform, stdenv, defaultCrateOverrides, fetchCrate, ncurses, rustc  }:
 
-let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
-                   dependencies, completeDeps, completeBuildDeps,
-                   crateFeatures, libName, build, release, libPath,
-                   crateType, metadata, crateBin, finalBins,
-                   verbose, colors }:
-
-      let depsDir = lib.concatStringsSep " " dependencies;
-          completeDepsDir = lib.concatStringsSep " " completeDeps;
-          completeBuildDepsDir = lib.concatStringsSep " " completeBuildDeps;
-          makeDeps = dependencies:
-            (lib.concatMapStringsSep " " (dep:
-              let extern = lib.strings.replaceStrings ["-"] ["_"] dep.libName; in
-              (if dep.crateType == "lib" then
-                 " --extern ${extern}=${dep.out}/lib/lib${extern}-${dep.metadata}.rlib"
-              else
-                 " --extern ${extern}=${dep.out}/lib/lib${extern}-${dep.metadata}${buildPlatform.extensions.sharedLibrary}")
-            ) dependencies);
-          deps = makeDeps dependencies;
-          buildDeps = makeDeps buildDependencies;
-          optLevel = if release then 3 else 0;
-          rustcOpts = (if release then "-C opt-level=3" else "-C debuginfo=2");
-          rustcMeta = "-C metadata=${metadata} -C extra-filename=-${metadata}";
-          version_ = lib.splitString "-" crateVersion;
-          versionPre = if lib.tail version_ == [] then "" else builtins.elemAt version_ 1;
-          version = lib.splitString "." (lib.head version_);
-          authors = lib.concatStringsSep ":" crateAuthors;
-      in ''
-      norm=""
-      bold=""
-      green=""
-      boldgreen=""
-      if [[ "${colors}" -eq "always" ]]; then
-        norm="$(printf '\033[0m')" #returns to "normal"
-        bold="$(printf '\033[0;1m')" #set bold
-        green="$(printf '\033[0;32m')" #set green
-        boldgreen="$(printf '\033[0;1;32m')" #set bold, and set green.
-      fi
-
+let makeDeps = dependencies:
+      (lib.concatMapStringsSep " " (dep:
+        let extern = lib.strings.replaceStrings ["-"] ["_"] dep.libName; in
+        (if dep.crateType == "lib" then
+           " --extern ${extern}=${dep.out}/lib/lib${extern}-${dep.metadata}.rlib"
+         else
+           " --extern ${extern}=${dep.out}/lib/lib${extern}-${dep.metadata}${buildPlatform.extensions.sharedLibrary}")
+      ) dependencies);
+
+    echo_build_heading = colors: ''
       echo_build_heading() {
        start=""
        end=""
@@ -57,7 +29,8 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
          echo "$start""Building $1 ($2)""$end"
        fi
       }
-
+    '';
+    noisily = colors: verbose: ''
       noisily() {
         start=""
         end=""
@@ -71,18 +44,29 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
 	''}
 	$@
       }
+    '';
 
+    configureCrate =
+      { crateName, crateVersion, crateAuthors, build, libName, crateFeatures, colors, libPath, release, buildDependencies, completeDeps, completeBuildDeps, verbose, dependencies }:
+      let version_ = lib.splitString "-" crateVersion;
+          versionPre = if lib.tail version_ == [] then "" else builtins.elemAt version_ 1;
+          version = lib.splitString "." (lib.head version_);
+          rustcOpts = (if release then "-C opt-level=3" else "-C debuginfo=2");
+          buildDeps = makeDeps buildDependencies;
+          authors = lib.concatStringsSep ":" crateAuthors;
+          optLevel = if release then 3 else 0;
+          completeDepsDir = lib.concatStringsSep " " completeDeps;
+          completeBuildDepsDir = lib.concatStringsSep " " completeBuildDeps;
+      in ''
+      runHook preConfigure
+      ${echo_build_heading colors}
+      ${noisily colors verbose}
       symlink_dependency() {
-      # $1 is the nix-store path of a dependency
+        # $1 is the nix-store path of a dependency
+        # $2 is the target path
         i=$1
-	dest=target/deps
-	if [ ! -z $2 ]; then
-           if [ "$2" = "--buildDep" ]; then
-             dest=target/buildDeps
-           fi
-	fi
-        ln -s -f $i/lib/*.rlib $dest #*/
-        ln -s -f $i/lib/*.so $i/lib/*.dylib $dest #*/
+        ln -s -f $i/lib/*.rlib $2 #*/
+        ln -s -f $i/lib/*.so $i/lib/*.dylib $2 #*/
         if [ -e "$i/lib/link" ]; then
             cat $i/lib/link >> target/link
             cat $i/lib/link >> target/link.final
@@ -92,48 +76,15 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
         fi
       }
 
-      build_lib() {
-         lib_src=$1
-         echo_build_heading $lib_src ${libName}
-
-         noisily rustc --crate-name $CRATE_NAME $lib_src --crate-type ${crateType} \
-           ${rustcOpts} ${rustcMeta} ${crateFeatures} --out-dir target/lib \
-           --emit=dep-info,link -L dependency=target/deps ${deps} --cap-lints allow \
-           $BUILD_OUT_DIR $EXTRA_BUILD $EXTRA_FEATURES --color ${colors}
-
-         EXTRA_LIB=" --extern $CRATE_NAME=target/lib/lib$CRATE_NAME-${metadata}.rlib"
-         if [ -e target/deps/lib$CRATE_NAME-${metadata}${buildPlatform.extensions.sharedLibrary} ]; then
-            EXTRA_LIB="$EXTRA_LIB --extern $CRATE_NAME=target/lib/lib$CRATE_NAME-${metadata}${buildPlatform.extensions.sharedLibrary}"
-         fi
-      }
-
-      build_bin() {
-        crate_name=$1
-        crate_name_=$(echo $crate_name | sed -e "s/-/_/g")
-	main_file=""
-	if [[ ! -z $2 ]]; then
-          main_file=$2
-	fi
-	echo_build_heading $@
-	noisily rustc --crate-name $crate_name_ $main_file --crate-type bin ${rustcOpts}\
-          ${crateFeatures} --out-dir target/bin --emit=dep-info,link -L dependency=target/deps \
-          $LINK ${deps}$EXTRA_LIB --cap-lints allow \
-          $BUILD_OUT_DIR $EXTRA_BUILD $EXTRA_FEATURES --color ${colors}
-        if [ "$crate_name_" -ne "$crate_name" ]; then
-          mv target/bin/$crate_name_ target/bin/$crate_name
-        fi
-      }
-
-      runHook preBuild
       mkdir -p target/{deps,lib,build,buildDeps}
       chmod uga+w target -R
       for i in ${completeDepsDir}; do
-        symlink_dependency $i
+        symlink_dependency $i target/deps
       done
       for i in ${completeBuildDepsDir}; do
-         symlink_dependency $i --buildDep
+         symlink_dependency $i target/buildDeps
       done
-      if [ -e target/link ]; then
+      if [[ -e target/link ]]; then
         sort -u target/link > target/link.sorted
         mv target/link.sorted target/link
         sort -u target/link.final > target/link.final.sorted
@@ -145,10 +96,16 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
       export CARGO_PKG_NAME=${crateName}
       export CARGO_PKG_VERSION=${crateVersion}
       export CARGO_PKG_AUTHORS="${authors}"
+
       export CARGO_CFG_TARGET_ARCH=${buildPlatform.parsed.cpu.name}
       export CARGO_CFG_TARGET_OS=${buildPlatform.parsed.kernel.name}
-
+      export CARGO_CFG_TARGET_FAMILY="unix"
+      export CARGO_CFG_UNIX=1
       export CARGO_CFG_TARGET_ENV="gnu"
+      export CARGO_CFG_TARGET_ENDIAN=${if buildPlatform.parsed.cpu.significantByte.name == "littleEndian" then "little" else "big"}
+      export CARGO_CFG_TARGET_POINTER_WIDTH=${toString buildPlatform.parsed.cpu.bits}
+      export CARGO_CFG_TARGET_VENDOR=${buildPlatform.parsed.vendor.name}
+
       export CARGO_MANIFEST_DIR="."
       export DEBUG="${toString (!release)}"
       export OPT_LEVEL="${toString optLevel}"
@@ -159,7 +116,7 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
       export CARGO_PKG_VERSION_MAJOR=${builtins.elemAt version 0}
       export CARGO_PKG_VERSION_MINOR=${builtins.elemAt version 1}
       export CARGO_PKG_VERSION_PATCH=${builtins.elemAt version 2}
-      if [ -n "${versionPre}" ]; then
+      if [[ -n "${versionPre}" ]]; then
         export CARGO_PKG_VERSION_PRE="${versionPre}"
       fi
 
@@ -180,8 +137,8 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
            EXTRA_BUILD_FLAGS="$EXTRA_BUILD_FLAGS $(cat target/link.build)"
          fi
          noisily rustc --crate-name build_script_build $BUILD --crate-type bin ${rustcOpts} \
-          ${crateFeatures} --out-dir target/build/${crateName} --emit=dep-info,link \
-          -L dependency=target/buildDeps ${buildDeps} --cap-lints allow $EXTRA_BUILD_FLAGS --color ${colors}
+           ${crateFeatures} --out-dir target/build/${crateName} --emit=dep-info,link \
+           -L dependency=target/buildDeps ${buildDeps} --cap-lints allow $EXTRA_BUILD_FLAGS --color ${colors}
 
          mkdir -p target/build/${crateName}.out
          export RUST_BACKTRACE=1
@@ -198,33 +155,104 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
            | sed -e "s/cargo:\([^=]*\)=\(.*\)/export DEP_$(echo $CRATENAME)_\U\1\E=\2/" > target/env
 
          set -e
-         if [ -n "$(ls target/build/${crateName}.out)" ]; then
+         if [[ -n "$(ls target/build/${crateName}.out)" ]]; then
 
-            if [ -e "${libPath}" ] ; then
+            if [[ -e "${libPath}" ]]; then
                cp -r target/build/${crateName}.out/* $(dirname ${libPath}) #*/
             else
                cp -r target/build/${crateName}.out/* src #*/
             fi
          fi
       fi
+      runHook postConfigure
+    '';
+
+    buildCrate = { crateName, crateVersion, crateAuthors,
+                   dependencies, completeDeps, completeBuildDeps,
+                   crateFeatures, libName, build, release, libPath,
+                   crateType, metadata, crateBin, finalBins,
+                   extraRustcOpts,
+                   verbose, colors }:
+
+      let depsDir = lib.concatStringsSep " " dependencies;
+          completeDepsDir = lib.concatStringsSep " " completeDeps;
+          completeBuildDepsDir = lib.concatStringsSep " " completeBuildDeps;
+          deps = makeDeps dependencies;
+          optLevel = if release then 3 else 0;
+          rustcOpts =
+            lib.lists.foldl' (opts: opt: opts + " " + opt)
+              (if release then "-C opt-level=3" else "-C debuginfo=2")
+              extraRustcOpts;
+          rustcMeta = "-C metadata=${metadata} -C extra-filename=-${metadata}";
+          version_ = lib.splitString "-" crateVersion;
+          versionPre = if lib.tail version_ == [] then "" else builtins.elemAt version_ 1;
+          version = lib.splitString "." (lib.head version_);
+          authors = lib.concatStringsSep ":" crateAuthors;
+      in ''
+      runHook preBuild
+      norm=""
+      bold=""
+      green=""
+      boldgreen=""
+      if [[ "${colors}" -eq "always" ]]; then
+        norm="$(printf '\033[0m')" #returns to "normal"
+        bold="$(printf '\033[0;1m')" #set bold
+        green="$(printf '\033[0;32m')" #set green
+        boldgreen="$(printf '\033[0;1;32m')" #set bold, and set green.
+      fi
+      ${echo_build_heading colors}
+      ${noisily colors verbose}
+
+      build_lib() {
+         lib_src=$1
+         echo_build_heading $lib_src ${libName}
+
+         noisily rustc --crate-name $CRATE_NAME $lib_src --crate-type ${crateType} \
+           ${rustcOpts} ${rustcMeta} ${crateFeatures} --out-dir target/lib \
+           --emit=dep-info,link -L dependency=target/deps ${deps} --cap-lints allow \
+           $BUILD_OUT_DIR $EXTRA_BUILD $EXTRA_FEATURES --color ${colors}
+
+         EXTRA_LIB=" --extern $CRATE_NAME=target/lib/lib$CRATE_NAME-${metadata}.rlib"
+         if [ -e target/deps/lib$CRATE_NAME-${metadata}${buildPlatform.extensions.sharedLibrary} ]; then
+            EXTRA_LIB="$EXTRA_LIB --extern $CRATE_NAME=target/lib/lib$CRATE_NAME-${metadata}${buildPlatform.extensions.sharedLibrary}"
+         fi
+      }
+
+      build_bin() {
+        crate_name=$1
+        crate_name_=$(echo $crate_name | sed -e "s/-/_/g")
+	main_file=""
+	if [[ ! -z $2 ]]; then
+          main_file=$2
+	fi
+	echo_build_heading $@
+	noisily rustc --crate-name $crate_name_ $main_file --crate-type bin ${rustcOpts}\
+          ${crateFeatures} --out-dir target/bin --emit=dep-info,link -L dependency=target/deps \
+          $LINK ${deps}$EXTRA_LIB --cap-lints allow \
+          $BUILD_OUT_DIR $EXTRA_BUILD $EXTRA_FEATURES --color ${colors}
+        if [ "$crate_name_" -ne "$crate_name" ]; then
+          mv target/bin/$crate_name_ target/bin/$crate_name
+        fi
+      }
+
 
       EXTRA_LIB=""
       CRATE_NAME=$(echo ${libName} | sed -e "s/-/_/g")
 
-      if [ -e target/link_ ]; then
+      if [[ -e target/link_ ]]; then
         EXTRA_BUILD="$(cat target/link_) $EXTRA_BUILD"
       fi
 
-      if [ -e "${libPath}" ] ; then
+      if [[ -e "${libPath}" ]]; then
          build_lib ${libPath}
-      elif [ -e src/lib.rs ] ; then
+      elif [[ -e src/lib.rs ]]; then
          build_lib src/lib.rs
-      elif [ -e src/${libName}.rs ] ; then
+      elif [[ -e src/${libName}.rs ]]; then
          build_lib src/${libName}.rs
       fi
 
       echo "$EXTRA_LINK_SEARCH" | while read i; do
-         if [ ! -z "$i" ]; then
+         if [[ ! -z "$i" ]]; then
            for lib in $i; do
              echo "-L $lib" >> target/link
              L=$(echo $lib | sed -e "s#$(pwd)/target/build#$out/lib#")
@@ -233,7 +261,7 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
          fi
       done
       echo "$EXTRA_LINK" | while read i; do
-         if [ ! -z "$i" ]; then
+         if [[ ! -z "$i" ]]; then
            for lib in $i; do
              echo "-l $lib" >> target/link
              echo "-l $lib" >> target/link.final
@@ -241,7 +269,7 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
          fi
       done
 
-      if [ -e target/link ]; then
+      if [[ -e target/link ]]; then
          sort -u target/link.final > target/link.final.sorted
          mv target/link.final.sorted target/link.final
          sort -u target/link > target/link.sorted
@@ -253,7 +281,7 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
 
       mkdir -p target/bin
       echo "${crateBin}" | sed -n 1'p' | tr ',' '\n' | while read BIN; do
-         if [ ! -z "$BIN" ]; then
+         if [[ ! -z "$BIN" ]]; then
            build_bin $BIN
          fi
       done
@@ -267,36 +295,49 @@ let buildCrate = { crateName, crateVersion, crateAuthors, buildDependencies,
       ''}
       # Remove object files to avoid "wrong ELF type"
       find target -type f -name "*.o" -print0 | xargs -0 rm -f
+    '' + finalBins + ''
       runHook postBuild
-    '' + finalBins;
+    '';
 
-    installCrate = crateName: ''
+    installCrate = crateName: metadata: ''
+      runHook preInstall
       mkdir -p $out
-      if [ -s target/env ]; then
+      if [[ -s target/env ]]; then
         cp target/env $out/env
       fi
-      if [ -s target/link.final ]; then
+      if [[ -s target/link.final ]]; then
         mkdir -p $out/lib
         cp target/link.final $out/lib/link
       fi
-      if [ "$(ls -A target/lib)" ]; then
+      if [[ "$(ls -A target/lib)" ]]; then
         mkdir -p $out/lib
         cp target/lib/* $out/lib #*/
+        for lib in $out/lib/*.so $out/lib/*.dylib; do #*/
+          ln -s $lib $(echo $lib | sed -e "s/-${metadata}//")
+        done
       fi
-      if [ "$(ls -A target/build)" ]; then # */
+      if [[ "$(ls -A target/build)" ]]; then # */
         mkdir -p $out/lib
         cp -r target/build/* $out/lib # */
       fi
-      if [ "$(ls -A target/bin)" ]; then
+      if [[ "$(ls -A target/bin)" ]]; then
         mkdir -p $out/bin
         cp -P target/bin/* $out/bin # */
       fi
+      runHook postInstall
     '';
 in
 
-crate_: lib.makeOverridable ({ rust, release, verbose, features, buildInputs, crateOverrides }:
+crate_: lib.makeOverridable ({ rust, release, verbose, features, buildInputs, crateOverrides,
+  dependencies, buildDependencies,
+  extraRustcOpts,
+  preUnpack, postUnpack, prePatch, patches, postPatch,
+  preConfigure, postConfigure, preBuild, postBuild, preInstall, postInstall }:
 
 let crate = crate_ // (lib.attrByPath [ crate_.crateName ] (attr: {}) crateOverrides crate_);
+    release_ = release;
+    dependencies_ = dependencies;
+    buildDependencies_ = buildDependencies;
     processedAttrs = [
       "src" "buildInputs" "crateBin" "crateLib" "libName" "libPath"
       "buildDependencies" "dependencies" "features"
@@ -308,6 +349,7 @@ in
 stdenv.mkDerivation (rec {
 
     inherit (crate) crateName;
+    inherit preUnpack postUnpack prePatch patches postPatch preConfigure postConfigure preBuild postBuild preInstall postInstall;
 
     src = if lib.hasAttr "src" crate then
         crate.src
@@ -318,12 +360,12 @@ stdenv.mkDerivation (rec {
     dependencies =
       builtins.map
         (dep: dep.override { rust = rust; release = release; verbose = verbose; crateOverrides = crateOverrides; })
-        (crate.dependencies or []);
+        dependencies_;
 
     buildDependencies =
       builtins.map
         (dep: dep.override { rust = rust; release = release; verbose = verbose; crateOverrides = crateOverrides; })
-        (crate.buildDependencies or []);
+        buildDependencies_;
 
     completeDeps = lib.lists.unique (dependencies ++ lib.lists.concatMap (dep: dep.completeDeps) dependencies);
     completeBuildDeps = lib.lists.unique (
@@ -338,7 +380,8 @@ stdenv.mkDerivation (rec {
     libName = if crate ? libName then crate.libName else crate.crateName;
     libPath = if crate ? libPath then crate.libPath else "";
 
-    metadata = builtins.substring 0 10 (builtins.hashString "sha256" (crateName + "-" + crateVersion));
+    depsMetadata = builtins.foldl' (str: dep: str + dep.metadata) "" (dependencies ++ buildDependencies);
+    metadata = builtins.substring 0 10 (builtins.hashString "sha256" (crateName + "-" + crateVersion + "___" + toString crateFeatures + "___" + depsMetadata ));
 
     crateBin = if crate ? crateBin then
        builtins.foldl' (bins: bin:
@@ -369,20 +412,42 @@ stdenv.mkDerivation (rec {
     crateAuthors = if crate ? authors && lib.isList crate.authors then crate.authors else [];
     crateType =
       if lib.attrByPath ["procMacro"] false crate then "proc-macro" else
-      if lib.attrByPath ["plugin"] false crate then "dylib" else "lib";
+      if lib.attrByPath ["plugin"] false crate then "dylib" else
+      if crate ? type then crate.type else "lib";
     colors = lib.attrByPath [ "colors" ] "always" crate;
-    buildPhase = buildCrate {
+    configurePhase = configureCrate {
       inherit crateName dependencies buildDependencies completeDeps completeBuildDeps
+              crateFeatures libName build release libPath crateVersion
+              crateAuthors verbose colors;
+    };
+    extraRustcOpts = if crate ? extraRustcOpts then crate.extraRustcOpts else [];
+    buildPhase = buildCrate {
+      inherit crateName dependencies completeDeps completeBuildDeps
               crateFeatures libName build release libPath crateType crateVersion
-              crateAuthors metadata crateBin finalBins verbose colors;
+              crateAuthors metadata crateBin finalBins verbose colors extraRustcOpts;
     };
-    installPhase = installCrate crateName;
+    installPhase = installCrate crateName metadata;
 
-} // extraDerivationAttrs)) {
+} // extraDerivationAttrs
+)) {
   rust = rustc;
-  release = true;
-  verbose = true;
+  release = crate_.release or true;
+  verbose = crate_.verbose or true;
+  extraRustcOpts = [];
   features = [];
   buildInputs = [];
   crateOverrides = defaultCrateOverrides;
+  preUnpack = crate_.preUnpack or "";
+  postUnpack = crate_.postUnpack or "";
+  prePatch = crate_.prePatch or "";
+  patches = crate_.patches or [];
+  postPatch = crate_.postPatch or "";
+  preConfigure = crate_.preConfigure or "";
+  postConfigure = crate_.postConfigure or "";
+  preBuild = crate_.preBuild or "";
+  postBuild = crate_.postBuild or "";
+  preInstall = crate_.preInstall or "";
+  postInstall = crate_.postInstall or "";
+  dependencies = crate_.dependencies or [];
+  buildDependencies = crate_.buildDependencies or [];
 }
diff --git a/pkgs/build-support/rust/carnix.nix b/pkgs/build-support/rust/carnix.nix
index 8b0af499c8f12..ebb46b0f59211 100644
--- a/pkgs/build-support/rust/carnix.nix
+++ b/pkgs/build-support/rust/carnix.nix
@@ -1,4 +1,4 @@
-# Generated by carnix 0.6.5: carnix -o carnix.nix Cargo.lock --src ./.
+# Generated by carnix 0.6.5: carnix -o carnix.nix Cargo.lock
 { lib, buildPlatform, buildRustCrate, fetchgit }:
 let kernel = buildPlatform.parsed.kernel.name;
     abi = buildPlatform.parsed.abi.name;
@@ -18,7 +18,7 @@ let kernel = buildPlatform.parsed.kernel.name;
     ) [] (builtins.attrNames feat);
 in
 rec {
-  carnix = f: carnix_0_6_5 { features = carnix_0_6_5_features { carnix_0_6_5 = f; }; };
+  carnix = f: carnix_0_6_6 { features = carnix_0_6_6_features { carnix_0_6_6 = f; }; };
   aho_corasick_0_6_3_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
     crateName = "aho-corasick";
     version = "0.6.3";
@@ -71,11 +71,11 @@ rec {
     sha256 = "0p4b3nr0s5nda2qmm7xdhnvh4lkqk3xd8l9ffmwbvqw137vx7mj1";
     inherit dependencies buildDependencies features;
   };
-  carnix_0_6_5_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
+  carnix_0_6_6_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
     crateName = "carnix";
-    version = "0.6.5";
+    version = "0.6.6";
     authors = [ "pe@pijul.org <pe@pijul.org>" ];
-    sha256 = "0r952s5az5mhw7z2r421i5lr0w5h436hah61md2bdb3204c2pl9c";
+    sha256 = "1ai2r52j6vlrclhb7cvifx3lsg9naiy3jpsrbi3mmfmr6zbi7rdw";
     inherit dependencies buildDependencies features;
   };
   cc_1_0_3_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
@@ -623,11 +623,11 @@ rec {
       (f.bitflags_1_0_1.default or false) ||
       (bitflags_1_0_1.default or false);
   }) [];
-  carnix_0_6_5 = { features?(carnix_0_6_5_features {}) }: carnix_0_6_5_ {
+  carnix_0_6_6 = { features?(carnix_0_6_6_features {}) }: carnix_0_6_6_ {
     dependencies = mapFeatures features ([ clap_2_28_0 env_logger_0_5_3 error_chain_0_11_0 itertools_0_7_3 log_0_4_1 nom_3_2_1 regex_0_2_2 rusqlite_0_13_0 serde_1_0_21 serde_derive_1_0_21 serde_json_1_0_6 tempdir_0_3_5 toml_0_4_5 ]);
   };
-  carnix_0_6_5_features = f: updateFeatures f (rec {
-    carnix_0_6_5.default = (f.carnix_0_6_5.default or true);
+  carnix_0_6_6_features = f: updateFeatures f (rec {
+    carnix_0_6_6.default = (f.carnix_0_6_6.default or true);
     clap_2_28_0.default = true;
     env_logger_0_5_3.default = true;
     error_chain_0_11_0.default = true;
diff --git a/pkgs/build-support/rust/default-crate-overrides.nix b/pkgs/build-support/rust/default-crate-overrides.nix
index 658548135aaff..346fd0e7908fd 100644
--- a/pkgs/build-support/rust/default-crate-overrides.nix
+++ b/pkgs/build-support/rust/default-crate-overrides.nix
@@ -1,5 +1,6 @@
 { stdenv, pkgconfig, curl, darwin, libiconv, libgit2, libssh2,
-  openssl, sqlite, zlib, dbus_libs, dbus_glib, gdk_pixbuf, cairo, python3, ... }:
+  openssl, sqlite, zlib, dbus_libs, dbus_glib, gdk_pixbuf, cairo, python3,
+  libsodium, postgresql, ... }:
 
 let
   inherit (darwin.apple_sdk.frameworks) CoreFoundation;
@@ -36,6 +37,7 @@ in
   openssl-sys = attrs: {
     buildInputs = [ pkgconfig openssl ];
   };
+
   dbus = attrs: {
     buildInputs = [ pkgconfig dbus_libs ];
   };
@@ -60,4 +62,11 @@ in
   xcb = attrs: {
     buildInputs = [ python3 ];
   };
+
+  thrussh-libsodium = attrs: {
+    buildInputs = [ pkgconfig libsodium ];
+  };
+  pq-sys = attr: {
+    buildInputs = [ pkgconfig postgresql ];
+  };
 }
diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix
index 63d08e1d03114..83ef146de5f8a 100644
--- a/pkgs/build-support/rust/default.nix
+++ b/pkgs/build-support/rust/default.nix
@@ -4,7 +4,7 @@ let
     inherit stdenv cacert git rust cargo-vendor;
   };
 in
-{ name, cargoSha256
+{ name, cargoSha256 ? null
 , src ? null
 , srcs ? null
 , sourceRoot ? null
@@ -13,15 +13,31 @@ in
 , cargoUpdateHook ? ""
 , cargoDepsHook ? ""
 , cargoBuildFlags ? []
+
+, cargoVendorDir ? null
 , ... } @ args:
 
+assert cargoVendorDir == null -> cargoSha256 != null;
+
 let
   lib = stdenv.lib;
 
-  cargoDeps = fetchcargo {
-    inherit name src srcs sourceRoot cargoUpdateHook;
-    sha256 = cargoSha256;
-  };
+  cargoDeps = if cargoVendorDir == null
+    then fetchcargo {
+        inherit name src srcs sourceRoot cargoUpdateHook;
+        sha256 = cargoSha256;
+      }
+    else null;
+
+  setupVendorDir = if cargoVendorDir == null
+    then ''
+      unpackFile "$cargoDeps"
+      cargoDepsCopy=$(stripHash $(basename $cargoDeps))
+      chmod -R +w "$cargoDepsCopy"
+    ''
+    else ''
+      cargoDepsCopy="$sourceRoot/${cargoVendorDir}"
+    '';
 
 in stdenv.mkDerivation (args // {
   inherit cargoDeps;
@@ -39,9 +55,7 @@ in stdenv.mkDerivation (args // {
   postUnpack = ''
     eval "$cargoDepsHook"
 
-    unpackFile "$cargoDeps"
-    cargoDepsCopy=$(stripHash $(basename $cargoDeps))
-    chmod -R +w "$cargoDepsCopy"
+    ${setupVendorDir}
 
     mkdir .cargo
     cat >.cargo/config <<-EOF
diff --git a/pkgs/build-support/setup-hooks/auto-patchelf.sh b/pkgs/build-support/setup-hooks/auto-patchelf.sh
new file mode 100644
index 0000000000000..0f9d7603d48fb
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/auto-patchelf.sh
@@ -0,0 +1,174 @@
+declare -a autoPatchelfLibs
+
+gatherLibraries() {
+    autoPatchelfLibs+=("$1/lib")
+}
+
+addEnvHooks "$targetOffset" gatherLibraries
+
+isExecutable() {
+    [ "$(file -b -N --mime-type "$1")" = application/x-executable ]
+}
+
+findElfs() {
+    find "$1" -type f -exec "$SHELL" -c '
+        while [ -n "$1" ]; do
+            mimeType="$(file -b -N --mime-type "$1")"
+            if [ "$mimeType" = application/x-executable \
+              -o "$mimeType" = application/x-sharedlib ]; then
+                echo "$1"
+            fi
+            shift
+        done
+    ' -- {} +
+}
+
+# We cache dependencies so that we don't need to search through all of them on
+# every consecutive call to findDependency.
+declare -a cachedDependencies
+
+addToDepCache() {
+    local existing
+    for existing in "${cachedDependencies[@]}"; do
+        if [ "$existing" = "$1" ]; then return; fi
+    done
+    cachedDependencies+=("$1")
+}
+
+declare -gi depCacheInitialised=0
+declare -gi doneRecursiveSearch=0
+declare -g foundDependency
+
+getDepsFromSo() {
+    ldd "$1" 2> /dev/null | sed -n -e 's/[^=]*=> *\(.\+\) \+([^)]*)$/\1/p'
+}
+
+populateCacheWithRecursiveDeps() {
+    local so found foundso
+    for so in "${cachedDependencies[@]}"; do
+        for found in $(getDepsFromSo "$so"); do
+            local libdir="${found%/*}"
+            local base="${found##*/}"
+            local soname="${base%.so*}"
+            for foundso in "${found%/*}/$soname".so*; do
+                addToDepCache "$foundso"
+            done
+        done
+    done
+}
+
+getSoArch() {
+    objdump -f "$1" | sed -ne 's/^architecture: *\([^,]\+\).*/\1/p'
+}
+
+# NOTE: If you want to use this function outside of the autoPatchelf function,
+# keep in mind that the dependency cache is only valid inside the subshell
+# spawned by the autoPatchelf function, so invoking this directly will possibly
+# rebuild the dependency cache. See the autoPatchelf function below for more
+# information.
+findDependency() {
+    local filename="$1"
+    local arch="$2"
+    local lib dep
+
+    if [ $depCacheInitialised -eq 0 ]; then
+        for lib in "${autoPatchelfLibs[@]}"; do
+            for so in "$lib/"*.so*; do addToDepCache "$so"; done
+        done
+        depCacheInitialised=1
+    fi
+
+    for dep in "${cachedDependencies[@]}"; do
+        if [ "$filename" = "${dep##*/}" ]; then
+            if [ "$(getSoArch "$dep")" = "$arch" ]; then
+                foundDependency="$dep"
+                return 0
+            fi
+        fi
+    done
+
+    # Populate the dependency cache with recursive dependencies *only* if we
+    # didn't find the right dependency so far and afterwards run findDependency
+    # again, but this time with $doneRecursiveSearch set to 1 so that it won't
+    # recurse again (and thus infinitely).
+    if [ $doneRecursiveSearch -eq 0 ]; then
+        populateCacheWithRecursiveDeps
+        doneRecursiveSearch=1
+        findDependency "$filename" "$arch" || return 1
+        return 0
+    fi
+    return 1
+}
+
+autoPatchelfFile() {
+    local dep rpath="" toPatch="$1"
+
+    local interpreter="$(< "$NIX_CC/nix-support/dynamic-linker")"
+    if isExecutable "$toPatch"; then
+        patchelf --set-interpreter "$interpreter" "$toPatch"
+        if [ -n "$runtimeDependencies" ]; then
+            for dep in $runtimeDependencies; do
+                rpath="$rpath${rpath:+:}$dep/lib"
+            done
+        fi
+    fi
+
+    echo "searching for dependencies of $toPatch" >&2
+
+    # We're going to find all dependencies based on ldd output, so we need to
+    # clear the RPATH first.
+    patchelf --remove-rpath "$toPatch"
+
+    local missing="$(
+        ldd "$toPatch" 2> /dev/null | \
+            sed -n -e 's/^[\t ]*\([^ ]\+\) => not found.*/\1/p'
+    )"
+
+    # This ensures that we get the output of all missing dependencies instead
+    # of failing at the first one, because it's more useful when working on a
+    # new package where you don't yet know its dependencies.
+    local -i depNotFound=0
+
+    for dep in $missing; do
+        echo -n "  $dep -> " >&2
+        if findDependency "$dep" "$(getSoArch "$toPatch")"; then
+            rpath="$rpath${rpath:+:}${foundDependency%/*}"
+            echo "found: $foundDependency" >&2
+        else
+            echo "not found!" >&2
+            depNotFound=1
+        fi
+    done
+
+    # This makes sure the builder fails if we didn't find a dependency, because
+    # the stdenv setup script is run with set -e. The actual error is emitted
+    # earlier in the previous loop.
+    [ $depNotFound -eq 0 ]
+
+    if [ -n "$rpath" ]; then
+        echo "setting RPATH to: $rpath" >&2
+        patchelf --set-rpath "$rpath" "$toPatch"
+    fi
+}
+
+autoPatchelf() {
+    echo "automatically fixing dependencies for ELF files" >&2
+
+    # Add all shared objects of the current output path to the start of
+    # cachedDependencies so that it's choosen first in findDependency.
+    cachedDependencies+=(
+        $(find "$prefix" \! -type d \( -name '*.so' -o -name '*.so.*' \))
+    )
+    local elffile
+
+    # Here we actually have a subshell, which also means that
+    # $cachedDependencies is final at this point, so whenever we want to run
+    # findDependency outside of this, the dependency cache needs to be rebuilt
+    # from scratch, so keep this in mind if you want to run findDependency
+    # outside of this function.
+    findElfs "$prefix" | while read -r elffile; do
+        autoPatchelfFile "$elffile"
+    done
+}
+
+fixupOutputHooks+=(autoPatchelf)
diff --git a/pkgs/build-support/setup-hooks/gog-unpack.sh b/pkgs/build-support/setup-hooks/gog-unpack.sh
new file mode 100644
index 0000000000000..559b543fadfce
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/gog-unpack.sh
@@ -0,0 +1,11 @@
+unpackPhase="unpackGog"
+
+unpackGog() {
+    runHook preUnpackGog
+
+    innoextract --silent --extract --exclude-temp "${src}"
+
+    find . -depth -print -execdir rename -f 'y/A-Z/a-z/' '{}' \;
+
+    runHook postUnpackGog
+}
diff --git a/pkgs/build-support/vm/default.nix b/pkgs/build-support/vm/default.nix
index d599f9bbb65f8..642365bdeb5cb 100644
--- a/pkgs/build-support/vm/default.nix
+++ b/pkgs/build-support/vm/default.nix
@@ -26,6 +26,7 @@ rec {
 
   modulesClosure = makeModulesClosure {
     inherit kernel rootModules;
+    firmware = kernel;
   };