From 897b7c7e9b45c6cb272f3221a28f2e5529a52e19 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Thu, 1 Mar 2018 13:31:36 -0500 Subject: nixos: Fix initrd dependency detection when cross-compiling. --- nixos/modules/system/boot/stage-1.nix | 48 ++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'nixos/modules') 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)" -- cgit 1.4.1