1{
2 newScope,
3 config,
4 stdenv,
5 makeWrapper,
6 buildPackages,
7 ed,
8 gnugrep,
9 coreutils,
10 xdg-utils,
11 glib,
12 gtk3,
13 gtk4,
14 adwaita-icon-theme,
15 gsettings-desktop-schemas,
16 gn,
17 fetchgit,
18 libva,
19 pipewire,
20 wayland,
21 runCommand,
22 lib,
23 libkrb5,
24 widevine-cdm,
25 electron-source, # for warnObsoleteVersionConditional
26
27 # package customization
28 # Note: enable* flags should not require full rebuilds (i.e. only affect the wrapper)
29 upstream-info ?
30 (lib.importJSON ./info.json).${if !ungoogled then "chromium" else "ungoogled-chromium"},
31 proprietaryCodecs ? true,
32 enableWideVine ? false,
33 ungoogled ? false, # Whether to build chromium or ungoogled-chromium
34 cupsSupport ? true,
35 pulseSupport ? config.pulseaudio or stdenv.hostPlatform.isLinux,
36 commandLineArgs ? "",
37 pkgsBuildBuild,
38 pkgs,
39}:
40
41let
42 stdenv = pkgs.rustc.llvmPackages.stdenv;
43
44 # Helper functions for changes that depend on specific versions:
45 warnObsoleteVersionConditional =
46 min-version: result:
47 let
48 min-supported-version = (lib.head (lib.attrValues electron-source)).unwrapped.info.chromium.version;
49 # Warning can be toggled by changing the value of enabled:
50 enabled = false;
51 in
52 lib.warnIf (enabled && lib.versionAtLeast min-supported-version min-version)
53 "chromium: min-supported-version ${min-supported-version} is newer than a conditional bounded at ${min-version}. You can safely delete it."
54 result;
55 chromiumVersionAtLeast =
56 min-version:
57 let
58 result = lib.versionAtLeast upstream-info.version min-version;
59 in
60 warnObsoleteVersionConditional min-version result;
61 versionRange =
62 min-version: upto-version:
63 let
64 inherit (upstream-info) version;
65 result = lib.versionAtLeast version min-version && lib.versionOlder version upto-version;
66 in
67 warnObsoleteVersionConditional upto-version result;
68
69 callPackage = newScope chromium;
70
71 chromium = rec {
72 inherit stdenv upstream-info;
73
74 mkChromiumDerivation = callPackage ./common.nix ({
75 inherit chromiumVersionAtLeast versionRange;
76 inherit
77 proprietaryCodecs
78 cupsSupport
79 pulseSupport
80 ungoogled
81 ;
82 gnChromium = buildPackages.gn.overrideAttrs (oldAttrs: {
83 version = if (upstream-info.deps.gn ? "version") then upstream-info.deps.gn.version else "0";
84 src = fetchgit {
85 url = "https://gn.googlesource.com/gn";
86 inherit (upstream-info.deps.gn) rev hash;
87 };
88 });
89 });
90
91 browser = callPackage ./browser.nix {
92 inherit chromiumVersionAtLeast enableWideVine ungoogled;
93 };
94
95 # ungoogled-chromium is, contrary to its name, not a build of
96 # chromium. It is a patched copy of chromium's *source code*.
97 # Therefore, it needs to come from buildPackages, because it
98 # contains python scripts which get /nix/store/.../bin/python3
99 # patched into their shebangs.
100 ungoogled-chromium = pkgsBuildBuild.callPackage ./ungoogled.nix { };
101 };
102
103 sandboxExecutableName = chromium.browser.passthru.sandboxExecutableName;
104
105 # We want users to be able to enableWideVine without rebuilding all of
106 # chromium, so we have a separate derivation here that copies chromium
107 # and adds the unfree WidevineCdm.
108 chromiumWV =
109 let
110 browser = chromium.browser;
111 in
112 if enableWideVine then
113 runCommand (browser.name + "-wv") { version = browser.version; } ''
114 mkdir -p $out
115 cp -a ${browser}/* $out/
116 chmod u+w $out/libexec/chromium
117 cp -a ${widevine-cdm}/share/google/chrome/WidevineCdm $out/libexec/chromium/
118 ''
119 else
120 browser;
121
122in
123stdenv.mkDerivation {
124 pname = lib.optionalString ungoogled "ungoogled-" + "chromium";
125 inherit (chromium.browser) version;
126
127 nativeBuildInputs = [
128 makeWrapper
129 ed
130 ];
131
132 buildInputs = [
133 # needed for GSETTINGS_SCHEMAS_PATH
134 gsettings-desktop-schemas
135 glib
136 gtk3
137 gtk4
138
139 # needed for XDG_ICON_DIRS
140 adwaita-icon-theme
141
142 # Needed for kerberos at runtime
143 libkrb5
144 ];
145
146 outputs = [
147 "out"
148 "sandbox"
149 ];
150
151 buildCommand =
152 let
153 browserBinary = "${chromiumWV}/libexec/chromium/chromium";
154 libPath = lib.makeLibraryPath [
155 libva
156 pipewire
157 wayland
158 gtk3
159 gtk4
160 libkrb5
161 ];
162
163 in
164 ''
165 mkdir -p "$out/bin"
166
167 makeWrapper "${browserBinary}" "$out/bin/chromium" \
168 --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}" \
169 --add-flags ${lib.escapeShellArg commandLineArgs}
170
171 ed -v -s "$out/bin/chromium" << EOF
172 2i
173
174 if [ -x "/run/wrappers/bin/${sandboxExecutableName}" ]
175 then
176 export CHROME_DEVEL_SANDBOX="/run/wrappers/bin/${sandboxExecutableName}"
177 else
178 export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}"
179 fi
180
181 # Make generated desktop shortcuts have a valid executable name.
182 export CHROME_WRAPPER='chromium'
183
184 ''
185 + lib.optionalString (libPath != "") ''
186 # To avoid loading .so files from cwd, LD_LIBRARY_PATH here must not
187 # contain an empty section before or after a colon.
188 export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH\''${LD_LIBRARY_PATH:+:}${libPath}"
189 ''
190 + ''
191
192 # libredirect causes chromium to deadlock on startup
193 export LD_PRELOAD="\$(echo -n "\$LD_PRELOAD" | ${coreutils}/bin/tr ':' '\n' | ${gnugrep}/bin/grep -v /lib/libredirect\\\\.so$ | ${coreutils}/bin/tr '\n' ':')"
194
195 export XDG_DATA_DIRS=$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH\''${XDG_DATA_DIRS:+:}\$XDG_DATA_DIRS
196
197 ''
198 + lib.optionalString (!xdg-utils.meta.broken) ''
199 # Mainly for xdg-open but also other xdg-* tools (this is only a fallback; \$PATH is suffixed so that other implementations can be used):
200 export PATH="\$PATH\''${PATH:+:}${xdg-utils}/bin"
201 ''
202 + ''
203
204 .
205 w
206 EOF
207
208 ln -sv "${chromium.browser.sandbox}" "$sandbox"
209
210 ln -s "$out/bin/chromium" "$out/bin/chromium-browser"
211
212 mkdir -p "$out/share"
213 for f in '${chromium.browser}'/share/*; do # hello emacs */
214 ln -s -t "$out/share/" "$f"
215 done
216 '';
217
218 inherit (chromium.browser) packageName;
219 meta = chromium.browser.meta;
220 passthru = {
221 inherit (chromium) upstream-info browser;
222 mkDerivation = chromium.mkChromiumDerivation;
223 inherit sandboxExecutableName;
224 };
225}