From 4f0b794d1500e644ebd25d13335cfccc65ebcd47 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Wed, 17 Dec 2025 15:13:30 +0200 Subject: [PATCH] tests.auto-patchelf-hook-preserve-origin: init This adds a test for the autoPatchelfHook --preserve-origin feature. --- .../default.nix | 91 +++++++++++++++++++ .../lib-main.c | 14 +++ pkgs/test/default.nix | 2 + pkgs/test/stdenv-inputs/default.nix | 3 + 4 files changed, 110 insertions(+) create mode 100644 pkgs/test/auto-patchelf-hook-preserve-origin/default.nix create mode 100644 pkgs/test/auto-patchelf-hook-preserve-origin/lib-main.c diff --git a/pkgs/test/auto-patchelf-hook-preserve-origin/default.nix b/pkgs/test/auto-patchelf-hook-preserve-origin/default.nix new file mode 100644 index 000000000000..7685f41e91c9 --- /dev/null +++ b/pkgs/test/auto-patchelf-hook-preserve-origin/default.nix @@ -0,0 +1,91 @@ +{ + lib, + stdenv, + tests, + autoPatchelfHook, + patchelf, +}: + +let + foo = tests.stdenv-inputs.foo; + bar = tests.stdenv-inputs.bar; + + # similar to lib-check in stdenv-inputs, but we ship + # binary and libraries in the same output, and only + # $ORIGIN/../lib in RUNPATH. + lib-check = stdenv.mkDerivation { + name = "lib-check-bundle"; + + buildInputs = [ + foo + bar + ]; + + nativeBuildInputs = [ + patchelf + ]; + + buildCommand = '' + $CC -lfoo -lbar -Wl,-rpath,'$ORIGIN/../lib' -o lib-check ${./lib-main.c} + + # Shrink RUNPATH to only keep the $ORIGIN/../lib one, + # dropping references to foo and bar store path. + patchelf --shrink-rpath --allowed-rpath-prefixes '$ORIGIN/../lib' lib-check + + + mkdir -p $out/lib $out/bin + cp ${lib.getDev foo}/lib/* ${lib.getDev bar}/lib/* $out/lib/ + cp lib-check $out/bin/ + + # Make sure the binary still works + $out/bin/lib-check + ''; + + disallowedReferences = [ + (lib.getDev foo) + (lib.getDev bar) + ]; + }; + # We treat `lib-check` as binaries and libraries coming from somewhere, + # and run `autoPatchelfHook` on them, but setting `--preserve-origin`. + # If we wouldn't,`autoPatchelfHook` would replace `RUNPATH` with a + # (self-)reference. + lib-check-autopatchelfed = stdenv.mkDerivation { + name = "lib-check-autopatchelfed"; + + nativeBuildInputs = [ + autoPatchelfHook + ]; + + autoPatchelfFlags = [ "--preserve-origin" ]; + + dontUnpack = true; + + # we don't set buildCommand because we want to ensure fixupPhase + # (containing autoPatchelfHook) is run. + installPhase = '' + mkdir -p $out + cp -R ${lib-check}/* $out + ''; + + # Should not refer to our source nor to itself. + disallowedReferences = [ + lib-check + "out" + ]; + }; +in +stdenv.mkDerivation { + name = "auto-patchelf-hook-preserve-origin"; + + buildCommand = '' + # Ensure the binary still works + ${lib-check-autopatchelfed}/bin/lib-check + touch $out + ''; + + meta.platforms = lib.platforms.all; + passthru = { + inherit lib-check lib-check-autopatchelfed; + }; +} diff --git a/pkgs/test/auto-patchelf-hook-preserve-origin/lib-main.c b/pkgs/test/auto-patchelf-hook-preserve-origin/lib-main.c new file mode 100644 index 000000000000..c9488fe43e55 --- /dev/null +++ b/pkgs/test/auto-patchelf-hook-preserve-origin/lib-main.c @@ -0,0 +1,14 @@ +#include + +extern unsigned int foo(void); +extern unsigned int bar(void); + +int main(int argc, char **argv) +{ + if (foo() != 42) + return 1; + if (bar() != 42) + return 1; + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix index 4c613135e977..da33cd9c07b0 100644 --- a/pkgs/test/default.nix +++ b/pkgs/test/default.nix @@ -225,6 +225,8 @@ in auto-patchelf-hook = callPackage ./auto-patchelf-hook { }; + auto-patchelf-hook-preserve-origin = callPackage ./auto-patchelf-hook-preserve-origin { }; + # Accumulate all passthru.tests from arrayUtilities into a single attribute set. arrayUtilities = recurseIntoAttrs ( concatMapAttrs ( diff --git a/pkgs/test/stdenv-inputs/default.nix b/pkgs/test/stdenv-inputs/default.nix index 9ffe2e6479ce..2615c905045d 100644 --- a/pkgs/test/stdenv-inputs/default.nix +++ b/pkgs/test/stdenv-inputs/default.nix @@ -70,4 +70,7 @@ stdenv.mkDerivation { ''; meta.platforms = lib.platforms.all; + passthru = { + inherit foo bar; + }; }