1{
2 stdenv,
3 lib,
4 fetchpatch,
5 zstd,
6 fetchFromGitiles,
7 fetchNpmDeps,
8 buildPackages,
9 pkgsBuildBuild,
10 # Channel data:
11 upstream-info,
12 # Helper functions:
13 chromiumVersionAtLeast,
14 versionRange,
15
16 # Native build inputs:
17 ninja,
18 bashInteractive,
19 pkg-config,
20 python3,
21 perl,
22 nodejs,
23 npmHooks,
24 which,
25 libuuid,
26 overrideCC,
27 # postPatch:
28 pkgsBuildHost,
29 # configurePhase:
30 gnChromium,
31 symlinkJoin,
32
33 # Build inputs:
34 libpng,
35 bzip2,
36 flac,
37 speex,
38 libopus,
39 libevent,
40 expat,
41 libjpeg,
42 snappy,
43 libcap,
44 minizip,
45 libwebp,
46 libusb1,
47 re2,
48 ffmpeg,
49 libxslt,
50 libxml2,
51 nasm,
52 nspr,
53 nss,
54 util-linux,
55 alsa-lib,
56 bison,
57 gperf,
58 libkrb5,
59 glib,
60 gtk3,
61 dbus-glib,
62 libXScrnSaver,
63 libXcursor,
64 libXtst,
65 libxshmfence,
66 libGLU,
67 libGL,
68 dri-pkgconfig-stub,
69 libgbm,
70 pciutils,
71 protobuf,
72 speechd-minimal,
73 libXdamage,
74 at-spi2-core,
75 pipewire,
76 libva,
77 libdrm,
78 wayland,
79 libxkbcommon, # Ozone
80 curl,
81 libffi,
82 libepoxy,
83 libevdev,
84 # postPatch:
85 glibc, # gconv + locale
86 # postFixup:
87 vulkan-loader,
88
89 # Package customization:
90 cupsSupport ? true,
91 cups ? null,
92 proprietaryCodecs ? true,
93 pulseSupport ? false,
94 libpulseaudio ? null,
95 ungoogled ? false,
96 ungoogled-chromium,
97 # Optional dependencies:
98 libgcrypt ? null, # cupsSupport
99 systemdSupport ? lib.meta.availableOn stdenv.hostPlatform systemd,
100 systemd,
101}:
102
103buildFun:
104
105let
106 python3WithPackages = python3.pythonOnBuildForHost.withPackages (
107 ps: with ps; [
108 ply
109 jinja2
110 setuptools
111 ]
112 );
113
114 # The additional attributes for creating derivations based on the chromium
115 # source tree.
116 extraAttrs = buildFun base;
117
118 githubPatch =
119 {
120 commit,
121 hash,
122 revert ? false,
123 excludes ? [ ],
124 }:
125 fetchpatch {
126 url = "https://github.com/chromium/chromium/commit/${commit}.patch";
127 inherit hash revert excludes;
128 };
129
130 mkGnFlags =
131 let
132 # Serialize Nix types into GN types according to this document:
133 # https://source.chromium.org/gn/gn/+/master:docs/language.md
134 mkGnString = value: "\"${lib.escape [ "\"" "$" "\\" ] value}\"";
135 sanitize =
136 value:
137 if value == true then
138 "true"
139 else if value == false then
140 "false"
141 else if lib.isList value then
142 "[${lib.concatMapStringsSep ", " sanitize value}]"
143 else if lib.isInt value then
144 toString value
145 else if lib.isString value then
146 mkGnString value
147 else
148 throw "Unsupported type for GN value `${value}'.";
149 toFlag = key: value: "${key}=${sanitize value}";
150 in
151 attrs: lib.concatStringsSep " " (lib.attrValues (lib.mapAttrs toFlag attrs));
152
153 # https://source.chromium.org/chromium/chromium/src/+/master:build/linux/unbundle/replace_gn_files.py
154 gnSystemLibraries = [
155 # TODO:
156 # "ffmpeg"
157 # "snappy"
158 "flac"
159 "libjpeg"
160 "libpng"
161 # Use the vendored libwebp for M124+ until we figure out how to solve:
162 # Running phase: configurePhase
163 # ERROR Unresolved dependencies.
164 # //third_party/libavif:libavif_enc(//build/toolchain/linux/unbundle:default)
165 # needs //third_party/libwebp:libwebp_sharpyuv(//build/toolchain/linux/unbundle:default)
166 # "libwebp"
167 "libxslt"
168 # "opus"
169 ];
170
171 # build paths and release info
172 packageName = extraAttrs.packageName or extraAttrs.name;
173 buildType = "Release";
174 buildPath = "out/${buildType}";
175 libExecPath = "$out/libexec/${packageName}";
176
177 ungoogler = ungoogled-chromium {
178 inherit (upstream-info.deps.ungoogled-patches) rev hash;
179 };
180
181 # There currently isn't a (much) more concise way to get a stdenv
182 # that uses lld as its linker without bootstrapping pkgsLLVM; see
183 # https://github.com/NixOS/nixpkgs/issues/142901
184 buildPlatformLlvmStdenv =
185 let
186 llvmPackages = pkgsBuildBuild.rustc.llvmPackages;
187 in
188 overrideCC llvmPackages.stdenv (
189 llvmPackages.stdenv.cc.override {
190 inherit (llvmPackages) bintools;
191 }
192 );
193
194 chromiumRosettaStone = {
195 cpu =
196 platform:
197 let
198 name = platform.parsed.cpu.name;
199 in
200 (
201 {
202 "x86_64" = "x64";
203 "i686" = "x86";
204 "arm" = "arm";
205 "aarch64" = "arm64";
206 }
207 .${platform.parsed.cpu.name} or (throw "no chromium Rosetta Stone entry for cpu: ${name}")
208 );
209 os =
210 platform:
211 if platform.isLinux then
212 "linux"
213 else
214 throw "no chromium Rosetta Stone entry for os: ${platform.config}";
215 };
216
217 isElectron = packageName == "electron";
218 rustcVersion = buildPackages.rustc.version;
219
220 chromiumDeps = lib.mapAttrs (
221 path: args:
222 fetchFromGitiles (
223 removeAttrs args [ "recompress" ]
224 // lib.optionalAttrs args.recompress or false {
225 name = "source.tar.zstd";
226 downloadToTemp = false;
227 passthru.unpack = true;
228 nativeBuildInputs = [ zstd ];
229 postFetch = ''
230 tar \
231 --use-compress-program="zstd -T$NIX_BUILD_CORES" \
232 --sort=name \
233 --mtime="1970-01-01" \
234 --owner=root --group=root \
235 --numeric-owner --mode=go=rX,u+rw,a-s \
236 --remove-files \
237 --directory="$out" \
238 -cf "$TMPDIR/source.zstd" .
239 mv "$TMPDIR/source.zstd" "$out"
240 '';
241 }
242 )
243 ) upstream-info.DEPS;
244
245 unpackPhaseSnippet = lib.concatStrings (
246 lib.mapAttrsToList (
247 path: dep:
248 (
249 if dep.unpack or false then
250 ''
251 mkdir -p ${path}
252 pushd ${path}
253 unpackFile ${dep}
254 popd
255 ''
256 else
257 ''
258 mkdir -p ${builtins.dirOf path}
259 cp -r ${dep}/. ${path}
260 ''
261 )
262 + ''
263 chmod u+w -R ${path}
264 ''
265 ) chromiumDeps
266 );
267
268 base = rec {
269 pname = "${lib.optionalString ungoogled "ungoogled-"}${packageName}-unwrapped";
270 inherit (upstream-info) version;
271 inherit packageName buildType buildPath;
272
273 unpackPhase = ''
274 runHook preUnpack
275
276 ${unpackPhaseSnippet}
277 sourceRoot=src
278
279 runHook postUnpack
280 '';
281
282 npmRoot = "third_party/node";
283 npmDeps =
284 (fetchNpmDeps {
285 src = chromiumDeps."src";
286 sourceRoot = npmRoot;
287 hash = upstream-info.deps.npmHash;
288 }).overrideAttrs
289 (p: {
290 nativeBuildInputs = p.nativeBuildInputs or [ ] ++ [ zstd ];
291 });
292
293 nativeBuildInputs = [
294 ninja
295 gnChromium
296 bashInteractive # needed for compgen in buildPhase -> process_template
297 pkg-config
298 python3WithPackages
299 perl
300 which
301 buildPackages.rustc.llvmPackages.bintools
302 bison
303 gperf
304 ]
305 ++ lib.optionals (!isElectron) [
306 nodejs
307 npmHooks.npmConfigHook
308 ];
309
310 depsBuildBuild = [
311 buildPlatformLlvmStdenv
312 buildPlatformLlvmStdenv.cc
313 pkg-config
314 libuuid
315 ]
316 # When cross-compiling, chromium builds a huge proportion of its
317 # components for both the `buildPlatform` (which it calls
318 # `host`) as well as for the `hostPlatform` -- easily more than
319 # half of the dependencies are needed here. To avoid having to
320 # maintain a separate list of buildPlatform-dependencies, we
321 # simply throw in the kitchen sink.
322 # ** Because of overrides, we have to copy the list as it otherwise mess with splicing **
323 ++ [
324 (buildPackages.libpng.override { apngSupport = false; }) # https://bugs.chromium.org/p/chromium/issues/detail?id=752403
325 (buildPackages.libopus.override { withCustomModes = true; })
326 bzip2
327 flac
328 speex
329 libevent
330 expat
331 libjpeg
332 snappy
333 libcap
334 minizip
335 libwebp
336 libusb1
337 re2
338 ffmpeg
339 libxslt
340 libxml2
341 nasm
342 nspr
343 nss
344 util-linux
345 alsa-lib
346 libkrb5
347 glib
348 gtk3
349 dbus-glib
350 libXScrnSaver
351 libXcursor
352 libXtst
353 libxshmfence
354 libGLU
355 libGL
356 libgbm
357 pciutils
358 protobuf
359 speechd-minimal
360 libXdamage
361 at-spi2-core
362 pipewire
363 libva
364 libdrm
365 wayland
366 libxkbcommon
367 curl
368 libepoxy
369 libffi
370 libevdev
371 ]
372 ++ lib.optional systemdSupport systemd
373 ++ lib.optionals cupsSupport [
374 libgcrypt
375 cups
376 ]
377 ++ lib.optional pulseSupport libpulseaudio;
378
379 buildInputs = [
380 (libpng.override { apngSupport = false; }) # https://bugs.chromium.org/p/chromium/issues/detail?id=752403
381 (libopus.override { withCustomModes = true; })
382 bzip2
383 flac
384 speex
385 libevent
386 expat
387 libjpeg
388 snappy
389 libcap
390 minizip
391 libwebp
392 libusb1
393 re2
394 ffmpeg
395 libxslt
396 libxml2
397 nasm
398 nspr
399 nss
400 util-linux
401 alsa-lib
402 libkrb5
403 glib
404 gtk3
405 dbus-glib
406 libXScrnSaver
407 libXcursor
408 libXtst
409 libxshmfence
410 libGLU
411 libGL
412 dri-pkgconfig-stub
413 libgbm
414 pciutils
415 protobuf
416 speechd-minimal
417 libXdamage
418 at-spi2-core
419 pipewire
420 libva
421 libdrm
422 wayland
423 libxkbcommon
424 curl
425 libepoxy
426 libffi
427 libevdev
428 ]
429 ++ lib.optional systemdSupport systemd
430 ++ lib.optionals cupsSupport [
431 libgcrypt
432 cups
433 ]
434 ++ lib.optional pulseSupport libpulseaudio;
435
436 patches = [
437 ./patches/cross-compile.patch
438 # Optional patch to use SOURCE_DATE_EPOCH in compute_build_timestamp.py (should be upstreamed):
439 ./patches/no-build-timestamps.patch
440 ]
441 ++ lib.optionals (!chromiumVersionAtLeast "136") [
442 # Fix build with Pipewire 1.4
443 # Submitted upstream: https://webrtc-review.googlesource.com/c/src/+/380500
444 # Got merged, started shipping with M136+.
445 ./patches/webrtc-pipewire-1.4.patch
446 ]
447 ++ lib.optionals (packageName == "chromium") [
448 # This patch is limited to chromium and ungoogled-chromium because electron-source sets
449 # enable_widevine to false.
450 #
451 # The patch disables the automatic Widevine download (component) that happens at runtime
452 # completely (~/.config/chromium/WidevineCdm/). This would happen if chromium encounters DRM
453 # protected content or when manually opening chrome://components.
454 #
455 # It also prevents previously downloaded Widevine blobs in that location from being loaded and
456 # used at all, while still allowing the use of our -wv wrapper. This is because those old
457 # versions are out of out our control and may be vulnerable, given we literally disable their
458 # auto updater.
459 #
460 # bundle_widevine_cdm is available as gn flag, but we cannot use it, as it expects a bunch of
461 # files Widevine files at configure/compile phase that we don't have. Changing the value of the
462 # BUNDLE_WIDEVINE_CDM build flag does work in the way we want though.
463 # We also need enable_widevine_cdm_component to be false. Unfortunately it isn't exposed as gn
464 # flag (declare_args) so we simply hardcode it to false.
465 ./patches/widevine-disable-auto-download-allow-bundle.patch
466 ]
467 ++ [
468 # Required to fix the build with a more recent wayland-protocols version
469 # (we currently package 1.26 in Nixpkgs while Chromium bundles 1.21):
470 # Source: https://bugs.chromium.org/p/angleproject/issues/detail?id=7582#c1
471 ./patches/angle-wayland-include-protocol.patch
472 # Chromium reads initial_preferences from its own executable directory
473 # This patch modifies it to read /etc/chromium/initial_preferences
474 ./patches/chromium-initial-prefs.patch
475 # https://github.com/chromium/chromium/commit/02b6456643700771597c00741937e22068b0f956
476 # https://github.com/chromium/chromium/commit/69736ffe943ff996d4a88d15eb30103a8c854e29
477 # Rebased variant of patch to build M126+ with LLVM 17.
478 # staging-next will bump LLVM to 18, so we will be able to drop this soon.
479 ./patches/chromium-126-llvm-17.patch
480 # Partial revert of https://github.com/chromium/chromium/commit/3687976b0c6d36cf4157419a24a39f6770098d61
481 # allowing us to use our rustc and our clang.
482 ./patches/chromium-129-rust.patch
483 ]
484 ++ lib.optionals (!ungoogled && !chromiumVersionAtLeast "136") [
485 # Note: We since use LLVM v19.1+ on unstable *and* release-24.11 for all version and as such
486 # no longer need this patch. We opt to arbitrarily limit it to versions prior to M136 just
487 # because that's when this revert stopped applying cleanly and defer fully dropping it for
488 # the next cleanup to bundle rebuilding all of chromium and electron.
489 #
490 # Our rustc.llvmPackages is too old for std::hardware_destructive_interference_size
491 # and std::hardware_constructive_interference_size.
492 # So let's revert the change for now and hope that our rustc.llvmPackages and
493 # nixpkgs-stable catch up sooner than later.
494 # https://groups.google.com/a/chromium.org/g/cxx/c/cwktrFxxUY4
495 # https://chromium-review.googlesource.com/c/chromium/src/+/5767325
496 # Note: We exclude the changes made to the partition_allocator (PA), as the revert
497 # would otherwise not apply because upstream reverted those changes to PA already
498 # in https://chromium-review.googlesource.com/c/chromium/src/+/5841144
499 # Note: ungoogled-chromium already reverts this as part of its patchset.
500 (githubPatch {
501 commit = "fc838e8cc887adbe95110045d146b9d5885bf2a9";
502 hash = "sha256-NNKzIp6NYdeZaqBLWDW/qNxiDB1VFRz7msjMXuMOrZ8=";
503 excludes = [ "base/allocator/partition_allocator/src/partition_alloc/*" ];
504 revert = true;
505 })
506 ]
507 ++ lib.optionals stdenv.hostPlatform.isAarch64 [
508 # Reverts decommit pooled pages which causes random crashes of tabs on systems
509 # with page sizes different than 4k. It 'supports' runtime page sizes, but has
510 # a hardcode for aarch64 systems.
511 # https://issues.chromium.org/issues/378017037
512 (fetchpatch {
513 name = "reverted-v8-decommit-pooled-paged-by-default.patch";
514 # https://chromium-review.googlesource.com/c/v8/v8/+/5864909
515 url = "https://chromium.googlesource.com/v8/v8/+/1ab1a14ad97394d384d8dc6de51bb229625e66d6^!?format=TEXT";
516 decode = "base64 -d";
517 stripLen = 1;
518 extraPrefix = "v8/";
519 revert = true;
520 hash = "sha256-PuinMLhJ2W4KPXI5K0ujw85ENTB1wG7Hv785SZ55xnY=";
521 })
522 ]
523 ++ lib.optionals (chromiumVersionAtLeast "136") [
524 # Modify the nodejs version check added in https://chromium-review.googlesource.com/c/chromium/src/+/6334038
525 # to look for the minimal version, not the exact version (major.minor.patch). The linked CL makes a case for
526 # preventing compilations of chromium with versions below their intended version, not about running the very
527 # exact version or even running a newer version.
528 ./patches/chromium-136-nodejs-assert-minimal-version-instead-of-exact-match.patch
529 ];
530
531 postPatch =
532 lib.optionalString (!isElectron)
533 # TODO: reuse mkGnFlags for this
534 (
535 if (chromiumVersionAtLeast "136") then
536 ''
537 cp ${./files/gclient_args.gni} build/config/gclient_args.gni
538 chmod u+w build/config/gclient_args.gni
539 echo 'checkout_mutter = false' >> build/config/gclient_args.gni
540 echo 'checkout_glic_e2e_tests = false' >> build/config/gclient_args.gni
541 ''
542 else
543 ''
544 ln -s ${./files/gclient_args.gni} build/config/gclient_args.gni
545 ''
546 )
547 + lib.optionalString (!isElectron) ''
548
549 echo 'LASTCHANGE=${upstream-info.DEPS."src".rev}-refs/tags/${version}@{#0}' > build/util/LASTCHANGE
550 echo "$SOURCE_DATE_EPOCH" > build/util/LASTCHANGE.committime
551
552 cat << EOF > gpu/config/gpu_lists_version.h
553 /* Generated by lastchange.py, do not edit.*/
554 #ifndef GPU_CONFIG_GPU_LISTS_VERSION_H_
555 #define GPU_CONFIG_GPU_LISTS_VERSION_H_
556 #define GPU_LISTS_VERSION "${upstream-info.DEPS."src".rev}"
557 #endif // GPU_CONFIG_GPU_LISTS_VERSION_H_
558 EOF
559
560 cat << EOF > skia/ext/skia_commit_hash.h
561 /* Generated by lastchange.py, do not edit.*/
562 #ifndef SKIA_EXT_SKIA_COMMIT_HASH_H_
563 #define SKIA_EXT_SKIA_COMMIT_HASH_H_
564 #define SKIA_COMMIT_HASH "${upstream-info.DEPS."src/third_party/skia".rev}-"
565 #endif // SKIA_EXT_SKIA_COMMIT_HASH_H_
566 EOF
567
568 echo -n '${upstream-info.DEPS."src/third_party/dawn".rev}' > gpu/webgpu/DAWN_VERSION
569
570 mkdir -p third_party/jdk/current/bin
571 ''
572 + ''
573 # Workaround/fix for https://bugs.chromium.org/p/chromium/issues/detail?id=1313361:
574 substituteInPlace BUILD.gn \
575 --replace '"//infra/orchestrator:orchestrator_all",' ""
576 # Disable build flags that require LLVM 15:
577 substituteInPlace build/config/compiler/BUILD.gn \
578 --replace '"-Xclang",' "" \
579 --replace '"-no-opaque-pointers",' ""
580 # remove unused third-party
581 for lib in ${toString gnSystemLibraries}; do
582 if [ -d "third_party/$lib" ]; then
583 find "third_party/$lib" -type f \
584 \! -path "third_party/$lib/chromium/*" \
585 \! -path "third_party/$lib/google/*" \
586 \! -path "third_party/harfbuzz-ng/utils/hb_scoped.h" \
587 \! -regex '.*\.\(gn\|gni\|isolate\)' \
588 -delete
589 fi
590 done
591
592 if [[ -e native_client/SConstruct ]]; then
593 # Required for patchShebangs (unsupported interpreter directive, basename: invalid option -- '*', etc.):
594 substituteInPlace native_client/SConstruct --replace "#! -*- python -*-" ""
595 fi
596 if [ -e third_party/harfbuzz-ng/src/src/update-unicode-tables.make ]; then
597 substituteInPlace third_party/harfbuzz-ng/src/src/update-unicode-tables.make \
598 --replace "/usr/bin/env -S make -f" "/usr/bin/make -f"
599 fi
600 if [ -e third_party/webgpu-cts/src/tools/run_deno ]; then
601 chmod -x third_party/webgpu-cts/src/tools/run_deno
602 fi
603 if [ -e third_party/dawn/third_party/webgpu-cts/tools/run_deno ]; then
604 chmod -x third_party/dawn/third_party/webgpu-cts/tools/run_deno
605 fi
606
607 # We want to be able to specify where the sandbox is via CHROME_DEVEL_SANDBOX
608 substituteInPlace sandbox/linux/suid/client/setuid_sandbox_host.cc \
609 --replace \
610 'return sandbox_binary;' \
611 'return base::FilePath(GetDevelSandboxPath());'
612
613 substituteInPlace services/audio/audio_sandbox_hook_linux.cc \
614 --replace \
615 '/usr/share/alsa/' \
616 '${alsa-lib}/share/alsa/' \
617 --replace \
618 '/usr/lib/x86_64-linux-gnu/gconv/' \
619 '${glibc}/lib/gconv/' \
620 --replace \
621 '/usr/share/locale/' \
622 '${glibc}/share/locale/'
623
624 ''
625 + lib.optionalString systemdSupport ''
626 sed -i -e '/lib_loader.*Load/s!"\(libudev\.so\)!"${lib.getLib systemd}/lib/\1!' \
627 device/udev_linux/udev?_loader.cc
628 ''
629 + ''
630 # Allow to put extensions into the system-path.
631 sed -i -e 's,/usr,/run/current-system/sw,' chrome/common/chrome_paths.cc
632
633 # Add final newlines to scripts that do not end with one.
634 # This is a temporary workaround until https://github.com/NixOS/nixpkgs/pull/255463 (or similar) has been merged,
635 # as patchShebangs hard-crashes when it encounters files that contain only a shebang and do not end with a final
636 # newline.
637 find . -type f -perm -0100 -exec sed -i -e '$a\' {} +
638
639 patchShebangs .
640 ''
641 + lib.optionalString (ungoogled) ''
642 # Prune binaries (ungoogled only) *before* linking our own binaries:
643 ${ungoogler}/utils/prune_binaries.py . ${ungoogler}/pruning.list || echo "some errors"
644 ''
645 + ''
646 # Link to our own Node.js and Java (required during the build):
647 mkdir -p third_party/node/linux/node-linux-x64/bin${lib.optionalString ungoogled " third_party/jdk/current/bin/"}
648 ln -sf "${pkgsBuildHost.nodejs}/bin/node" third_party/node/linux/node-linux-x64/bin/node
649 ln -s "${pkgsBuildHost.jdk17_headless}/bin/java" third_party/jdk/current/bin/
650
651 # Allow building against system libraries in official builds
652 sed -i 's/OFFICIAL_BUILD/GOOGLE_CHROME_BUILD/' tools/generate_shim_headers/generate_shim_headers.py
653
654 ''
655 +
656 lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform && stdenv.hostPlatform.isAarch64)
657 ''
658 substituteInPlace build/toolchain/linux/BUILD.gn \
659 --replace 'toolprefix = "aarch64-linux-gnu-"' 'toolprefix = ""'
660 ''
661 + lib.optionalString ungoogled ''
662 ${ungoogler}/utils/patches.py . ${ungoogler}/patches
663 ${ungoogler}/utils/domain_substitution.py apply -r ${ungoogler}/domain_regex.list -f ${ungoogler}/domain_substitution.list -c ./ungoogled-domsubcache.tar.gz .
664 '';
665
666 llvmCcAndBintools = symlinkJoin {
667 name = "llvmCcAndBintools";
668 paths = [
669 buildPackages.rustc.llvmPackages.llvm
670 buildPackages.rustc.llvmPackages.stdenv.cc
671 ];
672 };
673
674 gnFlags = mkGnFlags (
675 {
676 # Main build and toolchain settings:
677 # Create an official and optimized release build (only official builds
678 # should be distributed to users, as non-official builds are intended for
679 # development and may not be configured appropriately for production,
680 # e.g. unsafe developer builds have developer-friendly features that may
681 # weaken or disable security measures like sandboxing or ASLR):
682 is_official_build = true;
683 disable_fieldtrial_testing_config = true;
684
685 # note: chromium calls buildPlatform "host" and calls hostPlatform "target"
686 host_cpu = chromiumRosettaStone.cpu stdenv.buildPlatform;
687 host_os = chromiumRosettaStone.os stdenv.buildPlatform;
688 target_cpu = chromiumRosettaStone.cpu stdenv.hostPlatform;
689 v8_target_cpu = chromiumRosettaStone.cpu stdenv.hostPlatform;
690 target_os = chromiumRosettaStone.os stdenv.hostPlatform;
691
692 # Build Chromium using the system toolchain (for Linux distributions):
693 #
694 # What you would expect to be called "target_toolchain" is
695 # actually called either "default_toolchain" or "custom_toolchain",
696 # depending on which part of the codebase you are in; see:
697 # https://github.com/chromium/chromium/blob/d36462cc9279464395aea5e65d0893d76444a296/build/config/BUILDCONFIG.gn#L17-L44
698 custom_toolchain = "//build/toolchain/linux/unbundle:default";
699 host_toolchain = "//build/toolchain/linux/unbundle:default";
700 # We only build those specific toolchains when we cross-compile, as native non-cross-compilations would otherwise
701 # end up building much more things than they need to (roughly double the build steps and time/compute):
702 }
703 // lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform) {
704 host_toolchain = "//build/toolchain/linux/unbundle:host";
705 v8_snapshot_toolchain = "//build/toolchain/linux/unbundle:host";
706 }
707 // {
708 host_pkg_config = "${pkgsBuildBuild.pkg-config}/bin/pkg-config";
709 pkg_config = "${pkgsBuildHost.pkg-config}/bin/${stdenv.cc.targetPrefix}pkg-config";
710
711 # Don't build against a sysroot image downloaded from Cloud Storage:
712 use_sysroot = false;
713 # Because we use a different toolchain / compiler version:
714 treat_warnings_as_errors = false;
715 # We aren't compiling with Chrome's Clang (would enable Chrome-specific
716 # plugins for enforcing coding guidelines, etc.):
717 clang_use_chrome_plugins = false;
718 # Disable symbols (they would negatively affect the performance of the
719 # build since the symbols are large and dealing with them is slow):
720 symbol_level = 0;
721 blink_symbol_level = 0;
722
723 # Google API key, see: https://www.chromium.org/developers/how-tos/api-keys
724 # Note: The API key is for NixOS/nixpkgs use ONLY.
725 # For your own distribution, please get your own set of keys.
726 google_api_key = "AIzaSyDGi15Zwl11UNe6Y-5XW_upsfyw31qwZPI";
727
728 # Optional features:
729 use_gio = true;
730 use_cups = cupsSupport;
731
732 # Feature overrides:
733 # Native Client support was deprecated in 2020 and support will end in June 2021:
734 enable_nacl = false;
735 }
736 // lib.optionalAttrs (packageName == "chromium") {
737 # Enabling the Widevine here doesn't affect whether we can redistribute the chromium package.
738 # Widevine in this drv is a bit more complex than just that. See Widevine patch somewhere above.
739 enable_widevine = true;
740 }
741 // {
742 # Provides the enable-webrtc-pipewire-capturer flag to support Wayland screen capture:
743 rtc_use_pipewire = true;
744 # Disable PGO because the profile data requires a newer compiler version (LLVM 14 isn't sufficient):
745 chrome_pgo_phase = 0;
746 clang_base_path = "${llvmCcAndBintools}";
747
748 use_qt5 = false;
749 use_qt6 = false;
750 }
751 // lib.optionalAttrs (chromiumVersionAtLeast "136") {
752 # LLVM < v21 does not support --warning-suppression-mappings yet:
753 clang_warning_suppression_file = "";
754 }
755 // {
756 # To fix the build as we don't provide libffi_pic.a
757 # (ld.lld: error: unable to find library -l:libffi_pic.a):
758 use_system_libffi = true;
759 # Use nixpkgs Rust compiler instead of the one shipped by Chromium.
760 rust_sysroot_absolute = "${buildPackages.rustc}";
761 rust_bindgen_root = "${buildPackages.rust-bindgen}";
762 }
763 // {
764 enable_rust = true;
765 # While we technically don't need the cache-invalidation rustc_version provides, rustc_version
766 # is still used in some scripts (e.g. build/rust/std/find_std_rlibs.py).
767 rustc_version = rustcVersion;
768 }
769 // lib.optionalAttrs (!(stdenv.buildPlatform.canExecute stdenv.hostPlatform)) {
770 # https://www.mail-archive.com/v8-users@googlegroups.com/msg14528.html
771 arm_control_flow_integrity = "none";
772 }
773 // lib.optionalAttrs proprietaryCodecs {
774 # enable support for the H.264 codec
775 proprietary_codecs = true;
776 enable_hangout_services_extension = true;
777 ffmpeg_branding = "Chrome";
778 }
779 // lib.optionalAttrs stdenv.hostPlatform.isAarch64 {
780 # Enable v4l2 video decoder for hardware acceleratation on aarch64:
781 use_vaapi = false;
782 use_v4l2_codec = true;
783 }
784 // lib.optionalAttrs pulseSupport {
785 use_pulseaudio = true;
786 link_pulseaudio = true;
787 }
788 // lib.optionalAttrs ungoogled (lib.importTOML ./ungoogled-flags.toml)
789 // (extraAttrs.gnFlags or { })
790 );
791
792 # TODO: Migrate this to env.RUSTC_BOOTSTRAP next mass-rebuild.
793 # Chromium expects nightly/bleeding edge rustc features to be available.
794 # Our rustc in nixpkgs follows stable, but since bootstrapping rustc requires
795 # nightly features too, we can (ab-)use RUSTC_BOOTSTRAP here as well to
796 # enable those features in our stable builds.
797 preConfigure = ''
798 export RUSTC_BOOTSTRAP=1
799 ''
800 + lib.optionalString (!isElectron) ''
801 (
802 cd third_party/node
803 grep patch update_npm_deps | sh
804 )
805 '';
806
807 configurePhase = ''
808 runHook preConfigure
809
810 # This is to ensure expansion of $out.
811 libExecPath="${libExecPath}"
812 ${python3.pythonOnBuildForHost}/bin/python3 build/linux/unbundle/replace_gn_files.py --system-libraries ${toString gnSystemLibraries}
813 gn gen --args=${lib.escapeShellArg gnFlags} out/Release | tee gn-gen-outputs.txt
814
815 # Fail if `gn gen` contains a WARNING.
816 grep -o WARNING gn-gen-outputs.txt && echo "Found gn WARNING, exiting nix build" && exit 1
817
818 runHook postConfigure
819 '';
820
821 # Mute some warnings that are enabled by default. This is useful because
822 # our Clang is always older than Chromium's and the build logs have a size
823 # of approx. 25 MB without this option (and this saves e.g. 66 %).
824 env.NIX_CFLAGS_COMPILE =
825 "-Wno-unknown-warning-option"
826 + lib.optionalString (chromiumVersionAtLeast "135") " -Wno-unused-command-line-argument -Wno-shadow";
827 env.BUILD_CC = "$CC_FOR_BUILD";
828 env.BUILD_CXX = "$CXX_FOR_BUILD";
829 env.BUILD_AR = "$AR_FOR_BUILD";
830 env.BUILD_NM = "$NM_FOR_BUILD";
831 env.BUILD_READELF = "$READELF_FOR_BUILD";
832
833 buildPhase =
834 let
835 buildCommand = target: ''
836 TERM=dumb ninja -C "${buildPath}" -j$NIX_BUILD_CORES "${target}"
837 bash -s << EOL
838 (
839 source chrome/installer/linux/common/installer.include
840 PACKAGE=$packageName
841 MENUNAME="Chromium"
842 process_template chrome/app/resources/manpage.1.in "${buildPath}/chrome.1"
843 )
844 EOL
845 '';
846 targets = extraAttrs.buildTargets or [ ];
847 commands = map buildCommand targets;
848 in
849 ''
850 runHook preBuild
851 ${lib.concatStringsSep "\n" commands}
852 runHook postBuild
853 '';
854
855 postFixup = ''
856 # Make sure that libGLESv2 and libvulkan are found by dlopen in both chromium binary and ANGLE libGLESv2.so.
857 # libpci (from pciutils) is needed by dlopen in angle/src/gpu_info_util/SystemInfo_libpci.cpp
858 for chromiumBinary in "$libExecPath/$packageName" "$libExecPath/libGLESv2.so"; do
859 patchelf --set-rpath "${
860 lib.makeLibraryPath [
861 libGL
862 vulkan-loader
863 pciutils
864 ]
865 }:$(patchelf --print-rpath "$chromiumBinary")" "$chromiumBinary"
866 done
867
868 # replace bundled vulkan-loader
869 rm "$libExecPath/libvulkan.so.1"
870 ln -s -t "$libExecPath" "${lib.getLib vulkan-loader}/lib/libvulkan.so.1"
871 '';
872
873 passthru = {
874 updateScript = ./update.mjs;
875 }
876 // lib.optionalAttrs (!isElectron) {
877 inherit chromiumDeps npmDeps;
878 };
879 };
880
881in
882# Remove some extraAttrs we supplied to the base attributes already.
883stdenv.mkDerivation (
884 base
885 // removeAttrs extraAttrs [
886 "name"
887 "gnFlags"
888 "buildTargets"
889 ]
890 // {
891 passthru = base.passthru // (extraAttrs.passthru or { });
892 }
893)