nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 chromium,
5 fetchNpmDeps,
6 fetchpatch,
7
8 pkgsBuildHost,
9 gclient2nix,
10 nodejs,
11 npmHooks,
12 yarn-berry_4,
13 unzip,
14
15 libnotify,
16 libpulseaudio,
17 libsecret,
18 pipewire,
19 speechd-minimal,
20
21 info,
22}:
23
24let
25 gclientDeps = gclient2nix.importGclientDeps info.deps;
26 yarn-berry = yarn-berry_4;
27in
28
29((chromium.override { upstream-info = info.chromium; }).mkDerivation (base: {
30 packageName = "electron";
31 inherit (info) version;
32
33 buildTargets = [
34 "electron:copy_node_headers"
35 "electron:electron_dist_zip"
36 ];
37
38 outputs = [
39 "out"
40 "headers"
41 ];
42
43 # don't automatically move the include directory from $headers back into $out
44 moveToDev = false;
45
46 nativeBuildInputs = base.nativeBuildInputs ++ [
47 gclient2nix.gclientUnpackHook
48 nodejs
49 npmHooks.npmConfigHook
50 yarn-berry
51 yarn-berry.yarnBerryConfigHook
52 unzip
53 ];
54
55 buildInputs = base.buildInputs ++ [ libnotify ];
56
57 npmDeps = fetchNpmDeps rec {
58 src = gclientDeps."src".path;
59 # Assume that the fetcher always unpack the source,
60 # based on update.py
61 sourceRoot = "${src.name}/third_party/node";
62 hash = info.chromium_npm_hash;
63 };
64
65 npmRoot = "third_party/node";
66
67 yarnOfflineCache = yarn-berry.fetchYarnBerryDeps {
68 src = gclientDeps."src/electron".path;
69 hash = info.electron_yarn_hash;
70 };
71
72 dontYarnBerryInstallDeps = true; # we'll run the hook manually
73
74 inherit gclientDeps;
75 unpackPhase = null; # prevent chromium's unpackPhase from being used
76 sourceRoot = "src";
77
78 env = base.env // {
79 # Hydra can fail to build electron due to clang spamming deprecation
80 # warnings mid-build, causing the build log to grow beyond the limit
81 # of 64mb and then getting killed by Hydra.
82 # For some reason, the log size limit appears to only be enforced on
83 # aarch64-linux. x86_64-linux happily succeeds to build with ~180mb. To
84 # unbreak the build on h.n.o, we simply disable those warnings for now.
85 # https://hydra.nixos.org/build/283952243
86 NIX_CFLAGS_COMPILE = base.env.NIX_CFLAGS_COMPILE + " -Wno-deprecated";
87 # Needed for header generation in electron 35 and above
88 ELECTRON_OUT_DIR = "Release";
89 };
90
91 src = null;
92
93 patches =
94 base.patches
95 ++ lib.optionals (lib.versionOlder info.version "38") [
96 # Fix build with Rust 1.89.0
97 # https://chromium-review.googlesource.com/c/chromium/src/+/6624733
98 (fetchpatch {
99 name = "Define-rust-no-alloc-shim-is-unstable-v2.patch";
100 url = "https://github.com/chromium/chromium/commit/6aae0e2353c857d98980ff677bf304288d7c58de.patch";
101 hash = "sha256-Dd38c/0hiH+PbGPJhhEFuW6kUR45A36XZqOVExoxlhM=";
102 })
103 # Fix build with LLVM 21+
104 # https://chromium-review.googlesource.com/c/chromium/src/+/6633292
105 (fetchpatch {
106 name = "Dont-return-an-enum-from-EnumSizeTraits-Count.patch";
107 url = "https://github.com/chromium/chromium/commit/b0ff8c3b258a8816c05bdebf472dbba719d3c491.patch";
108 hash = "sha256-YIWcsCj5w0jUd7D67hsuk0ljTA/IbHwA6db3eK4ggUY=";
109 })
110 ]
111 ++ lib.optionals (lib.versionOlder info.version "39") [
112 # Fix build with Rust 1.90.0
113 # https://chromium-review.googlesource.com/c/chromium/src/+/6875644
114 (fetchpatch {
115 name = "Define-rust-alloc-error-handler-should-panic-v2.patch";
116 url = "https://github.com/chromium/chromium/commit/23d818d3c7fba4658248f17fd7b8993199242aa9.patch";
117 hash = "sha256-JVv36PgU/rr34jrhgCyf4Pp8o5j2T8fD1xBVH1avT48=";
118 })
119 # Fix build with Rust 1.91.0
120 # https://chromium-review.googlesource.com/c/chromium/src/+/6949745
121 (fetchpatch {
122 name = "Remove-unicode_width-from-rust-dependencies.patch";
123 url = "https://github.com/chromium/chromium/commit/0420449584e2afb7473393f536379efe194ba23c.patch";
124 hash = "sha256-2x1QoKkZEBfJw0hBjaErN/E47WrVfZvDngAXSIDzJs4=";
125 })
126 (fetchpatch {
127 name = "CrabbyAvif-Switch-from-no_sanitize-cfi-to-sanitize-cfi-off-1.patch";
128 url = "https://github.com/webmproject/CrabbyAvif/commit/4c70b98d1ebc8a210f2919be7ccabbcf23061cb5.patch";
129 extraPrefix = "third_party/crabbyavif/src/";
130 stripLen = 1;
131 hash = "sha256-E8/PmL+8+ZSoDO6L0/YOygIsliCDmcaBptXsi2L6ETQ=";
132 })
133 # backport of https://github.com/webmproject/CrabbyAvif/commit/3ba05863e84fd3acb4f4af2b4545221b317a2e55
134 ./CrabbyAvif-Switch-from-no_sanitize-cfi-to-sanitize-cfi-off-2.patch
135 # https://chromium-review.googlesource.com/c/chromium/src/+/6879484
136 (fetchpatch {
137 name = "crabbyavif-BUILD-gn-Temporarily-remove-disable_cfi-feature.patch";
138 url = "https://github.com/chromium/chromium/commit/e46275404d8f8a65ed84b3e583e9b78e4298acc7.patch";
139 hash = "sha256-2Dths53ervzCPKFbAVxeBHxtPHckxYhesJhaYZbxGSA=";
140 })
141 # https://chromium-review.googlesource.com/c/chromium/src/+/6960510
142 (fetchpatch {
143 name = "crabbyavif-BUILD-gn-Enable-disable_cfi-feature.patch";
144 url = "https://github.com/chromium/chromium/commit/9415f40bc6f853547f791e633be638c71368ce56.patch";
145 hash = "sha256-+M4gI77SoQ4dYIe/iGFgIwF1fS/6KQ8s16vj8ht/rik=";
146 })
147 ];
148
149 postPatch = ''
150 mkdir -p third_party/jdk/current/bin
151
152 echo 'build_with_chromium = true' >> build/config/gclient_args.gni
153 echo 'checkout_google_benchmark = false' >> build/config/gclient_args.gni
154 echo 'checkout_android = false' >> build/config/gclient_args.gni
155 echo 'checkout_android_prebuilts_build_tools = false' >> build/config/gclient_args.gni
156 echo 'checkout_android_native_support = false' >> build/config/gclient_args.gni
157 echo 'checkout_ios_webkit = false' >> build/config/gclient_args.gni
158 echo 'checkout_nacl = false' >> build/config/gclient_args.gni
159 echo 'checkout_openxr = false' >> build/config/gclient_args.gni
160 echo 'checkout_rts_model = false' >> build/config/gclient_args.gni
161 echo 'checkout_src_internal = false' >> build/config/gclient_args.gni
162 echo 'cros_boards = ""' >> build/config/gclient_args.gni
163 echo 'cros_boards_with_qemu_images = ""' >> build/config/gclient_args.gni
164 echo 'generate_location_tags = true' >> build/config/gclient_args.gni
165
166 echo 'LASTCHANGE=${info.deps."src".args.tag}-refs/heads/master@{#0}' > build/util/LASTCHANGE
167 echo "$SOURCE_DATE_EPOCH" > build/util/LASTCHANGE.committime
168
169 cat << EOF > gpu/config/gpu_lists_version.h
170 /* Generated by lastchange.py, do not edit.*/
171 #ifndef GPU_CONFIG_GPU_LISTS_VERSION_H_
172 #define GPU_CONFIG_GPU_LISTS_VERSION_H_
173 #define GPU_LISTS_VERSION "${info.deps."src".args.tag}"
174 #endif // GPU_CONFIG_GPU_LISTS_VERSION_H_
175 EOF
176
177 cat << EOF > skia/ext/skia_commit_hash.h
178 /* Generated by lastchange.py, do not edit.*/
179 #ifndef SKIA_EXT_SKIA_COMMIT_HASH_H_
180 #define SKIA_EXT_SKIA_COMMIT_HASH_H_
181 #define SKIA_COMMIT_HASH "${info.deps."src/third_party/skia".args.rev}-"
182 #endif // SKIA_EXT_SKIA_COMMIT_HASH_H_
183 EOF
184
185 echo -n '${info.deps."src/third_party/dawn".args.rev}' > gpu/webgpu/DAWN_VERSION
186 ''
187 + lib.optionalString (lib.versionAtLeast info.version "39") ''
188 cat << EOF > gpu/webgpu/dawn_commit_hash.h
189 /* Generated by lastchange.py, do not edit.*/
190 #ifndef GPU_WEBGPU_DAWN_COMMIT_HASH_H_
191 #define GPU_WEBGPU_DAWN_COMMIT_HASH_H_
192 #define DAWN_COMMIT_HASH "${info.deps."src/third_party/dawn".args.rev}"
193 #endif // GPU_WEBGPU_DAWN_COMMIT_HASH_H_
194 EOF
195 ''
196 + ''
197 (
198 cd electron
199 YARN_ENABLE_SCRIPTS=0 yarnBerryConfigHook
200 )
201 (
202 cd ..
203 PATH=$PATH:${
204 lib.makeBinPath (
205 with pkgsBuildHost;
206 [
207 jq
208 git
209 ]
210 )
211 }
212 config=src/electron/patches/config.json
213 for entry in $(cat $config | jq -c ".[]")
214 do
215 patch_dir=$(echo $entry | jq -r ".patch_dir")
216 repo=$(echo $entry | jq -r ".repo")
217 for patch in $(cat $patch_dir/.patches)
218 do
219 echo applying in $repo: $patch
220 git apply -p1 --directory=$repo --exclude='src/third_party/blink/web_tests/*' --exclude='src/content/test/data/*' $patch_dir/$patch
221 done
222 done
223 )
224 echo 'checkout_glic_e2e_tests = false' >> build/config/gclient_args.gni
225 echo 'checkout_mutter = false' >> build/config/gclient_args.gni
226 ''
227 + lib.optionalString (lib.versionAtLeast info.version "38") ''
228 echo 'checkout_clusterfuzz_data = false' >> build/config/gclient_args.gni
229 ''
230 + base.postPatch;
231
232 preConfigure = ''
233 (
234 cd third_party/node
235 grep patch update_npm_deps | sh
236 )
237 ''
238 + (base.preConfigure or "");
239
240 gnFlags = rec {
241 # build/args/release.gn
242 is_component_build = false;
243 is_official_build = true;
244 rtc_use_h264 = proprietary_codecs;
245 is_component_ffmpeg = true;
246
247 # build/args/all.gn
248 is_electron_build = true;
249 root_extra_deps = [ "//electron" ];
250 node_module_version = lib.toInt info.modules;
251 v8_promise_internal_field_count = 1;
252 v8_embedder_string = "-electron.0";
253 v8_enable_snapshot_native_code_counters = false;
254 v8_enable_javascript_promise_hooks = true;
255 enable_cdm_host_verification = false;
256 proprietary_codecs = true;
257 ffmpeg_branding = "Chrome";
258 enable_printing = true;
259 angle_enable_vulkan_validation_layers = false;
260 dawn_enable_vulkan_validation_layers = false;
261 enable_pseudolocales = false;
262 allow_runtime_configurable_key_storage = true;
263 enable_cet_shadow_stack = false;
264 is_cfi = false;
265 v8_builtins_profiling_log_file = "";
266 enable_dangling_raw_ptr_checks = false;
267 dawn_use_built_dxc = false;
268 v8_enable_private_mapping_fork_optimization = true;
269 v8_expose_public_symbols = true;
270 enable_dangling_raw_ptr_feature_flag = false;
271 clang_unsafe_buffers_paths = "";
272 enterprise_cloud_content_analysis = false;
273 }
274 // lib.optionalAttrs (lib.versionAtLeast info.version "39") {
275 enable_linux_installer = false;
276 enable_pdf_save_to_drive = false;
277 }
278 // {
279
280 # other
281 enable_widevine = false;
282 override_electron_version = info.version;
283 }
284 // lib.optionalAttrs (lib.versionOlder info.version "38") {
285 content_enable_legacy_ipc = true;
286 };
287
288 installPhase = ''
289 runHook preInstall
290
291 mkdir -p $libExecPath
292 unzip -d $libExecPath out/Release/dist.zip
293
294 mkdir -p $headers
295 cp -r out/Release/gen/node_headers/* $headers/
296
297 runHook postInstall
298 '';
299
300 postFixup =
301 let
302 libPath = lib.makeLibraryPath [
303 libnotify
304 pipewire
305 stdenv.cc.cc
306 libsecret
307 libpulseaudio
308 speechd-minimal
309 ];
310 in
311 base.postFixup
312 + ''
313 patchelf \
314 --add-rpath "${libPath}" \
315 $out/libexec/electron/electron
316 '';
317
318 requiredSystemFeatures = [ "big-parallel" ];
319
320 passthru = {
321 inherit info;
322 };
323
324 meta = {
325 description = "Cross platform desktop application shell";
326 homepage = "https://github.com/electron/electron";
327 platforms = lib.platforms.linux;
328 license = lib.licenses.mit;
329 teams = [ lib.teams.electron ];
330 mainProgram = "electron";
331 hydraPlatforms =
332 lib.optionals (!(lib.hasInfix "alpha" info.version) && !(lib.hasInfix "beta" info.version))
333 [
334 "aarch64-linux"
335 "x86_64-linux"
336 ];
337 timeout = 172800; # 48 hours (increased from the Hydra default of 10h)
338 };
339})).overrideAttrs
340 (
341 finalAttrs: prevAttrs: {
342 # this was the only way I could get the package to properly reference itself
343 passthru = prevAttrs.passthru // {
344 dist = finalAttrs.finalPackage + "/libexec/electron";
345 };
346 }
347 )