1 { newScope, config, stdenv, makeWrapper
3 , ed, gnugrep, coreutils, xdg-utils
4 , glib, gtk3, gtk4, adwaita-icon-theme, gsettings-desktop-schemas, gn, fetchgit
5 , libva, pipewire, wayland
9 , electron-source # for warnObsoleteVersionConditional
11 # package customization
12 # Note: enable* flags should not require full rebuilds (i.e. only affect the wrapper)
14 , upstream-info ? (import ./upstream-info.nix).${channel}
15 , proprietaryCodecs ? true
16 , enableWideVine ? false
17 , ungoogled ? false # Whether to build chromium or ungoogled-chromium
19 , pulseSupport ? config.pulseaudio or stdenv.hostPlatform.isLinux
20 , commandLineArgs ? ""
26 stdenv = pkgs.rustc.llvmPackages.stdenv;
28 # Helper functions for changes that depend on specific versions:
29 warnObsoleteVersionConditional = min-version: result:
30 let min-supported-version = (lib.head (lib.attrValues electron-source)).unwrapped.info.chromium.version;
32 (lib.versionAtLeast min-supported-version min-version)
33 "chromium: min-supported-version ${min-supported-version} is newer than a conditional bounded at ${min-version}. You can safely delete it."
35 chromiumVersionAtLeast = min-version:
36 let result = lib.versionAtLeast upstream-info.version min-version;
37 in warnObsoleteVersionConditional min-version result;
38 versionRange = min-version: upto-version:
39 let inherit (upstream-info) version;
40 result = lib.versionAtLeast version min-version && lib.versionOlder version upto-version;
41 in warnObsoleteVersionConditional upto-version result;
43 callPackage = newScope chromium;
46 inherit stdenv upstream-info;
48 mkChromiumDerivation = callPackage ./common.nix ({
49 inherit channel chromiumVersionAtLeast versionRange;
50 inherit proprietaryCodecs
51 cupsSupport pulseSupport ungoogled;
52 gnChromium = buildPackages.gn.overrideAttrs (oldAttrs: {
53 inherit (upstream-info.deps.gn) version;
55 inherit (upstream-info.deps.gn) url rev hash;
57 } // lib.optionalAttrs (chromiumVersionAtLeast "127") {
58 # Relax hardening as otherwise gn unstable 2024-06-06 and later fail with:
59 # cc1plus: error: '-Wformat-security' ignored without '-Wformat' [-Werror=format-security]
60 hardeningDisable = [ "format" ];
61 } // lib.optionalAttrs (chromiumVersionAtLeast "130") {
62 # At the time of writing, gn is at v2024-05-13 and has a backported patch.
63 # This patch appears to be already present in v2024-09-09 (from M130), which
64 # results in the patch not applying and thus failing the build.
65 # As a work around until gn is updated again, we filter specifically that patch out.
66 patches = lib.filter (e: lib.getName e != "LFS64.patch") oldAttrs.patches;
68 recompressTarball = callPackage ./recompress-tarball.nix { inherit chromiumVersionAtLeast; };
71 browser = callPackage ./browser.nix {
72 inherit channel chromiumVersionAtLeast enableWideVine ungoogled;
75 # ungoogled-chromium is, contrary to its name, not a build of
76 # chromium. It is a patched copy of chromium's *source code*.
77 # Therefore, it needs to come from buildPackages, because it
78 # contains python scripts which get /nix/store/.../bin/python3
79 # patched into their shebangs.
80 ungoogled-chromium = pkgsBuildBuild.callPackage ./ungoogled.nix {};
83 suffix = lib.optionalString (channel != "stable" && channel != "ungoogled-chromium") ("-" + channel);
85 sandboxExecutableName = chromium.browser.passthru.sandboxExecutableName;
87 # We want users to be able to enableWideVine without rebuilding all of
88 # chromium, so we have a separate derivation here that copies chromium
89 # and adds the unfree WidevineCdm.
90 chromiumWV = let browser = chromium.browser; in if enableWideVine then
91 runCommand (browser.name + "-wv") { version = browser.version; }
94 cp -a ${browser}/* $out/
95 chmod u+w $out/libexec/chromium
96 cp -a ${widevine-cdm}/share/google/chrome/WidevineCdm $out/libexec/chromium/
100 in stdenv.mkDerivation {
101 pname = lib.optionalString ungoogled "ungoogled-"
102 + "chromium${suffix}";
103 inherit (chromium.browser) version;
105 nativeBuildInputs = [
110 # needed for GSETTINGS_SCHEMAS_PATH
111 gsettings-desktop-schemas glib gtk3 gtk4
113 # needed for XDG_ICON_DIRS
116 # Needed for kerberos at runtime
120 outputs = ["out" "sandbox"];
123 browserBinary = "${chromiumWV}/libexec/chromium/chromium";
124 libPath = lib.makeLibraryPath [ libva pipewire wayland gtk3 gtk4 libkrb5 ];
129 makeWrapper "${browserBinary}" "$out/bin/chromium" \
130 --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations}}" \
131 --add-flags ${lib.escapeShellArg commandLineArgs}
133 ed -v -s "$out/bin/chromium" << EOF
136 if [ -x "/run/wrappers/bin/${sandboxExecutableName}" ]
138 export CHROME_DEVEL_SANDBOX="/run/wrappers/bin/${sandboxExecutableName}"
140 export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}"
143 # Make generated desktop shortcuts have a valid executable name.
144 export CHROME_WRAPPER='chromium'
146 '' + lib.optionalString (libPath != "") ''
147 # To avoid loading .so files from cwd, LD_LIBRARY_PATH here must not
148 # contain an empty section before or after a colon.
149 export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH\''${LD_LIBRARY_PATH:+:}${libPath}"
152 # libredirect causes chromium to deadlock on startup
153 export LD_PRELOAD="\$(echo -n "\$LD_PRELOAD" | ${coreutils}/bin/tr ':' '\n' | ${gnugrep}/bin/grep -v /lib/libredirect\\\\.so$ | ${coreutils}/bin/tr '\n' ':')"
155 export XDG_DATA_DIRS=$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH\''${XDG_DATA_DIRS:+:}\$XDG_DATA_DIRS
157 '' + lib.optionalString (!xdg-utils.meta.broken) ''
158 # Mainly for xdg-open but also other xdg-* tools (this is only a fallback; \$PATH is suffixed so that other implementations can be used):
159 export PATH="\$PATH\''${PATH:+:}${xdg-utils}/bin"
166 ln -sv "${chromium.browser.sandbox}" "$sandbox"
168 ln -s "$out/bin/chromium" "$out/bin/chromium-browser"
170 mkdir -p "$out/share"
171 for f in '${chromium.browser}'/share/*; do # hello emacs */
172 ln -s -t "$out/share/" "$f"
176 inherit (chromium.browser) packageName;
177 meta = chromium.browser.meta;
179 inherit (chromium) upstream-info browser;
180 mkDerivation = chromium.mkChromiumDerivation;
181 inherit sandboxExecutableName;
184 # the following is a complicated and long-winded variant of
185 # `inherit (chromium.browser) version`, with the added benefit
186 # that it keeps the pointer to upstream-info.nix for
187 # builtins.unsafeGetAttrPos, which is what ofborg uses to
188 # decide which maintainers need to be pinged.
189 // builtins.removeAttrs chromium.browser (builtins.filter (e: e != "version") (builtins.attrNames chromium.browser))