From b3c18fe2be0e0078c7b8de9f331357227ccddc39 Mon Sep 17 00:00:00 2001 From: Guillaume Bouchard Date: Mon, 4 May 2020 14:39:44 +0200 Subject: apitrace: fix OpenGL library path and Qt GUI (#86475) For unknown reasons, Apitrace breaks the runpath of the traced program. OpenGL programs on nix are looking at /run/opengl-driver/lib to find the system OpenGL driver. This change: - add path /run/opengl-driver{-32} to the RPATH of the wrapper libraries. This fixs tracing with `apitrace trace`. - add rpath to `libglnvd` and `libGL` to the `{e}glretrace` binaries. These libraries are loaded at runtime, but does not appears as NEEDED in the binaries, hence the need for the explicit rpath addition. This fix `{e}glretrace`. - Explicitly add Qt wrapper to `qapitrace`. It fixs the GUI. Co-authored-by: Florian Klink Co-authored-by: Florian Klink --- pkgs/applications/graphics/apitrace/default.nix | 45 +++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/pkgs/applications/graphics/apitrace/default.nix b/pkgs/applications/graphics/apitrace/default.nix index f6f9cb281a772..e6865d2d8f07a 100644 --- a/pkgs/applications/graphics/apitrace/default.nix +++ b/pkgs/applications/graphics/apitrace/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchFromGitHub, cmake, libX11, procps, python2, libdwarf, qtbase, qtwebkit }: +{ stdenv, fetchFromGitHub, cmake, libX11, procps, python2, libdwarf, qtbase, qtwebkit, wrapQtAppsHook, libglvnd }: stdenv.mkDerivation rec { pname = "apitrace"; @@ -15,7 +15,48 @@ stdenv.mkDerivation rec { # of games -- so it's fine to use e.g. bundled snappy. buildInputs = [ libX11 procps python2 libdwarf qtbase qtwebkit ]; - nativeBuildInputs = [ cmake ]; + nativeBuildInputs = [ cmake wrapQtAppsHook ]; + + # Don't automatically wrap all binaries, I prefer to explicitly only wrap + # `qapitrace`. + dontWrapQtApps = true; + + postFixup = '' + + # Since https://github.com/NixOS/nixpkgs/pull/60985, we add `/run-opengl-driver[-32]` + # to the `RUNPATH` of dispatcher libraries `dlopen()` ing OpenGL drivers. + # `RUNPATH` doesn't propagate throughout the whole application, but only + # from the module performing the `dlopen()`. + # + # Apitrace wraps programs by running them with `LD_PRELOAD` pointing to `.so` + # files in $out/lib/apitrace/wrappers. + # + # Theses wrappers effectively wrap the `dlopen()` calls from `libglvnd` + # and other dispatcher libraries, and run `dlopen()` by themselves. + # + # As `RUNPATH` doesn't propagate through the whole library, and they're now the + # library doing the real `dlopen()`, they also need to have + # `/run-opengl-driver[-32]` added to their `RUNPATH`. + # + # To stay simple, we add paths for 32 and 64 bits unconditionally. + # This doesn't have an impact on closure size, and if the 32 bit drivers + # are not available, that folder is ignored. + for i in $out/lib/apitrace/wrappers/*.so + do + echo "Patching OpenGL driver path for $i" + patchelf --set-rpath "/run/opengl-driver/lib:/run/opengl-driver-32/lib:$(patchelf --print-rpath $i)" $i + done + + # Theses open the OpenGL driver at runtime, but it is not listed as NEEDED libraries. They need + # a reference to libglvnd. + for i in $out/bin/eglretrace $out/bin/glretrace + do + echo "Patching RPath for $i" + patchelf --set-rpath "${stdenv.lib.makeLibraryPath [libglvnd]}:$(patchelf --print-rpath $i)" $i + done + + wrapQtApp $out/bin/qapitrace + ''; meta = with stdenv.lib; { homepage = "https://apitrace.github.io"; -- cgit 1.4.1