From 863cdf8f097c172ed92ccb689c6d52915c2858c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Na=C3=AFm=20Favier?= Date: Sat, 7 May 2022 18:13:19 +0200 Subject: [PATCH] wrapFirefox: handle binary wrappers We can't just edit binary wrappers in place because of a length mismatch, so we have to parse the generating makeCWrapper call out of the binary, extract wrapper arguments from it and add them to the Firefox wrapper. All these contortions are needed because Firefox looks for its runtime in argv0, so the proper argv0 needs to be set by wrappers to always point to the "final" runtime. I think this could be avoided by wrapping /lib/$libName/firefox instead of /bin/firefox, and I'd like to look into that in the future, but for now I'm just fixing the immediate problem. --- .../networking/browsers/firefox/wrapper.nix | 67 ++++++++++--------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/pkgs/applications/networking/browsers/firefox/wrapper.nix b/pkgs/applications/networking/browsers/firefox/wrapper.nix index d5055f04ed8..235794dd421 100644 --- a/pkgs/applications/networking/browsers/firefox/wrapper.nix +++ b/pkgs/applications/networking/browsers/firefox/wrapper.nix @@ -1,5 +1,5 @@ { stdenv, lib, makeDesktopItem, makeWrapper, lndir, config -, replace, fetchurl, zip, unzip, jq, xdg-utils, writeText +, fetchurl, zip, unzip, jq, xdg-utils, writeText ## various stuff that can be plugged in , ffmpeg, xorg, alsa-lib, libpulseaudio, libcanberra-gtk3, libglvnd, libnotify, opensc @@ -176,7 +176,7 @@ let startupWMClass = wmClass; }; - nativeBuildInputs = [ makeWrapper lndir replace jq ]; + nativeBuildInputs = [ makeWrapper lndir jq ]; buildInputs = [ browser.gtk3 ]; @@ -206,48 +206,50 @@ let done # fix links and absolute references - cd "${browser}" find . -type l -print0 | while read -d $'\0' l; do - target="$(readlink "$l" | replace-literal -es -- "${browser}" "$out")" + target="$(readlink "$l")" + target=''${target/#"${browser}"/"$out"} ln -sfT "$target" "$out/$l" done - # This will not patch binaries, only "text" files. - # Its there for the wrapper mostly. - cd "$out" - replace-literal -esfR -- "${browser}" "$out" - # create the wrapper executablePrefix="$out/bin" executablePath="$executablePrefix/${applicationName}" + oldWrapperArgs=() - if [ ! -x "$executablePath" ] - then - echo "cannot find executable file \`${browser}/bin/${applicationName}'" - exit 1 - fi - - if [ ! -L "$executablePath" ] - then - # Careful here, the file at executablePath may already be - # a wrapper. That is why we postfix it with -old instead - # of -wrapped. - oldExe="$executablePrefix"/".${applicationName}"-old - mv "$executablePath" "$oldExe" - else + if [[ -L $executablePath ]]; then + # Symbolic link: wrap the link's target. oldExe="$(readlink -v --canonicalize-existing "$executablePath")" - fi - - if [ ! -x "${browser}/bin/${applicationName}" ] - then - echo "cannot find executable file \`${browser}/bin/${applicationName}'" - exit 1 + rm "$executablePath" + elif wrapperCmd=$(strings -dw "$executablePath" | sed -n '/^makeCWrapper/,/^$/ p'); [[ $wrapperCmd ]]; then + # If the executable is a binary wrapper, we need to update its target to + # point to $out, but we can't just edit the binary in-place because of length + # issues. So we extract the command used to create the wrapper and add the + # arguments to our wrapper. + parseMakeCWrapperCall() { + shift # makeCWrapper + oldExe=$1; shift + for arg do case $arg in + --inherit-argv0) oldWrapperArgs+=(--argv0 '$0');; # makeWrapper doesn't understand --inherit-argv0 + *) oldWrapperArgs+=("$arg");; + esac done + } + eval "parseMakeCWrapperCall ''${wrapperCmd//"${browser}"/"$out"}" + rm "$executablePath" + else + if read -rn2 shebang < "$executablePath" && [[ $shebang == '#!' ]]; then + # Shell wrapper: patch in place to point to $out. + sed -i "s@${browser}@$out@g" "$executablePath" + fi + # Suffix the executable with -old, because -wrapped might already be used by the old wrapper. + oldExe="$executablePrefix/.${applicationName}"-old + mv "$executablePath" "$oldExe" fi makeWrapper "$oldExe" \ - "$out/bin/${applicationName}${nameSuffix}" \ + "''${executablePath}${nameSuffix}" \ --prefix LD_LIBRARY_PATH ':' "$libs" \ --suffix-each GTK_PATH ':' "$gtk_modules" \ --prefix PATH ':' "${xdg-utils}/bin" \ @@ -258,9 +260,8 @@ let --set MOZ_ALLOW_DOWNGRADE 1 \ --prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH" \ --suffix XDG_DATA_DIRS : '${gnome.adwaita-icon-theme}/share' \ - ${lib.optionalString forceWayland '' - --set MOZ_ENABLE_WAYLAND "1" \ - ''} + ${lib.optionalString forceWayland "--set MOZ_ENABLE_WAYLAND 1"} \ + "''${oldWrapperArgs[@]}" ############################# # # # END EXTRA PREF CHANGES #