summary refs log tree commit diff
path: root/nixos/modules/system/boot/stage-1.nix
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2018-03-01 13:31:36 -0500
committerShea Levy <shea@shealevy.com>2018-03-01 13:31:36 -0500
commit897b7c7e9b45c6cb272f3221a28f2e5529a52e19 (patch)
treedcf86e3db9bfc2b5b2caab4a3cfe8b1fe54ca812 /nixos/modules/system/boot/stage-1.nix
parent20072d733bd6ecf9afd98c7cfbb3f3574de4eaef (diff)
downloadnixpkgs-897b7c7e9b45c6cb272f3221a28f2e5529a52e19.tar
nixpkgs-897b7c7e9b45c6cb272f3221a28f2e5529a52e19.tar.gz
nixpkgs-897b7c7e9b45c6cb272f3221a28f2e5529a52e19.tar.bz2
nixpkgs-897b7c7e9b45c6cb272f3221a28f2e5529a52e19.tar.lz
nixpkgs-897b7c7e9b45c6cb272f3221a28f2e5529a52e19.tar.xz
nixpkgs-897b7c7e9b45c6cb272f3221a28f2e5529a52e19.tar.zst
nixpkgs-897b7c7e9b45c6cb272f3221a28f2e5529a52e19.zip
nixos: Fix initrd dependency detection when cross-compiling.
Diffstat (limited to 'nixos/modules/system/boot/stage-1.nix')
-rw-r--r--nixos/modules/system/boot/stage-1.nix48
1 files changed, 45 insertions, 3 deletions
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 494780f1748..55bb6d3449c 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -30,6 +30,50 @@ let
   # mounting `/`, like `/` on a loopback).
   fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems;
 
+  # A utility for enumerating the shared-library dependencies of a program
+  findLibs = pkgs.writeShellScriptBin "find-libs" ''
+    set -euo pipefail
+
+    declare -A seen
+    declare -a left
+
+    patchelf="${pkgs.buildPackages.patchelf}/bin/patchelf"
+
+    function add_needed {
+      rpath="$($patchelf --print-rpath $1)"
+      dir="$(dirname $1)"
+      for lib in $($patchelf --print-needed $1); do
+        left+=("$lib" "$rpath" "$dir")
+      done
+    }
+
+    add_needed $1
+
+    while [ ''${#left[@]} -ne 0 ]; do
+      next=''${left[0]}
+      rpath=''${left[1]}
+      ORIGIN=''${left[2]}
+      left=("''${left[@]:3}")
+      if [ -z ''${seen[$next]+x} ]; then
+        seen[$next]=1
+        IFS=: read -ra paths <<< $rpath
+        res=
+        for path in "''${paths[@]}"; do
+          path=$(eval "echo $path")
+          if [ -f "$path/$next" ]; then
+              res="$path/$next"
+              echo "$res"
+              add_needed "$res"
+              break
+          fi
+        done
+        if [ -z "$res" ]; then
+          echo "Couldn't satisfy dependency $next" >&2
+          exit 1
+        fi
+      fi
+    done
+  '';
 
   # Some additional utilities needed in stage 1, like mount, lvm, fsck
   # etc.  We don't want to bring in all of those packages, so we just
@@ -103,9 +147,7 @@ let
       # Copy all of the needed libraries
       find $out/bin $out/lib -type f | while read BIN; do
         echo "Copying libs for executable $BIN"
-        LDD="$(ldd $BIN)" || continue
-        LIBS="$(echo "$LDD" | awk '{print $3}' | sed '/^$/d')"
-        for LIB in $LIBS; do
+        for LIB in $(${findLibs}/bin/find-libs $BIN); do
           TGT="$out/lib/$(basename $LIB)"
           if [ ! -f "$TGT" ]; then
             SRC="$(readlink -e $LIB)"