nixpkgs/pkgs/applications/networking/browsers/chromium/default.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

185 lines
6.7 KiB
Nix
Raw Normal View History

{ newScope, config, stdenv, fetchurl, makeWrapper
, buildPackages
, ed, gnugrep, coreutils, xdg-utils
, glib, gtk3, gtk4, gnome, gsettings-desktop-schemas, gn, fetchgit
, libva, pipewire, wayland
, gcc, nspr, nss, runCommand
2022-02-11 18:51:42 +00:00
, lib, libkrb5
, widevine-cdm
, electron-source # for warnObsoleteVersionConditional
# package customization
# Note: enable* flags should not require full rebuilds (i.e. only affect the wrapper)
, channel ? "stable"
, upstream-info ? (import ./upstream-info.nix).${channel}
, proprietaryCodecs ? true
, enableWideVine ? false
, ungoogled ? false # Whether to build chromium or ungoogled-chromium
2014-12-07 13:52:36 +00:00
, cupsSupport ? true
, pulseSupport ? config.pulseaudio or stdenv.isLinux
, commandLineArgs ? ""
, pkgsBuildTarget
, pkgsBuildBuild
, pkgs
}:
let
# Sometimes we access `llvmPackages` via `pkgs`, and other times
# via `pkgsFooBar`, so a string (attrname) is the only way to have
# a single point of control over the LLVM version used.
2023-12-17 01:08:18 +00:00
llvmPackages_attrName = "llvmPackages_17";
stdenv = pkgs.${llvmPackages_attrName}.stdenv;
# Helper functions for changes that depend on specific versions:
warnObsoleteVersionConditional = min-version: result:
let min-supported-version = (lib.head (lib.attrValues electron-source)).unwrapped.info.chromium.version;
in lib.warnIf
(lib.versionAtLeast min-supported-version min-version)
"chromium: min-supported-version ${min-supported-version} is newer than a conditional bounded at ${min-version}. You can safely delete it."
result;
chromiumVersionAtLeast = min-version:
let result = lib.versionAtLeast upstream-info.version min-version;
in warnObsoleteVersionConditional min-version result;
versionRange = min-version: upto-version:
let inherit (upstream-info) version;
result = lib.versionAtLeast version min-version && lib.versionOlder version upto-version;
in warnObsoleteVersionConditional upto-version result;
callPackage = newScope chromium;
chromium = rec {
inherit stdenv llvmPackages_attrName upstream-info;
mkChromiumDerivation = callPackage ./common.nix ({
inherit channel chromiumVersionAtLeast versionRange;
inherit proprietaryCodecs
cupsSupport pulseSupport ungoogled;
gnChromium = buildPackages.gn.overrideAttrs (oldAttrs: {
inherit (upstream-info.deps.gn) version;
src = fetchgit {
inherit (upstream-info.deps.gn) url rev hash;
};
});
chromium: improve and move `recompressTarball` Recap: We need that (arguably stupid) helper function/drv because the chromium tarball is big -- and is likely to increase even more in the future. So big, that we eventually exceeded hydra.nixos.org's max-output-limit (3G). Instead of raising global hydra's limit, it was decided that we recompress the tarball after deleting unused vendored files from it. I spent a lot of time on a version/prototype that does everything (downloading, decompression, tar extraction, deleting unused files, reproducible tar recreation and finally recompression) via stdin but eventually had to scratch that. GNU tar does not allow to create a tarball just from stdin, nixpkgs' stdenv isn't built with stdin/stdout/pipes in mind, and things a lot of other things I probably already forgot. Nonetheless, this version improves multiple things: - No more `mv` (used to be multiple, not just ours, since fetchzip had some as well) - No more `rm` to get rid of the extracted files before recompressing. Instead, we simply don't extract them in the first place (thanks to tar's --exlude). - No more "no space left" that happened due to `downloadToTemp = true;`. - Multithreaded xz decompression, since that commit is still in staging-next. We cannot use stdenv's unpackFile() because that does not allow us to specify the needed --exclude (and --strip-components=1 if we don't want to rely on glob matching). The hash changed because we now have a static base directory ("source") in the tarball, instead of whatever upstream provided us with (e.g. "chromium-120.0.6099.129").
2024-01-04 00:34:15 +00:00
recompressTarball = callPackage ./recompress-tarball.nix { };
});
browser = callPackage ./browser.nix {
inherit channel chromiumVersionAtLeast enableWideVine ungoogled;
};
# ungoogled-chromium is, contrary to its name, not a build of
# chromium. It is a patched copy of chromium's *source code*.
# Therefore, it needs to come from buildPackages, because it
# contains python scripts which get /nix/store/.../bin/python3
# patched into their shebangs.
ungoogled-chromium = pkgsBuildBuild.callPackage ./ungoogled.nix {};
};
suffix = lib.optionalString (channel != "stable" && channel != "ungoogled-chromium") ("-" + channel);
sandboxExecutableName = chromium.browser.passthru.sandboxExecutableName;
# We want users to be able to enableWideVine without rebuilding all of
# chromium, so we have a separate derivation here that copies chromium
# and adds the unfree WidevineCdm.
chromiumWV = let browser = chromium.browser; in if enableWideVine then
runCommand (browser.name + "-wv") { version = browser.version; }
''
mkdir -p $out
cp -a ${browser}/* $out/
chmod u+w $out/libexec/chromium
cp -a ${widevine-cdm}/share/google/chrome/WidevineCdm $out/libexec/chromium/
''
else browser;
in stdenv.mkDerivation {
2022-03-22 16:57:23 +00:00
pname = lib.optionalString ungoogled "ungoogled-"
+ "chromium${suffix}";
inherit (chromium.browser) version;
nativeBuildInputs = [
makeWrapper ed
];
buildInputs = [
# needed for GSETTINGS_SCHEMAS_PATH
2023-04-28 19:42:59 +00:00
gsettings-desktop-schemas glib gtk3 gtk4
# needed for XDG_ICON_DIRS
gnome.adwaita-icon-theme
2022-02-11 18:51:42 +00:00
# Needed for kerberos at runtime
libkrb5
];
outputs = ["out" "sandbox"];
buildCommand = let
browserBinary = "${chromiumWV}/libexec/chromium/chromium";
libPath = lib.makeLibraryPath [ libva pipewire wayland gtk3 gtk4 libkrb5 ];
2021-01-15 13:21:58 +00:00
in with lib; ''
mkdir -p "$out/bin"
2022-02-02 11:07:18 +00:00
makeWrapper "${browserBinary}" "$out/bin/chromium" \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations}}" \
--add-flags ${escapeShellArg commandLineArgs}
ed -v -s "$out/bin/chromium" << EOF
2i
if [ -x "/run/wrappers/bin/${sandboxExecutableName}" ]
then
export CHROME_DEVEL_SANDBOX="/run/wrappers/bin/${sandboxExecutableName}"
else
export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}"
fi
# Make generated desktop shortcuts have a valid executable name.
export CHROME_WRAPPER='chromium'
'' + lib.optionalString (libPath != "") ''
# To avoid loading .so files from cwd, LD_LIBRARY_PATH here must not
# contain an empty section before or after a colon.
export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH\''${LD_LIBRARY_PATH:+:}${libPath}"
'' + ''
# libredirect causes chromium to deadlock on startup
export LD_PRELOAD="\$(echo -n "\$LD_PRELOAD" | ${coreutils}/bin/tr ':' '\n' | ${gnugrep}/bin/grep -v /lib/libredirect\\\\.so$ | ${coreutils}/bin/tr '\n' ':')"
export XDG_DATA_DIRS=$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH\''${XDG_DATA_DIRS:+:}\$XDG_DATA_DIRS
'' + lib.optionalString (!xdg-utils.meta.broken) ''
# Mainly for xdg-open but also other xdg-* tools (this is only a fallback; \$PATH is suffixed so that other implementations can be used):
export PATH="\$PATH\''${PATH:+:}${xdg-utils}/bin"
'' + ''
.
w
EOF
ln -sv "${chromium.browser.sandbox}" "$sandbox"
ln -s "$out/bin/chromium" "$out/bin/chromium-browser"
mkdir -p "$out/share"
for f in '${chromium.browser}'/share/*; do # hello emacs */
ln -s -t "$out/share/" "$f"
done
'';
inherit (chromium.browser) packageName;
meta = chromium.browser.meta;
passthru = {
inherit (chromium) upstream-info browser;
mkDerivation = chromium.mkChromiumDerivation;
inherit sandboxExecutableName;
};
}
# the following is a complicated and long-winded variant of
# `inherit (chromium.browser) version`, with the added benefit
# that it keeps the pointer to upstream-info.nix for
# builtins.unsafeGetAttrPos, which is what ofborg uses to
# decide which maintainers need to be pinged.
// builtins.removeAttrs chromium.browser (builtins.filter (e: e != "version") (builtins.attrNames chromium.browser))