summary refs log tree commit diff
path: root/pkgs/applications/networking/browsers/firefox/wrapper.nix
diff options
context:
space:
mode:
authorNaïm Favier <n@monade.li>2022-05-07 18:13:19 +0200
committerNaïm Favier <n@monade.li>2022-05-07 20:40:43 +0200
commit863cdf8f097c172ed92ccb689c6d52915c2858c3 (patch)
tree21e00257ca5276f06d3f41f8ee333e051e188e10 /pkgs/applications/networking/browsers/firefox/wrapper.nix
parent2bebc577d88eaefeae686d7972d268af65a1051f (diff)
downloadnixpkgs-863cdf8f097c172ed92ccb689c6d52915c2858c3.tar
nixpkgs-863cdf8f097c172ed92ccb689c6d52915c2858c3.tar.gz
nixpkgs-863cdf8f097c172ed92ccb689c6d52915c2858c3.tar.bz2
nixpkgs-863cdf8f097c172ed92ccb689c6d52915c2858c3.tar.lz
nixpkgs-863cdf8f097c172ed92ccb689c6d52915c2858c3.tar.xz
nixpkgs-863cdf8f097c172ed92ccb689c6d52915c2858c3.tar.zst
nixpkgs-863cdf8f097c172ed92ccb689c6d52915c2858c3.zip
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.
Diffstat (limited to 'pkgs/applications/networking/browsers/firefox/wrapper.nix')
-rw-r--r--pkgs/applications/networking/browsers/firefox/wrapper.nix67
1 files 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  #