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/init.sh.in2
-rw-r--r--pkgs/build-support/build-fhs-chrootenv/mount.sh.in8
-rw-r--r--pkgs/build-support/build-fhs-chrootenv/umount.sh.in2
-rwxr-xr-xpkgs/build-support/build-fhs-userenv/chroot-user.rb8
-rw-r--r--pkgs/build-support/build-fhs-userenv/default.nix40
-rw-r--r--pkgs/build-support/build-maven.nix16
-rwxr-xr-xpkgs/build-support/buildenv/builder.pl72
-rw-r--r--pkgs/build-support/buildenv/default.nix10
-rw-r--r--pkgs/build-support/builder-defs/builder-defs.nix2
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix7
-rw-r--r--pkgs/build-support/emacs/generic.nix4
-rw-r--r--pkgs/build-support/emacs/melpa.nix2
-rw-r--r--pkgs/build-support/fetchurl/mirrors.nix1
-rw-r--r--pkgs/build-support/grsecurity/default.nix4
-rw-r--r--pkgs/build-support/rust/default.nix2
-rw-r--r--pkgs/build-support/setup-hooks/make-coverage-analysis-report.sh11
-rw-r--r--pkgs/build-support/setup-hooks/make-wrapper.sh14
-rw-r--r--pkgs/build-support/setup-hooks/move-docs.sh1
-rw-r--r--pkgs/build-support/setup-hooks/patch-shebangs.sh2
-rw-r--r--pkgs/build-support/setup-hooks/wrap-gapps-hook.sh41
20 files changed, 183 insertions, 66 deletions
diff --git a/pkgs/build-support/build-fhs-chrootenv/init.sh.in b/pkgs/build-support/build-fhs-chrootenv/init.sh.in
index 9078a31fe46a..9c85069a655c 100644
--- a/pkgs/build-support/build-fhs-chrootenv/init.sh.in
+++ b/pkgs/build-support/build-fhs-chrootenv/init.sh.in
@@ -3,7 +3,7 @@
 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,home,var,run}
+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@/*
diff --git a/pkgs/build-support/build-fhs-chrootenv/mount.sh.in b/pkgs/build-support/build-fhs-chrootenv/mount.sh.in
index ef2cac21c21a..24b28aae78f7 100644
--- a/pkgs/build-support/build-fhs-chrootenv/mount.sh.in
+++ b/pkgs/build-support/build-fhs-chrootenv/mount.sh.in
@@ -22,5 +22,13 @@ 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
index b8222a4121ab..27000cff10a9 100644
--- a/pkgs/build-support/build-fhs-chrootenv/umount.sh.in
+++ b/pkgs/build-support/build-fhs-chrootenv/umount.sh.in
@@ -3,4 +3,4 @@
 chrootenvDest=/run/chrootenv/@name@
 
 # Unmount all (r)bind mounts
-umount -l $chrootenvDest/{dev/pts,dev/shm,dev,nix/store,proc,sys,host-etc,home,var,tmp,run}
+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 c555f053875a..b7d6276ceab0 100755
--- a/pkgs/build-support/build-fhs-userenv/chroot-user.rb
+++ b/pkgs/build-support/build-fhs-userenv/chroot-user.rb
@@ -7,16 +7,13 @@ mounts = [ ['/nix/store', nil],
            ['/proc', nil],
            ['/sys', nil],
            ['/etc', 'host-etc'],
+           ['/tmp', 'host-tmp'],
            ['/home', nil],
            ['/var', nil],
            ['/run', nil],
            ['/root', nil],
          ]
 
-# Create directories
-mkdirs = ['tmp',
-         ]
-
 # Propagate environment variables
 envvars = [ 'TERM',
             'DISPLAY',
@@ -99,9 +96,6 @@ if $cpid == 0
   write_file '/proc/self/uid_map', "#{uid} #{uid} 1"
   write_file '/proc/self/gid_map', "#{gid} #{gid} 1"
 
-  # Do mkdirs
-  mkdirs.each { |x| FileUtils.mkdir_p "#{root}/#{x}" }
-
   # Do rbind mounts.
   mounts.each do |x|
     to = "#{root}/#{x[1]}"
diff --git a/pkgs/build-support/build-fhs-userenv/default.nix b/pkgs/build-support/build-fhs-userenv/default.nix
index 546345c7e6c2..9060c073eee3 100644
--- a/pkgs/build-support/build-fhs-userenv/default.nix
+++ b/pkgs/build-support/build-fhs-userenv/default.nix
@@ -1,4 +1,4 @@
-{ writeText, writeScriptBin, stdenv, ruby } : { env, runScript } :
+{ runCommand, writeText, writeScriptBin, stdenv, ruby } : { env, runScript ? "bash" } :
 
 let
   name = env.pname;
@@ -9,13 +9,37 @@ let
     ${builtins.readFile ./chroot-user.rb}
   '';
 
-  init = writeText "init" ''
-           [ -d "$1" ] && [ -r "$1" ] && cd "$1"
-           shift
-           exec "${runScript}" "$@"
-         '';
+  init = run: writeText "${name}-init" ''
+    # Make /tmp directory
+    mkdir -m 1777 /tmp
 
-in writeScriptBin name ''
+    # Expose sockets in /tmp
+    for i in /host-tmp/.*-unix; do
+      ln -s "$i" "/tmp/$(basename "$i")"
+    done
+
+    [ -d "$1" ] && [ -r "$1" ] && cd "$1"
+    shift
+    exec ${run} "$@"
+  '';
+
+in runCommand name {
+  passthru.env =
+    runCommand "${name}-shell-env" {
+      shellHook = ''
+        exec ${chroot-user}/bin/chroot-user ${env} bash -l ${init "bash"} "$(pwd)"
+      '';
+    } ''
+      echo >&2 ""
+      echo >&2 "*** User chroot 'env' attributes are intended for interactive nix-shell sessions, not for building! ***"
+      echo >&2 ""
+      exit 1
+    '';
+} ''
+  mkdir -p $out/bin
+  cat <<EOF >$out/bin/${name}
   #! ${stdenv.shell}
-  exec ${chroot-user}/bin/chroot-user ${env} bash -l ${init} "$(pwd)" "$@"
+  exec ${chroot-user}/bin/chroot-user ${env} bash -l ${init runScript} "\$(pwd)" "\$@"
+  EOF
+  chmod +x $out/bin/${name}
 ''
diff --git a/pkgs/build-support/build-maven.nix b/pkgs/build-support/build-maven.nix
index a1faf8060be9..ff91828eeca7 100644
--- a/pkgs/build-support/build-maven.nix
+++ b/pkgs/build-support/build-maven.nix
@@ -15,15 +15,27 @@ infoFile: let
 
   script = writeText "build-maven-repository.sh" ''
     ${lib.concatStrings (map (dep: let
-      inherit (dep) url sha1 groupId artifactId version authenticated;
+      inherit (dep)
+        url sha1 groupId artifactId version
+        authenticated metadata extension repository-id;
+
+      versionDir = dep.unresolved-version or version;
 
       fetch = (if authenticated then requireFile else fetchurl) {
         inherit url sha1;
       };
+
+      fetchMetadata = (if authenticated then requireFile else fetchurl) {
+        inherit (metadata) url sha1;
+      };
     in ''
-      dir=$out/$(echo ${groupId} | sed 's|\.|/|g')/${artifactId}/${version}
+      dir=$out/$(echo ${groupId} | sed 's|\.|/|g')/${artifactId}/${versionDir}
       mkdir -p $dir
       ln -sv ${fetch} $dir/${fetch.name}
+      ${lib.optionalString (dep ? metadata) ''
+        ln -svf ${fetchMetadata} $dir/maven-metadata-${repository-id}.xml
+        ln -sv ${fetch} $dir/$(echo ${fetch.name} | sed 's|${version}|${dep.unresolved-version}|')
+      ''}
     '') info.dependencies)}
   '';
 
diff --git a/pkgs/build-support/buildenv/builder.pl b/pkgs/build-support/buildenv/builder.pl
index 08331b178f4f..a272a84261e4 100755
--- a/pkgs/build-support/buildenv/builder.pl
+++ b/pkgs/build-support/buildenv/builder.pl
@@ -5,6 +5,7 @@ use Cwd 'abs_path';
 use IO::Handle;
 use File::Path;
 use File::Basename;
+use JSON::PP;
 
 STDOUT->autoflush(1);
 
@@ -17,7 +18,7 @@ sub isInPathsToLink {
     $path = "/" if $path eq "";
     foreach my $elem (@pathsToLink) {
         return 1 if
-            $elem eq "/" || 
+            $elem eq "/" ||
             (substr($path, 0, length($elem)) eq $elem
              && (($path eq $elem) || (substr($path, length($elem), 1) eq "/")));
     }
@@ -28,25 +29,29 @@ sub isInPathsToLink {
 # For each activated package, determine what symlinks to create.
 
 my %symlinks;
-$symlinks{""} = ""; # create root directory
+
+for my $p (@pathsToLink) {
+    $p = "" if $p eq "/";
+    $symlinks{$p} = ["", 0];
+}
 
 sub findFiles;
 
 sub findFilesInDir {
-    my ($relName, $target, $ignoreCollisions) = @_;
+    my ($relName, $target, $ignoreCollisions, $priority) = @_;
 
     opendir DIR, "$target" or die "cannot open `$target': $!";
     my @names = readdir DIR or die;
     closedir DIR;
-    
+
     foreach my $name (@names) {
         next if $name eq "." || $name eq "..";
-        findFiles("$relName/$name", "$target/$name", $name, $ignoreCollisions);
+        findFiles("$relName/$name", "$target/$name", $name, $ignoreCollisions, $priority);
     }
 }
-    
+
 sub findFiles {
-    my ($relName, $target, $baseName, $ignoreCollisions) = @_;
+    my ($relName, $target, $baseName, $ignoreCollisions, $priority) = @_;
 
     # Urgh, hacky...
     return if
@@ -57,41 +62,48 @@ sub findFiles {
         $baseName eq "perllocal.pod" ||
         $baseName eq "log";
 
-    my $oldTarget = $symlinks{$relName};
+    my ($oldTarget, $oldPriority) = @{$symlinks{$relName} // [undef, undef]};
+
+    # If target doesn't exist, create it. If it already exists as a
+    # symlink to a file (not a directory) in a lower-priority package,
+    # overwrite it.
+    if (!defined $oldTarget || ($priority < $oldPriority && ($oldTarget ne "" && ! -d $oldTarget))) {
+        $symlinks{$relName} = [$target, $priority];
+        return;
+    }
 
-    if (!defined $oldTarget) {
-        $symlinks{$relName} = $target;
+    # If target already exists as a symlink to a file (not a
+    # directory) in a higher-priority package, skip.
+    if (defined $oldTarget && $priority > $oldPriority && $oldTarget ne "" && ! -d $oldTarget) {
         return;
     }
 
     unless (-d $target && ($oldTarget eq "" || -d $oldTarget)) {
         if ($ignoreCollisions) {
-            warn "collision between `$target' and `$oldTarget'" if $ignoreCollisions == 1;
+            warn "collision between `$target' and `$oldTarget'\n" if $ignoreCollisions == 1;
             return;
         } else {
-            die "collision between `$target' and `$oldTarget'";
+            die "collision between `$target' and `$oldTarget'\n";
         }
     }
 
-    findFilesInDir($relName, $oldTarget, $ignoreCollisions) unless $oldTarget eq "";
-    findFilesInDir($relName, $target, $ignoreCollisions);
-    
-    $symlinks{$relName} = ""; # denotes directory
+    findFilesInDir($relName, $oldTarget, $ignoreCollisions, $oldPriority) unless $oldTarget eq "";
+    findFilesInDir($relName, $target, $ignoreCollisions, $priority);
+
+    $symlinks{$relName} = ["", $priority]; # denotes directory
 }
 
 
 my %done;
 my %postponed;
 
-sub addPkg;
-sub addPkg($;$) {
-    my $pkgDir = shift;
-    my $ignoreCollisions = shift;
+sub addPkg {
+    my ($pkgDir, $ignoreCollisions, $priority)  = @_;
 
     return if (defined $done{$pkgDir});
     $done{$pkgDir} = 1;
 
-    findFiles("", "$pkgDir", "", $ignoreCollisions);
+    findFiles("", $pkgDir, "", $ignoreCollisions, $priority);
 
     my $propagatedFN = "$pkgDir/nix-support/propagated-user-env-packages";
     if (-e $propagatedFN) {
@@ -106,23 +118,25 @@ sub addPkg($;$) {
 }
 
 
-# Symlink to the packages that have been installed explicitly by the user.
-my @args = split ' ', $ENV{"paths"};
-
-foreach my $pkgDir (@args) {
-    addPkg($pkgDir, $ENV{"ignoreCollisions"} eq "1") if -e $pkgDir;
+# Symlink to the packages that have been installed explicitly by the
+# user.
+for my $pkg (@{decode_json $ENV{"pkgs"}}) {
+    for my $path (@{$pkg->{paths}}) {
+        addPkg($path, $ENV{"ignoreCollisions"} eq "1", $pkg->{priority}) if -e $path;
+    }
 }
 
 
 # Symlink to the packages that have been "propagated" by packages
-# installed by the user (i.e., package X declares that it want Y
+# installed by the user (i.e., package X declares that it wants Y
 # installed as well).  We do these later because they have a lower
 # priority in case of collisions.
+my $priorityCounter = 1000; # don't care about collisions
 while (scalar(keys %postponed) > 0) {
     my @pkgDirs = keys %postponed;
     %postponed = ();
     foreach my $pkgDir (sort @pkgDirs) {
-        addPkg($pkgDir, 2);
+        addPkg($pkgDir, 2, $priorityCounter++);
     }
 }
 
@@ -130,7 +144,7 @@ while (scalar(keys %postponed) > 0) {
 # Create the symlinks.
 my $nrLinks = 0;
 foreach my $relName (sort keys %symlinks) {
-    my $target = $symlinks{$relName};
+    my ($target, $priority) = @{$symlinks{$relName}};
     my $abs = "$out/$relName";
     next unless isInPathsToLink $relName;
     if ($target eq "") {
diff --git a/pkgs/build-support/buildenv/default.nix b/pkgs/build-support/buildenv/default.nix
index 293291dc1dad..2ae8123faca4 100644
--- a/pkgs/build-support/buildenv/default.nix
+++ b/pkgs/build-support/buildenv/default.nix
@@ -9,10 +9,10 @@
 , # The manifest file (if any).  A symlink $out/manifest will be
   # created to it.
   manifest ? ""
-  
+
 , # The paths to symlink.
   paths
-  
+
 , # Whether to ignore collisions or abort.
   ignoreCollisions ? false
 
@@ -28,7 +28,11 @@
 }:
 
 runCommand name
-  { inherit manifest paths ignoreCollisions passthru pathsToLink postBuild;
+  { inherit manifest ignoreCollisions passthru pathsToLink postBuild;
+    pkgs = builtins.toJSON (map (drv: {
+      paths = [ drv ]; # FIXME: handle multiple outputs
+      priority = drv.meta.priority or 5;
+    }) paths);
     preferLocalBuild = true;
   }
   ''
diff --git a/pkgs/build-support/builder-defs/builder-defs.nix b/pkgs/build-support/builder-defs/builder-defs.nix
index 42d8f35b076d..e7c64501614c 100644
--- a/pkgs/build-support/builder-defs/builder-defs.nix
+++ b/pkgs/build-support/builder-defs/builder-defs.nix
@@ -569,7 +569,7 @@ let inherit (builtins) head tail trace; in
      # Interpreters that are already in the store are left untouched.
          echo "patching script interpreter paths"
          local f
-         for f in $(find "${dir}" -xtype f -perm +0100); do
+         for f in $(find "${dir}" -xtype f -perm /0100); do
              local oldPath=$(sed -ne '1 s,^#![ ]*\([^ ]*\).*$,\1,p' "$f")
              if test -n "$oldPath" -a "''${oldPath:0:''${#NIX_STORE}}" != "$NIX_STORE"; then
                  local newPath=$(type -P $(basename $oldPath) || true)
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index ec024c72481d..8965fc6bef0c 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -7,9 +7,9 @@
 
 { name ? "", stdenv, nativeTools, nativeLibc, nativePrefix ? ""
 , cc ? null, libc ? null, binutils ? null, coreutils ? null, shell ? stdenv.shell
-, zlib ? null, extraPackages ? []
+, zlib ? null, extraPackages ? [], extraBuildCommands ? ""
 , dyld ? null # TODO: should this be a setup-hook on dyld?
-, isGNU ? false, isClang ? false
+, isGNU ? false, isClang ? cc.isClang or false
 }:
 
 with stdenv.lib;
@@ -232,7 +232,8 @@ stdenv.mkDerivation {
 
       substituteAll ${./add-flags} $out/nix-support/add-flags.sh
       cp -p ${./utils.sh} $out/nix-support/utils.sh
-    '';
+    ''
+    + extraBuildCommands;
 
   # The dynamic linker has different names on different Linux platforms.
   dynamicLinker =
diff --git a/pkgs/build-support/emacs/generic.nix b/pkgs/build-support/emacs/generic.nix
index be81e93e32ae..6fd630b13f4a 100644
--- a/pkgs/build-support/emacs/generic.nix
+++ b/pkgs/build-support/emacs/generic.nix
@@ -16,10 +16,14 @@ with lib;
 }@args:
 
 let
+
   defaultMeta = {
     broken = false;
     platforms = emacs.meta.platforms;
+  } // optionalAttrs ((args.src.meta.homepage or "") != "") {
+    homepage = args.src.meta.homepage;
   };
+
 in
 
 stdenv.mkDerivation ({
diff --git a/pkgs/build-support/emacs/melpa.nix b/pkgs/build-support/emacs/melpa.nix
index 607a1b4a5ef6..5eaa995b4126 100644
--- a/pkgs/build-support/emacs/melpa.nix
+++ b/pkgs/build-support/emacs/melpa.nix
@@ -31,7 +31,7 @@ let
   targets = concatStringsSep " " (if files == null then fileSpecs else files);
 
   defaultMeta = {
-    homepage = "http://melpa.org/#/${pname}";
+    homepage = args.src.meta.homepage or "http://melpa.org/#/${pname}";
   };
 
 in
diff --git a/pkgs/build-support/fetchurl/mirrors.nix b/pkgs/build-support/fetchurl/mirrors.nix
index 2f6a4d36327c..cf986a064d9d 100644
--- a/pkgs/build-support/fetchurl/mirrors.nix
+++ b/pkgs/build-support/fetchurl/mirrors.nix
@@ -280,6 +280,7 @@ rec {
     http://archive.apache.org/dist/ # fallback for old releases
     ftp://ftp.funet.fi/pub/mirrors/apache.org/
     http://apache.cs.uu.nl/dist/
+    http://apache.cs.utah.edu/
   ];
 
   postgresql = [
diff --git a/pkgs/build-support/grsecurity/default.nix b/pkgs/build-support/grsecurity/default.nix
index 0fd3df6d5f5f..f26291e7daae 100644
--- a/pkgs/build-support/grsecurity/default.nix
+++ b/pkgs/build-support/grsecurity/default.nix
@@ -33,7 +33,7 @@ let
 
     grKernel = if cfg.stable
                then mkKernel pkgs.linux_3_14 stable-patch
-               else mkKernel pkgs.linux_4_0 test-patch;
+               else mkKernel pkgs.linux_4_1 test-patch;
 
     ## -- grsecurity configuration ---------------------------------------------
 
@@ -85,7 +85,7 @@ let
       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.services.virtualboxGuest.enable
+          #randstruct = optionalString config.virtualisation.virtualbox.guest.enable
           #  "GRKERNSEC_RANDSTRUCT n";
 
           # Disable restricting links under the testing kernel, as something
diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix
index cd19782e6115..c23581d96019 100644
--- a/pkgs/build-support/rust/default.nix
+++ b/pkgs/build-support/rust/default.nix
@@ -44,7 +44,7 @@ in stdenv.mkDerivation (args // {
     export CARGO_HOME="$(realpath deps)"
 
     # Let's find out which $indexHash cargo uses for file:///dev/null
-    (cd $sourceRoot && cargo fetch &>/dev/null)
+    (cd $sourceRoot && cargo fetch &>/dev/null) || true
     cd deps
     indexHash="$(basename $(echo registry/index/*))"
 
diff --git a/pkgs/build-support/setup-hooks/make-coverage-analysis-report.sh b/pkgs/build-support/setup-hooks/make-coverage-analysis-report.sh
index 4b8abb61ace5..9108b4c50355 100644
--- a/pkgs/build-support/setup-hooks/make-coverage-analysis-report.sh
+++ b/pkgs/build-support/setup-hooks/make-coverage-analysis-report.sh
@@ -10,9 +10,16 @@ coverageReportPhase() {
     mkdir -p $out/coverage
     genhtml app.info $lcovExtraTraceFiles -o $out/coverage > log
 
-    # Grab the overall coverage percentage for use in release overviews.
+    # Grab the overall coverage percentage so that Hydra can plot it over time.
     mkdir -p $out/nix-support
-    grep "Overall coverage rate" log | sed 's/^.*(\(.*\)%).*$/\1/' > $out/nix-support/coverage-rate
+    lineCoverage="$(sed 's/.*lines\.*: \([0-9\.]\+\)%.*/\1/; t ; d' log)"
+    functionCoverage="$(sed 's/.*functions\.*: \([0-9\.]\+\)%.*/\1/; t ; d' log)"
+    if [ -z "$lineCoverage" -o -z "$functionCoverage" ]; then
+        echo "failed to get coverage statistics"
+        exit 1
+    fi
+    echo "lineCoverage $lineCoverage %" >> $out/nix-support/hydra-metrics
+    echo "functionCoverage $functionCoverage %" >> $out/nix-support/hydra-metrics
 
     echo "report coverage $out/coverage" >> $out/nix-support/hydra-build-products
 }
diff --git a/pkgs/build-support/setup-hooks/make-wrapper.sh b/pkgs/build-support/setup-hooks/make-wrapper.sh
index 41f2a59246d1..5150b4f0218a 100644
--- a/pkgs/build-support/setup-hooks/make-wrapper.sh
+++ b/pkgs/build-support/setup-hooks/make-wrapper.sh
@@ -2,7 +2,7 @@ makeWrapper() {
     local original=$1
     local wrapper=$2
     local params varName value command separator n fileNames
-    local flagsBefore flags
+    local argv0 flagsBefore flags
 
     mkdir -p "$(dirname $wrapper)"
 
@@ -68,12 +68,18 @@ makeWrapper() {
             n=$((n + 1))
             flagsBefore="$flagsBefore $flags"
         fi
+
+        if test "$p" = "--argv0"; then
+            argv0=${params[$((n + 1))]}
+            n=$((n + 1))
+        fi
     done
 
     # Note: extraFlagsArray is an array containing additional flags
     # that may be set by --run actions.
-    echo exec "$original" $flagsBefore '"${extraFlagsArray[@]}"' '"$@"' >> $wrapper
-    
+    echo exec ${argv0:+-a $argv0} "$original" \
+         $flagsBefore '"${extraFlagsArray[@]}"' '"$@"' >> $wrapper
+
     chmod +x $wrapper
 }
 
@@ -98,5 +104,5 @@ wrapProgram() {
     local prog="$1"
     local hidden="$(dirname "$prog")/.$(basename "$prog")"-wrapped
     mv $prog $hidden
-    makeWrapper $hidden $prog "$@"
+    makeWrapper $hidden $prog --argv0 '"$0"' "$@"
 }
diff --git a/pkgs/build-support/setup-hooks/move-docs.sh b/pkgs/build-support/setup-hooks/move-docs.sh
index c819ee12a9c9..57b71c15691d 100644
--- a/pkgs/build-support/setup-hooks/move-docs.sh
+++ b/pkgs/build-support/setup-hooks/move-docs.sh
@@ -42,6 +42,7 @@ _moveDocs() {
     _moveToOutput share/man "$man"
     _moveToOutput share/info "$info"
     _moveToOutput share/doc "$doc"
+    _moveToOutput share/gtk-doc "$doc"
 
     # Remove empty share directory.
     if [ -d "$out/share" ]; then
diff --git a/pkgs/build-support/setup-hooks/patch-shebangs.sh b/pkgs/build-support/setup-hooks/patch-shebangs.sh
index 5a7f23b2d816..44ebad0d593b 100644
--- a/pkgs/build-support/setup-hooks/patch-shebangs.sh
+++ b/pkgs/build-support/setup-hooks/patch-shebangs.sh
@@ -18,7 +18,7 @@ patchShebangs() {
     local oldInterpreterLine
     local newInterpreterLine
 
-    find "$dir" -type f -perm +0100 | while read f; do
+    find "$dir" -type f -perm /0100 | while read f; do
         if [ "$(head -1 "$f" | head -c +2)" != '#!' ]; then
             # missing shebang => not a script
             continue
diff --git a/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh b/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh
new file mode 100644
index 000000000000..3445c4b9cc1d
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh
@@ -0,0 +1,41 @@
+gappsWrapperArgs=()
+
+find_gio_modules() {
+    if [ -d "$1"/lib/gio/modules ] && [ -n "$(ls -A $1/lib/gio/modules)" ] ; then
+        gappsWrapperArgs+=(--prefix GIO_EXTRA_MODULES : "$1/lib/gio/modules")
+    fi
+}
+
+envHooks+=(find_gio_modules)
+
+wrapGAppsHook() {
+  if [ -n "$GDK_PIXBUF_MODULE_FILE" ]; then
+    gappsWrapperArgs+=(--set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE")
+  fi
+
+  if [ -n "$XDG_ICON_DIRS" ]; then
+    gappsWrapperArgs+=(--prefix XDG_DATA_DIRS : "$XDG_ICON_DIRS")
+  fi
+
+  if [ -n "$GSETTINGS_SCHEMAS_PATH" ]; then
+    gappsWrapperArgs+=(--prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH")
+  fi
+
+  if [ -d "$prefix/share" ]; then
+    gappsWrapperArgs+=(--prefix XDG_DATA_DIRS : "$prefix/share")
+  fi
+
+  for v in $wrapPrefixVariables GST_PLUGIN_SYSTEM_PATH_1_0 GI_TYPELIB_PATH GRL_PLUGIN_PATH; do
+    eval local dummy="\$$v"
+    gappsWrapperArgs+=(--prefix $v : "$dummy")
+  done
+
+  if [ -z "$dontWrapGApps" ]; then
+    for i in $prefix/bin/* $prefix/libexec/*; do
+      echo "Wrapping app $i"
+      wrapProgram "$i" "${gappsWrapperArgs[@]}"
+    done
+  fi
+}
+
+fixupOutputHooks+=(wrapGAppsHook)