projects/guix·blob javascript-team · refs

2240 lines · 96.1 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2013, 2015 Andreas Enge <[email protected]>
3;;; Copyright © 2013-2022 Ludovic Courtès <[email protected]>
4;;; Copyright © 2014-2026 Mark H Weaver <[email protected]>
5;;; Copyright © 2015 Sou Bunnbu <[email protected]>
6;;; Copyright © 2016-2019, 2021, 2024, 2025 Efraim Flashner <[email protected]>
7;;; Copyright © 2016 Alex Griffin <[email protected]>
8;;; Copyright © 2017, 2023 Clément Lassieur <[email protected]>
9;;; Copyright © 2017, 2018 Nikita <[email protected]>
10;;; Copyright © 2017, 2018, 2020 Tobias Geerinckx-Rice <[email protected]>
11;;; Copyright © 2018, 2020, 2025 Ricardo Wurmus <[email protected]>
12;;; Copyright © 2019 Ivan Petkov <[email protected]>
13;;; Copyright © 2020, 2024 Oleg Pykhalov <[email protected]>
14;;; Copyright © 2020 Jakub Kądziołka <[email protected]>
15;;; Copyright © 2019, 2020 Adrian Malacoda <[email protected]>
16;;; Copyright © 2020-2023 Jonathan Brielmaier <[email protected]>
17;;; Copyright © 2020, 2022 Marius Bakke <[email protected]>
18;;; Copyright © 2021 Brice Waegeneire <[email protected]>
19;;; Copyright © 2021 Maxime Devos <[email protected]>
20;;; Copyright © 2021-2023, 2025 Maxim Cournoyer <[email protected]>
21;;; Copyright © 2021 Baptiste Strazzul <[email protected]>
22;;; Copyright © 2022 SeerLite <[email protected]>
23;;; Copyright © 2024 Aleksandr Vityazev <[email protected]>
24;;;
25;;; This file is part of GNU Guix.
26;;;
27;;; GNU Guix is free software; you can redistribute it and/or modify it
28;;; under the terms of the GNU General Public License as published by
29;;; the Free Software Foundation; either version 3 of the License, or (at
30;;; your option) any later version.
31;;;
32;;; GNU Guix is distributed in the hope that it will be useful, but
33;;; WITHOUT ANY WARRANTY; without even the implied warranty of
34;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35;;; GNU General Public License for more details.
36;;;
37;;; You should have received a copy of the GNU General Public License
38;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
39
40(define-module (gnu packages gnuzilla)
41 #:use-module ((srfi srfi-1) #:hide (zip))
42 #:use-module (ice-9 format)
43 #:use-module (ice-9 match)
44 #:autoload (ice-9 pretty-print) (pretty-print)
45 #:autoload (ice-9 textual-ports) (get-string-all)
46 #:use-module (gnu packages)
47 #:use-module ((guix licenses) #:prefix license:)
48 #:use-module (guix packages)
49 #:use-module (guix download)
50 #:use-module (guix git-download)
51 #:use-module (guix hg-download)
52 #:use-module (guix gexp)
53 #:use-module (guix store)
54 #:use-module (guix modules)
55 #:use-module (guix monads)
56 #:use-module (guix utils)
57 #:use-module (guix build-system cargo)
58 #:use-module (guix build-system copy)
59 #:use-module (guix build-system gnu)
60 #:use-module (guix build-system trivial)
61 #:use-module (guix build-system mozilla)
62 #:use-module (gnu packages admin)
63 #:use-module (gnu packages audio)
64 #:use-module (gnu packages autotools)
65 #:use-module (gnu packages m4)
66 #:use-module (gnu packages base)
67 #:use-module (gnu packages bash)
68 #:use-module (gnu packages databases)
69 #:use-module (gnu packages freedesktop)
70 #:use-module (gnu packages glib)
71 #:use-module (gnu packages gtk)
72 #:use-module (gnu packages gnome)
73 #:use-module (gnu packages libcanberra)
74 #:use-module (gnu packages cups)
75 #:use-module (gnu packages kerberos)
76 #:use-module (gnu packages linux)
77 #:use-module (gnu packages messaging)
78 #:use-module (gnu packages perl)
79 #:use-module (gnu packages pkg-config)
80 #:use-module (gnu packages python-web)
81 #:use-module (gnu packages compression)
82 #:use-module (gnu packages fontutils)
83 #:use-module (gnu packages fonts)
84 #:use-module (gnu packages hunspell)
85 #:use-module (gnu packages libevent)
86 #:use-module (gnu packages image)
87 #:use-module (gnu packages libffi)
88 #:use-module (gnu packages pulseaudio)
89 #:use-module (gnu packages python)
90 #:use-module (gnu packages python-xyz)
91 #:use-module (gnu packages node)
92 #:use-module (gnu packages xorg)
93 #:use-module (gnu packages gl)
94 #:use-module (gnu packages gnupg)
95 #:use-module (gnu packages pciutils)
96 #:use-module (gnu packages assembly)
97 #:use-module (gnu packages rust)
98 #:use-module (gnu packages rust-apps)
99 #:use-module (gnu packages llvm)
100 #:use-module (gnu packages nss)
101 #:use-module (gnu packages icu4c)
102 #:use-module (gnu packages video)
103 #:use-module (gnu packages xiph)
104 #:use-module (gnu packages xdisorg)
105 #:use-module (gnu packages readline)
106 #:use-module (gnu packages sqlite)
107 #:use-module (gnu packages time))
108
109(define computed-origin-method (@@ (guix packages) computed-origin-method))
110
111(define mozilla-compare-locales
112 (origin
113 (method git-fetch)
114 (uri (git-reference
115 (url "https://github.com/mozilla/compare-locales")
116 (commit "RELEASE_9_0_5"))) ;use the latest release
117 (file-name "mozilla-compare-locales")
118 (sha256 (base32 "06j6mr4wd1z8q2fr3dhd0mg1d5hbny4x825q2l48841q144dmyc3"))))
119
120(define mozilla-l10n
121 (origin
122 (method git-fetch)
123 (uri (git-reference
124 (url "https://github.com/mozilla-l10n/firefox-l10n")
125 ;; Use the revision specified in the
126 ;; browser/locales/l10n-changesets.json file of the used firefox
127 ;; source (all the languages normally use the same revision).
128 (commit "5e42b46226b4e4b8722697bc020b18013c543eb5")))
129 (file-name "mozilla-l10n")
130 (sha256 (base32 "134pggczsy2z0yx0gx7fpimsmja9dvkfibqjzfa95jgqidbmjljb"))))
131
132(define (format-locales all-locales-file)
133 "Format a Scheme list of all the locales string found in ALL-LOCALES-FILE.
134In the case of Thunderbird, that file is comm/mail/locales/all-locales, while
135in the case of Firefox, it is browser/locales/all-locales."
136 (pretty-print (string-split
137 (string-trim-right
138 (call-with-input-file all-locales-file
139 get-string-all))
140 #\newline)))
141
142;;; To regenerate, use the above `format-locales' procedure.
143(define %icecat-locales
144 '("ach"
145 "af"
146 "an"
147 "ar"
148 "ast"
149 "az"
150 "be"
151 "bg"
152 "bn"
153 "bo"
154 "bqi"
155 "br"
156 "brx"
157 "bs"
158 "ca"
159 "ca-valencia"
160 "cak"
161 "ckb"
162 "cs"
163 "cy"
164 "da"
165 "de"
166 "dsb"
167 "el"
168 "en-CA"
169 "en-GB"
170 "eo"
171 "es-AR"
172 "es-CL"
173 "es-ES"
174 "es-MX"
175 "et"
176 "eu"
177 "fa"
178 "ff"
179 "fi"
180 "fr"
181 "fur"
182 "fy-NL"
183 "ga-IE"
184 "gd"
185 "gl"
186 "gn"
187 "gu-IN"
188 "he"
189 "hi-IN"
190 "hr"
191 "hsb"
192 "hu"
193 "hy-AM"
194 "hye"
195 "ia"
196 "id"
197 "is"
198 "it"
199 "ja"
200 "ja-JP-mac"
201 "ka"
202 "kab"
203 "kk"
204 "km"
205 "kn"
206 "ko"
207 "lij"
208 "lo"
209 "lt"
210 "ltg"
211 "lv"
212 "meh"
213 "mk"
214 "ml"
215 "mr"
216 "ms"
217 "my"
218 "nb-NO"
219 "ne-NP"
220 "nl"
221 "nn-NO"
222 "oc"
223 "pa-IN"
224 "pl"
225 "pt-BR"
226 "pt-PT"
227 "rm"
228 "ro"
229 "ru"
230 "sat"
231 "sc"
232 "scn"
233 "sco"
234 "si"
235 "sk"
236 "skr"
237 "sl"
238 "son"
239 "sq"
240 "sr"
241 "sv-SE"
242 "szl"
243 "ta"
244 "te"
245 "tg"
246 "th"
247 "tl"
248 "tr"
249 "trs"
250 "uk"
251 "ur"
252 "uz"
253 "vi"
254 "wo"
255 "xh"
256 "zh-CN"
257 "zh-TW"))
258
259;;; Please keep these versions in sync with icedove.
260(define %icecat-base-version "153.5.0")
261(define %icecat-version (string-append %icecat-base-version "-gnu1"))
262(define %icecat-build-id "20261013000000") ;must be of the form YYYYMMDDhhmmss
263
264;; 'icecat-source' is a "computed" origin that generates an IceCat tarball
265;; from the corresponding upstream Firefox ESR tarball, using the 'makeicecat'
266;; script from the upstream IceCat project.
267(define icecat-source
268 (let* ((major-version (first (string-split %icecat-base-version #\.)))
269 (minor-version (second (string-split %icecat-base-version #\.)))
270 (sub-version (third (string-split %icecat-base-version #\.)))
271
272 (upstream-firefox-version (string-append %icecat-base-version "esr"))
273 (upstream-firefox-source
274 (origin
275 (method url-fetch)
276 (uri (string-append
277 "https://ftp.mozilla.org/pub/firefox/releases/"
278 upstream-firefox-version "/source/"
279 "firefox-" upstream-firefox-version ".source.tar.xz"))
280 (sha256
281 (base32
282 "02s1wdhvfvn2cyjikgqy7k5xk8vmfzg25073zfmcff4v9xyllw98"))))
283
284 (gnuzilla-commit "ac1ff821a67463e277853820109d56f7a2daf44d")
285 (gnuzilla-source
286 (origin
287 (method git-fetch)
288 (uri (git-reference
289 (url "git://git.savannah.gnu.org/gnuzilla.git")
290 (commit gnuzilla-commit)))
291 (file-name (git-file-name "gnuzilla"
292 (string-take gnuzilla-commit 8)))
293 (sha256
294 (base32
295 "0sfgrglj6l0i7b2b6fsj76380wvp359g78bz0ljx0q9zh8iich82"))))
296
297 ;; 'search-patch' returns either a valid file name or #f, so wrap it
298 ;; in 'assume-valid-file-name' to avoid 'local-file' warnings.
299 (makeicecat-patch
300 (local-file (assume-valid-file-name
301 (search-patch "icecat-153-makeicecat.patch")))))
302
303 (origin
304 (method computed-origin-method)
305 (file-name (string-append "icecat-" %icecat-version ".tar.zst"))
306 (sha256 #f)
307 (uri
308 (delay
309 (with-imported-modules '((guix build utils))
310 #~(begin
311 (use-modules (guix build utils))
312 (let ((firefox-dir
313 (string-append "firefox-" #$%icecat-base-version))
314 (icecat-dir
315 (string-append "icecat-" #$%icecat-version)))
316
317 (set-path-environment-variable
318 "PATH" '("bin")
319 (list #+python
320 #+(canonical-package bash)
321 #+(canonical-package coreutils)
322 #+(canonical-package findutils)
323 #+(canonical-package patch)
324 #+(canonical-package xz)
325 #+(canonical-package zstd)
326 #+(canonical-package sed)
327 #+(canonical-package grep)
328 #+(canonical-package bzip2)
329 #+(canonical-package gzip)
330 #+(canonical-package tar)))
331
332 (set-path-environment-variable
333 "PYTHONPATH"
334 (list #+(format #f "lib/python~a/site-packages"
335 (version-major+minor
336 (package-version python))))
337 '#+(cons python-jsonschema
338 (map second
339 (package-transitive-propagated-inputs
340 python-jsonschema))))
341
342 ;; We copy the gnuzilla source directory because it is
343 ;; read-only in 'gnuzilla-source', and the makeicecat script
344 ;; uses "cp -a" to copy parts of it and assumes that the
345 ;; copies will be writable.
346 (copy-recursively #+gnuzilla-source "/tmp/gnuzilla"
347 #:log (%make-void-port "w"))
348
349 (with-directory-excursion "/tmp/gnuzilla"
350 (make-file-writable "makeicecat")
351 (invoke "patch" "--force" "--no-backup-if-mismatch"
352 "-p1" "--input" #+makeicecat-patch)
353 (patch-shebang "makeicecat")
354 (substitute* "makeicecat"
355 (("^readonly FFMAJOR=(.*)" all ffmajor)
356 (unless (string=? #$major-version
357 (string-trim-both ffmajor))
358 ;; The makeicecat script cannot be expected to work
359 ;; properly on a different version of Firefox, even if
360 ;; no errors occur during execution.
361 (error "makeicecat major version mismatch"))
362 (string-append "readonly FFMAJOR=" #$major-version "\n"))
363 (("^readonly FFMINOR=.*")
364 (string-append "readonly FFMINOR=" #$minor-version "\n"))
365 (("^readonly FFSUB=.*")
366 (string-append "readonly FFSUB=" #$sub-version "\n"))
367 (("^readonly DATADIR=.*")
368 "readonly DATADIR=/tmp/gnuzilla/data\n")
369 (("^readonly SOURCEDIR=.*")
370 (string-append "readonly SOURCEDIR=" icecat-dir "\n"))
371 (("/bin/sed")
372 #+(file-append (canonical-package sed) "/bin/sed"))))
373
374 (format #t "Unpacking upstream firefox tarball...~%")
375 (force-output)
376 (invoke "tar" "xf" #+upstream-firefox-source)
377 (rename-file firefox-dir icecat-dir)
378
379 (with-directory-excursion icecat-dir
380 (format #t "Populating l10n directory...~%")
381 (force-output)
382 (mkdir "l10n")
383 (with-directory-excursion "l10n"
384 (for-each
385 (lambda (locale)
386 (let ((locale-dir (string-append #+mozilla-l10n "/"
387 locale)))
388 (format #t " ~a~%" locale)
389 (force-output)
390 (copy-recursively locale-dir locale
391 #:log (%make-void-port "w"))
392 (for-each make-file-writable (find-files locale))
393 (with-directory-excursion locale
394 (mkdir-p "browser/chrome/browser/preferences")
395 (call-with-output-file "browser/chrome/browser/\
396preferences/advanced-scripts.dtd"
397 (lambda (port) #f)))))
398 '#+%icecat-locales)
399 (copy-recursively #+mozilla-compare-locales
400 "compare-locales"
401 #:log (%make-void-port "w"))
402 (delete-file "compare-locales/.gitignore")))
403
404 (format #t "Running makeicecat script...~%")
405 (force-output)
406 (invoke "bash" "/tmp/gnuzilla/makeicecat")
407
408 (format #t "Packing IceCat source tarball...~%")
409 (force-output)
410 (setenv "ZSTD_NBTHREADS" (number->string (parallel-job-count)))
411 (invoke "tar" "cfa" #$output
412 ;; Avoid non-determinism in the archive. We set the
413 ;; mtime of files in the archive to early 1980 because
414 ;; the build process fails if the mtime of source
415 ;; files is pre-1980, due to the creation of zip
416 ;; archives.
417 "--mtime=@315619200" ; 1980-01-02 UTC
418 "--owner=root:0"
419 "--group=root:0"
420 "--sort=name"
421 icecat-dir)))))))))
422
423(define-public icecat-minimal
424 (package
425 (name "icecat-minimal")
426 (version %icecat-version)
427 (source icecat-source)
428 (build-system mozilla-build-system)
429 (inputs
430 (list alsa-lib
431 bash-minimal
432 bzip2
433 cups
434 dbus-glib
435 gdk-pixbuf
436 glib
437 gtk+
438 ;; UNBUNDLE-ME! graphite2
439 cairo
440 pango
441 freetype
442 font-dejavu
443 ;; UNBUNDLE-ME! harfbuzz
444 libcanberra
445 libgnome
446 libjpeg-turbo
447 libpng-apng-next
448 ;; UNBUNDLE-ME! libogg
449 ;; UNBUNDLE-ME! libtheora ; wants theora-1.2, not yet released
450 ;; UNBUNDLE-ME! libvorbis
451 libxft
452 libevent
453 libwebp
454 libxinerama
455 libxscrnsaver
456 libxcomposite
457 libxt
458 libffi
459 ;; See <https://bugzilla.mozilla.org/show_bug.cgi?id=1962139>
460 ffmpeg-6
461 libvpx
462 ;; UNBUNDLE-ME! icu4c-78 ; needs 78.3 with mozilla patches
463 pixman
464 pulseaudio
465 mesa
466 pciutils
467 mit-krb5
468 hunspell
469 libnotify
470 nspr
471 ;;nss-rapid ;pending resolution of
472 ;<https://codeberg.org/guix/guix/issues/661>
473 shared-mime-info
474 sqlite
475 eudev
476 unzip
477 zip
478 zlib))
479 (native-inputs
480 ;; The following patches are specific to the Guix packaging of IceCat,
481 ;; and therefore we prefer to leave them out of 'source', which should be
482 ;; a tarball suitable for compilation on any system that IceCat supports.
483 ;; (Bug fixes and security fixes, however, should go in 'source').
484 (list
485 ;; XXX TODO: Adapt these patches to current IceCat.
486 ;; ("icecat-avoid-bundled-libraries.patch"
487 ;; ,(search-patch "icecat-avoid-bundled-libraries.patch"))
488 ;; ("icecat-use-system-graphite2+harfbuzz.patch"
489 ;; ,(search-patch "icecat-use-system-graphite2+harfbuzz.patch"))
490 ;; ("icecat-use-system-media-libs.patch"
491 ;; ,(search-patch "icecat-use-system-media-libs.patch"))
492 rust
493 `(,rust "cargo")
494 rust-cbindgen
495 llvm-21
496 clang-21
497 perl
498 node-lts
499 python-wrapper
500 yasm
501 nasm ; XXX FIXME: only needed on x86_64 and i686
502 pkg-config
503 m4
504 which))
505 (arguments
506 (list
507 #:tests? #f ;not worth the cost
508
509 ;; Some dynamic lib was determined at runtime, so rpath check may fail.
510 #:validate-runpath? #f
511
512 #:configure-flags
513 #~(list
514 "--disable-bootstrap" ;do not attempt to fetch toolchain binaries
515 "--disable-fhs"
516 "--enable-application=browser"
517 "--with-distribution-id=org.gnu"
518 "--enable-geckodriver"
519 ;; Do not require addons in the global app or system directories to
520 ;; be signed by Mozilla.
521 "--with-unsigned-addon-scopes=app,system"
522 "--allow-addon-sideload"
523
524 "--enable-pulseaudio"
525
526 "--disable-tests"
527 "--disable-updater"
528 "--disable-crashreporter"
529 ;; The --disable-eme option is not available on aarch64.
530 #$(if (target-aarch64?) "" "--disable-eme")
531
532 ;; Building with debugging symbols takes ~5GiB, so disable it.
533 "--disable-debug"
534 "--disable-debug-symbols"
535
536 "--enable-rust-simd"
537 "--enable-release"
538 "--enable-optimize"
539 "--enable-strip"
540 "--disable-elf-hack"
541
542 ;; Clang is needed to build Stylo, Mozilla's new CSS engine. We must
543 ;; specify the clang paths manually, because otherwise the Mozilla
544 ;; build system looks in the directories returned by llvm-config
545 ;; --bindir and llvm-config --libdir, which return paths in the llvm
546 ;; package where clang is not found.
547 (string-append "--with-clang-path="
548 (search-input-file %build-inputs "bin/clang"))
549 (string-append "--with-libclang-path="
550 (dirname (search-input-file %build-inputs
551 "lib/libclang.so")))
552
553 ;; TODO: Add support for wasm sandboxed libraries.
554 "--without-wasm-sandboxed-libraries"
555
556 ;; Avoid bundled libraries.
557 "--enable-system-pixman"
558 "--with-system-ffi"
559 ;; UNBUNDLE-ME! "--with-system-icu" ; needs 78.3 with mozilla patches
560 "--with-system-jpeg" ;must be libjpeg-turbo
561 "--with-system-libevent"
562 "--with-system-libvpx"
563 "--with-system-nspr"
564 ;; "--with-system-nss"
565 ;; (pending resolution of <https://codeberg.org/guix/guix/issues/661>)
566 "--with-system-png" ;must be libpng-apng
567 "--with-system-webp"
568 "--with-system-zlib"
569
570 ;; TODO: To be implemented.
571 ;; UNBUNDLE-ME! "--with-system-bz2"
572 ;; UNBUNDLE-ME! "--with-system-ogg"
573 ;; UNBUNDLE-ME! "--with-system-vorbis"
574 ;; UNBUNDLE-ME! "--with-system-theora" ; wants theora-1.2, not yet released
575 ;; UNBUNDLE-ME! "--with-system-harfbuzz"
576 ;; UNBUNDLE-ME! "--with-system-graphite2"
577 ;; UNBUNDLE-ME! "--enable-system-sqlite"
578 )
579
580 #:imported-modules %cargo-utils-modules ;for `generate-all-checksums'
581
582 #:modules `((ice-9 ftw)
583 (ice-9 match)
584 (srfi srfi-1)
585 (srfi srfi-26)
586 (rnrs bytevectors)
587 (rnrs io ports)
588 (guix elf)
589 (guix build gremlin)
590 ,@%default-gnu-modules)
591 #:phases
592 #~(modify-phases %standard-phases
593 (add-after 'unpack 'apply-guix-specific-patches
594 (lambda _
595 (for-each
596 (lambda (file) (invoke "patch" "--force" "-p1" "-i" file))
597 '(#$(local-file
598 (search-patch "icecat-compare-paths.patch"))
599 #$(local-file
600 (search-patch "icecat-use-system-wide-dir.patch"))
601 #$(local-file
602 (search-patch "icecat-fhs-configure-option.patch"))))))
603 (add-after 'apply-guix-specific-patches 'remove-bundled-libraries
604 (lambda _
605 ;; Remove bundled libraries that we don't use, since they may
606 ;; contain unpatched security flaws, they waste disk space and
607 ;; memory, and may cause confusion.
608 (for-each (lambda (file)
609 (format #t "deleting '~a'...~%" file)
610 (delete-file-recursively file))
611 '( ;; FIXME: Removing the bundled icu breaks configure.
612 ;; * The bundled icu headers are used in some places.
613 ;; * The version number is taken from the bundled copy.
614 ;;"intl/icu"
615 ;;
616 ;; FIXME: A script from the bundled nspr is used.
617 ;;"nsprpub"
618 ;;
619 ;; FIXME: Some of the bundled NSS sources are used
620 ;; to build third_party/prio.
621 ;;"security/nss"
622 ;;
623 ;; TODO: Use more system media libraries. See:
624 ;; <https://bugzilla.mozilla.org/show_bug.cgi?id=517422>
625 ;; * libtheora: esr60 wants v1.2, not yet released.
626 ;; * soundtouch: avoiding the bundled library would
627 ;; result in some loss of functionality. There's
628 ;; also an issue with exception handling
629 ;; configuration. It seems that this is needed in
630 ;; some moz.build:
631 ;; DEFINES['ST_NO_EXCEPTION_HANDLING'] = 1
632 ;; * libopus
633 ;; * speex
634 ;;
635 "ipc/chromium/src/third_party/libevent"
636 "js/src/ctypes/libffi"
637 "media/libjpeg"
638 "media/libvpx"
639 "modules/freetype2"
640
641 ;; UNBUNDLE-ME! "modules/zlib"
642 ;; UNBUNDLE-ME! "media/libogg"
643 ;; UNBUNDLE-ME! "media/libvorbis"
644 ;; UNBUNDLE-ME! "media/libtheora" ; wants theora-1.2, not yet released
645 ;; UNBUNDLE-ME! "media/libtremor"
646 ;; UNBUNDLE-ME! "gfx/harfbuzz"
647 ;; UNBUNDLE-ME! "gfx/graphite2"
648 ;; UNBUNDLE-ME! "db/sqlite3"
649 ))))
650 (add-after 'remove-bundled-libraries 'fix-ffmpeg-runtime-linker
651 (lambda* (#:key inputs #:allow-other-keys)
652 ;; Arrange to load libavcodec.so by its absolute file name.
653 (substitute* "dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp"
654 (("libavcodec\\.so")
655 (search-input-file inputs "lib/libavcodec.so")))))
656 (add-after 'fix-ffmpeg-runtime-linker 'build-sandbox-whitelist
657 (lambda* (#:key inputs #:allow-other-keys)
658 (define (runpath-of lib)
659 (call-with-input-file lib
660 (compose elf-dynamic-info-runpath
661 elf-dynamic-info
662 parse-elf
663 get-bytevector-all)))
664 (define (runpaths-of-input label)
665 (let* ((dir (string-append (assoc-ref inputs label) "/lib"))
666 (libs (find-files dir "\\.so$")))
667 (append-map runpath-of libs)))
668 ;; Populate the sandbox read-path whitelist as needed by ffmpeg.
669 (let* ((whitelist
670 (map (cut string-append <> "/")
671 (delete-duplicates
672 `(,(string-append (assoc-ref inputs "shared-mime-info")
673 "/share/mime")
674 ,(string-append (assoc-ref inputs "font-dejavu")
675 "/share/fonts")
676 "/run/current-system/profile/share/fonts"
677 ,@(append-map runpaths-of-input
678 '("mesa" "ffmpeg"))))))
679 (whitelist-string (string-join whitelist ","))
680 (port (open-file "browser/app/profile/icecat.js" "a")))
681 (format #t "setting 'security.sandbox.content.read_path_whitelist' to '~a'~%"
682 whitelist-string)
683 (format port "~%pref(\"security.sandbox.content.read_path_whitelist\", ~S);~%"
684 whitelist-string)
685 (close-output-port port))))
686 (add-after 'patch-source-shebangs 'patch-cargo-checksums
687 (lambda _
688 (use-modules (guix build cargo-utils))
689 (let ((null-hash "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"))
690 (for-each (lambda (file)
691 (format #t "patching checksums in ~a~%" file)
692 (substitute* file
693 (("^checksum = \".*\"")
694 (string-append "checksum = \"" null-hash "\""))))
695 (find-files "." "Cargo.lock$"))
696 (for-each generate-all-checksums
697 '("services"
698 "js"
699 "third_party/rust"
700 "dom/media"
701 "dom/webauthn"
702 "toolkit"
703 "gfx"
704 "storage"
705 "modules"
706 "xpcom/rust"
707 "media"
708 "mozglue/static/rust"
709 "netwerk"
710 "remote"
711 "intl"
712 "servo"
713 "security/manager/ssl"
714 "build")))))
715 (add-after 'patch-cargo-checksums 'remove-cargo-frozen-flag
716 (lambda _
717 ;; Remove --frozen flag from cargo invocation, otherwise it'll
718 ;; complain that it's not able to change Cargo.lock.
719 ;; https://bugzilla.mozilla.org/show_bug.cgi?id=1726373
720 (substitute* "build/RunCbindgen.py"
721 (("args.append\\(\"--frozen\"\\)") "pass"))
722 (substitute* "config/makefiles/rust.mk"
723 (("cargo_build_flags \\+= --frozen") ""))))
724 (delete 'bootstrap)
725 (replace 'configure
726 ;; configure does not work followed by both "SHELL=..." and
727 ;; "CONFIG_SHELL=..."; set environment variables instead
728 (lambda* (#:key outputs configure-flags #:allow-other-keys)
729 (let* ((bash (which "bash"))
730 (abs-srcdir (getcwd))
731 (flags `(,(string-append "--prefix=" #$output)
732 ,(string-append "--with-l10n-base="
733 abs-srcdir "/l10n")
734 ,@configure-flags)))
735 (setenv "SHELL" bash)
736 (setenv "CONFIG_SHELL" bash)
737
738 (setenv "AR" "llvm-ar")
739 (setenv "NM" "llvm-nm")
740 (setenv "CC" "clang")
741 (setenv "CXX" "clang++")
742 (setenv "LDFLAGS" (string-append "-Wl,-rpath="
743 #$output "/lib/icecat"))
744
745 (setenv "MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE" "system")
746 (setenv "MOZ_BUILD_DATE" #$%icecat-build-id) ; avoid timestamp
747
748 ;; WM_CLASS (default is "$MOZ_APP_NAME-$MOZ_UPDATE_CHANNEL").
749 (setenv "MOZ_APP_REMOTINGNAME" "Icecat")
750
751 ;; XXX TODO: Fix this to work on systems other than x86_64-linux.
752 (setenv "GUIX_PYTHONPATH"
753 (string-append (getcwd)
754 "/obj-x86_64-pc-linux-gnu/_virtualenvs/build"))
755
756 (mkdir ".mozbuild")
757 (setenv "MOZBUILD_STATE_PATH"
758 (string-append (getcwd) "/.mozbuild"))
759
760 (format #t "build directory: ~s~%" (getcwd))
761 (format #t "configure flags: ~s~%" flags)
762
763 (call-with-output-file "mozconfig"
764 (lambda (port)
765 (for-each (lambda (flag)
766 (format port "ac_add_options ~a\n" flag))
767 flags)))
768
769 (invoke "./mach" "configure"))))
770 (replace 'build
771 (lambda* (#:key (make-flags '()) (parallel-build? #t)
772 #:allow-other-keys)
773 (apply invoke "./mach" "build"
774 ;; mach will use a wide parallel build if possible by
775 ;; default, so reign it in if requested.
776 `(,(string-append
777 "-j" (number->string (if parallel-build?
778 (parallel-job-count)
779 1)))
780 ,@make-flags))))
781 (add-after 'build 'neutralise-store-references
782 (lambda _
783 ;; Mangle the store references to compilers & other build tools in
784 ;; about:buildconfig, reducing IceCat's closure by 1 GiB on x86-64.
785 (let* ((obj-dir (match (scandir "." (cut string-prefix? "obj-" <>))
786 ((dir) dir)))
787 (file (string-append
788 obj-dir
789 "/dist/bin/chrome/toolkit/content/global/buildconfig.html")))
790 (substitute* file
791 (("[0-9a-df-np-sv-z]{32}" hash)
792 (string-append (string-take hash 8)
793 "<!-- Guix: not a runtime dependency -->"
794 (string-drop hash 8)))))))
795 (replace 'install
796 (lambda* (#:key outputs #:allow-other-keys)
797 (invoke "./mach" "install")
798 ;; The geckodriver binary is not installed by the above, for some
799 ;; reason. Use 'find-files' to avoid having to deal with the
800 ;; system/architecture-specific file name.
801 (install-file (first (find-files "." "geckodriver"))
802 (string-append #$output "/bin"))
803 ;; Install a policies.json file as an extra step to ensure
804 ;; IceCat does not call home. The available policies can be
805 ;; found at <https://mozilla.github.io/policy-templates/>.
806
807 ;; TODO: Disable remote settings feature when it becomes
808 ;; possible to do so (see:
809 ;; <https://bugzilla.mozilla.org/show_bug.cgi?id=1988070>).
810 (let ((policies.json (string-append
811 #$output
812 "/lib/icecat/distribution/policies.json")))
813 (mkdir-p (dirname policies.json))
814 (call-with-output-file policies.json
815 (lambda (p)
816 (format p "\
817{
818 \"policies\": {
819 \"DisableFirefoxAccounts\": true,
820 \"DisableTelemetry\": true,
821 \"DisablePocket\": true
822 }
823}~%"))))))
824 (add-after 'install 'wrap-program
825 (lambda* (#:key inputs #:allow-other-keys)
826 (let* ((lib (string-append #$output "/lib"))
827 (gtk #$(this-package-input "gtk+"))
828 (gtk-share (string-append gtk "/share"))
829 (ld-libs '#$(cons
830 (file-append
831 (this-package-input "libcanberra")
832 "/lib/gtk-3.0/modules")
833 (map (lambda (label)
834 (file-append (this-package-input label) "/lib"))
835 '("libpng-apng"
836 "libxscrnsaver"
837 "mesa"
838 "pciutils"
839 "mit-krb5"
840 "eudev"
841 "pulseaudio"
842 ;; For the integration of native notifications
843 ;; (same reason as icedove)
844 "libnotify")))))
845 (wrap-program (car (find-files lib "^icecat$"))
846 `("XDG_DATA_DIRS" prefix (,gtk-share))
847 ;; The following line is commented out because the icecat
848 ;; package on guix has been observed to be unstable when
849 ;; using wayland, and the bundled extensions stop working.
850 ;; `("MOZ_ENABLE_WAYLAND" = ("1"))
851 `("LD_LIBRARY_PATH" prefix ,ld-libs)))))
852 (add-after 'wrap-program 'install-desktop-entry
853 (lambda _
854 ;; Install the '.desktop' file.
855 (let* ((applications (string-append #$output "/share/applications"))
856 (desktop-file (string-append applications "/icecat.desktop")))
857 (mkdir-p applications)
858 (call-with-output-file desktop-file
859 (lambda (p)
860 (format p "\
861[Desktop Entry]
862Version=1.0
863Name=GNU IceCat
864GenericName=Web Browser
865Comment=Your web, the way you like it
866Exec=~a/bin/icecat %u
867Icon=icecat
868Terminal=false
869Type=Application
870StartupWMClass=Icecat
871MimeType=text/html;text/xml;application/xhtml+xml;text/mml;x-scheme-handler/http;x-scheme-handler/https;
872StartupNotify=true
873X-MultipleArgs=false
874X-Desktop-File-Install-Version=0.16
875Categories=Network;WebBrowser;
876Encoding=UTF-8~%"
877 #$output))))))
878 (add-after 'install-desktop-entry 'install-icons
879 (lambda _
880 (with-directory-excursion "browser/branding/unofficial"
881 (for-each
882 (lambda (file)
883 (let* ((size (string-filter char-numeric? file))
884 (icons (string-append #$output "/share/icons/hicolor/"
885 size "x" size "/apps")))
886 (mkdir-p icons)
887 (copy-file file (string-append icons "/icecat.png"))))
888 '("default16.png" "default22.png" "default24.png"
889 "default32.png" "default48.png" "default256.png"
890 "content/icon64.png" "mozicon128.png" ))))))))
891 (native-search-paths
892 (list (search-path-specification
893 (variable "MOZILLA_SYSTEM_DIR")
894 (separator #f) ;single entry
895 (files '("lib/icecat")))))
896 (home-page "https://www.gnu.org/software/gnuzilla/")
897 (synopsis "Entirely free browser derived from Mozilla Firefox")
898 (description
899 "IceCat is the GNU version of the Firefox browser. It is entirely free
900software, which does not recommend non-free plugins and addons. It also
901features built-in privacy-protecting features. This package also includes the
902@command{geckodriver} command, which can be useful for automated web
903testing.")
904 (license license:mpl2.0) ;and others, see toolkit/content/license.html
905 (properties
906 `((ftp-directory . "/gnu/gnuzilla")
907 (cpe-name . "firefox_esr")
908 (cpe-version . ,(first (string-split version #\-)))))))
909
910;;;
911;;; TEMPORARY old version of icecat-source and dependencies
912;;; for use by mozjs and icedove until they are updated.
913;;;
914
915(define mozilla-140.17.0-compare-locales
916 (origin
917 (method git-fetch)
918 (uri (git-reference
919 (url "https://github.com/mozilla/compare-locales")
920 (commit "RELEASE_9_0_4"))) ;use the latest release
921 (file-name "mozilla-compare-locales")
922 (sha256 (base32 "13qn983j0pgs2550fgd5gvnl4lq6ywqjvgbyx850jwg79w8b0ifz"))))
923
924(define mozilla-140.17.0-l10n
925 (origin
926 (method git-fetch)
927 (uri (git-reference
928 (url "https://github.com/mozilla-l10n/firefox-l10n")
929 ;; Use the revision specified in the
930 ;; browser/locales/l10n-changesets.json file of the used firefox
931 ;; source (all the languages normally use the same revision).
932 (commit "64046fdc97c1b1886a479dead61e6dc5428ae6e6")))
933 (file-name "mozilla-l10n")
934 (sha256 (base32 "1rvk1m8bjnk9x61663s7bhgax6ig37v9m1d64g89fk1qwsk3djhh"))))
935
936(define %icecat-140.17.0-locales
937 '("ach" "af" "an" "ar" "ast" "az" "be" "bg" "bn" "bo" "br" "brx" "bs" "ca"
938 "ca-valencia" "cak" "ckb" "cs" "cy" "da" "de" "dsb" "el" "en-CA" "en-GB"
939 "eo" "es-AR" "es-CL" "es-ES" "es-MX" "et" "eu" "fa" "ff" "fi" "fr" "fur"
940 "fy-NL" "ga-IE" "gd" "gl" "gn" "gu-IN" "he" "hi-IN" "hr" "hsb" "hu" "hy-AM"
941 "hye" "ia" "id" "is" "it" "ja" "ja-JP-mac" "ka" "kab" "kk" "km" "kn" "ko"
942 "lij" "lo" "lt" "ltg" "lv" "meh" "mk" "ml" "mr" "ms" "my" "nb-NO" "ne-NP"
943 "nl" "nn-NO" "oc" "pa-IN" "pl" "pt-BR" "pt-PT" "rm" "ro" "ru" "sat" "sc"
944 "scn" "sco" "si" "sk" "skr" "sl" "son" "sq" "sr" "sv-SE" "szl" "ta" "te"
945 "tg" "th" "tl" "tr" "trs" "uk" "ur" "uz" "vi" "wo" "xh" "zh-CN" "zh-TW"))
946
947(define %icecat-140.17.0-base-version "140.17.0")
948(define %icecat-140.17.0-version (string-append %icecat-140.17.0-base-version "-gnu1"))
949
950(define icecat-140.17.0-source
951 (let* ((major-version (first (string-split %icecat-140.17.0-base-version #\.)))
952 (minor-version (second (string-split %icecat-140.17.0-base-version #\.)))
953 (sub-version (third (string-split %icecat-140.17.0-base-version #\.)))
954
955 (upstream-firefox-version (string-append %icecat-140.17.0-base-version "esr"))
956 (upstream-firefox-source
957 (origin
958 (method url-fetch)
959 (uri (string-append
960 "https://ftp.mozilla.org/pub/firefox/releases/"
961 upstream-firefox-version "/source/"
962 "firefox-" upstream-firefox-version ".source.tar.xz"))
963 (sha256
964 (base32
965 "0csws0jrmwxrz0fh72kd0c5sq4v0vaavmn0jmddwas90ifqx6vjd"))))
966
967 (gnuzilla-commit "d7ffa7cbb29e7047b491ebbf5e50549548d480cb")
968 (gnuzilla-source
969 (origin
970 (method git-fetch)
971 (uri (git-reference
972 (url "git://git.savannah.gnu.org/gnuzilla.git")
973 (commit gnuzilla-commit)))
974 (file-name (git-file-name "gnuzilla"
975 (string-take gnuzilla-commit 8)))
976 (sha256
977 (base32
978 "0hiknvpc6hqxxf7a250zalbps84sn4vpfb6bv0v7ava00kyf61mf"))))
979
980 ;; 'search-patch' returns either a valid file name or #f, so wrap it
981 ;; in 'assume-valid-file-name' to avoid 'local-file' warnings.
982 (makeicecat-patch
983 (local-file (assume-valid-file-name
984 (search-patch "icecat-makeicecat.patch")))))
985
986 (origin
987 (method computed-origin-method)
988 (file-name (string-append "icecat-" %icecat-140.17.0-version ".tar.zst"))
989 (sha256 #f)
990 (uri
991 (delay
992 (with-imported-modules '((guix build utils))
993 #~(begin
994 (use-modules (guix build utils))
995 (let ((firefox-dir
996 (string-append "firefox-" #$%icecat-140.17.0-base-version))
997 (icecat-dir
998 (string-append "icecat-" #$%icecat-140.17.0-version)))
999
1000 (set-path-environment-variable
1001 "PATH" '("bin")
1002 (list #+python
1003 #+(canonical-package bash)
1004 #+(canonical-package coreutils)
1005 #+(canonical-package findutils)
1006 #+(canonical-package patch)
1007 #+(canonical-package xz)
1008 #+(canonical-package zstd)
1009 #+(canonical-package sed)
1010 #+(canonical-package grep)
1011 #+(canonical-package bzip2)
1012 #+(canonical-package gzip)
1013 #+(canonical-package tar)))
1014
1015 (set-path-environment-variable
1016 "PYTHONPATH"
1017 (list #+(format #f "lib/python~a/site-packages"
1018 (version-major+minor
1019 (package-version python))))
1020 '#+(cons python-jsonschema
1021 (map second
1022 (package-transitive-propagated-inputs
1023 python-jsonschema))))
1024
1025 ;; We copy the gnuzilla source directory because it is
1026 ;; read-only in 'gnuzilla-source', and the makeicecat script
1027 ;; uses "cp -a" to copy parts of it and assumes that the
1028 ;; copies will be writable.
1029 (copy-recursively #+gnuzilla-source "/tmp/gnuzilla"
1030 #:log (%make-void-port "w"))
1031
1032 (with-directory-excursion "/tmp/gnuzilla"
1033 (make-file-writable "makeicecat")
1034 (invoke "patch" "--force" "--no-backup-if-mismatch"
1035 "-p1" "--input" #+makeicecat-patch)
1036 (patch-shebang "makeicecat")
1037 (substitute* "makeicecat"
1038 (("^readonly FFMAJOR=(.*)" all ffmajor)
1039 (unless (string=? #$major-version
1040 (string-trim-both ffmajor))
1041 ;; The makeicecat script cannot be expected to work
1042 ;; properly on a different version of Firefox, even if
1043 ;; no errors occur during execution.
1044 (error "makeicecat major version mismatch"))
1045 (string-append "readonly FFMAJOR=" #$major-version "\n"))
1046 (("^readonly FFMINOR=.*")
1047 (string-append "readonly FFMINOR=" #$minor-version "\n"))
1048 (("^readonly FFSUB=.*")
1049 (string-append "readonly FFSUB=" #$sub-version "\n"))
1050 (("^readonly DATADIR=.*")
1051 "readonly DATADIR=/tmp/gnuzilla/data\n")
1052 (("^readonly SOURCEDIR=.*")
1053 (string-append "readonly SOURCEDIR=" icecat-dir "\n"))
1054 (("/bin/sed")
1055 #+(file-append (canonical-package sed) "/bin/sed"))))
1056
1057 (format #t "Unpacking upstream firefox tarball...~%")
1058 (force-output)
1059 (invoke "tar" "xf" #+upstream-firefox-source)
1060 (rename-file firefox-dir icecat-dir)
1061
1062 (with-directory-excursion icecat-dir
1063 (format #t "Populating l10n directory...~%")
1064 (force-output)
1065 (mkdir "l10n")
1066 (with-directory-excursion "l10n"
1067 (for-each
1068 (lambda (locale)
1069 (let ((locale-dir (string-append #+mozilla-140.17.0-l10n "/"
1070 locale)))
1071 (format #t " ~a~%" locale)
1072 (force-output)
1073 (copy-recursively locale-dir locale
1074 #:log (%make-void-port "w"))
1075 (for-each make-file-writable (find-files locale))
1076 (with-directory-excursion locale
1077 (mkdir-p "browser/chrome/browser/preferences")
1078 (call-with-output-file "browser/chrome/browser/\
1079preferences/advanced-scripts.dtd"
1080 (lambda (port) #f)))))
1081 '#+%icecat-140.17.0-locales)
1082 (copy-recursively #+mozilla-140.17.0-compare-locales
1083 "compare-locales"
1084 #:log (%make-void-port "w"))
1085 (delete-file "compare-locales/.gitignore")))
1086
1087 (format #t "Running makeicecat script...~%")
1088 (force-output)
1089 (invoke "bash" "/tmp/gnuzilla/makeicecat")
1090
1091 (format #t "Packing IceCat source tarball...~%")
1092 (force-output)
1093 (setenv "ZSTD_NBTHREADS" (number->string (parallel-job-count)))
1094 (invoke "tar" "cfa" #$output
1095 ;; Avoid non-determinism in the archive. We set the
1096 ;; mtime of files in the archive to early 1980 because
1097 ;; the build process fails if the mtime of source
1098 ;; files is pre-1980, due to the creation of zip
1099 ;; archives.
1100 "--mtime=@315619200" ; 1980-01-02 UTC
1101 "--owner=root:0"
1102 "--group=root:0"
1103 "--sort=name"
1104 icecat-dir)))))))))
1105
1106(define %icedove-build-id "20260929000000") ;must be of the form YYYYMMDDhhmmss
1107;;; See <https://product-details.mozilla.org/1.0/thunderbird_versions.json>
1108;;; for the source of truth regarding Thunderbird releases.
1109;;; Please keep these version numbers in sync with icecat.
1110;;; Please also update thunderbird-comm-source and thunderbird-comm-l10n to
1111;;; the icedove version.
1112(define %icedove-version "140.17.0")
1113
1114;; Provides the "comm" folder which is inserted into the icecat source.
1115;; Avoids the duplication of Icecat's source tarball. Pick the changeset that
1116;; matches the most recent tag of the form 'THUNDERBIRD_140_2_0esr_RELEASE'.
1117;; Please also update the commit of thunderbird-comm-l10n to match the
1118;; changeset used by thunderbird-comm-source.
1119(define thunderbird-comm-source
1120 (origin
1121 (method hg-fetch)
1122 (uri (hg-reference
1123 (url "https://hg.mozilla.org/releases/comm-esr140")
1124 (changeset "b597cbd02b76abf43bc73d58c24e52a26116cc26")))
1125 (file-name (string-append "thunderbird-" %icedove-version "-checkout"))
1126 (sha256
1127 (base32
1128 "0g044rdp2y98vrdb0gwbmv9j8cqqn06jmjz235v63kgns08f6slw"))
1129 (patches (search-patches "icedove-observer-fix.patch"))))
1130
1131;;; To regenerate, see the `format-locales' helper defined above.
1132(define %icedove-locales
1133 '("af"
1134 "ar"
1135 "ast"
1136 "be"
1137 "bg"
1138 "br"
1139 "ca"
1140 "cak"
1141 "cs"
1142 "cy"
1143 "da"
1144 "de"
1145 "dsb"
1146 "el"
1147 "en-CA"
1148 "en-GB"
1149 "es-AR"
1150 "es-ES"
1151 "es-MX"
1152 "et"
1153 "eu"
1154 "fi"
1155 "fr"
1156 "fy-NL"
1157 "ga-IE"
1158 "gd"
1159 "gl"
1160 "he"
1161 "hr"
1162 "hsb"
1163 "hu"
1164 "hy-AM"
1165 "id"
1166 "is"
1167 "it"
1168 "ja"
1169 "ja-JP-mac"
1170 "ka"
1171 "kab"
1172 "kk"
1173 "ko"
1174 "lt"
1175 "lv"
1176 "mk"
1177 "ms"
1178 "nb-NO"
1179 "nl"
1180 "nn-NO"
1181 "pa-IN"
1182 "pl"
1183 "pt-BR"
1184 "pt-PT"
1185 "rm"
1186 "ro"
1187 "ru"
1188 "sk"
1189 "sl"
1190 "sq"
1191 "sr"
1192 "sv-SE"
1193 "th"
1194 "tr"
1195 "uk"
1196 "uz"
1197 "vi"
1198 "zh-CN"
1199 "zh-TW"))
1200
1201(define thunderbird-comm-l10n
1202 ;; The commit to use can be found in the mail/locales/l10n-changesets.json
1203 ;; file in Thunderbird's source (e.g.:
1204 ;; <https://hg-edge.mozilla.org/releases/comm-esr140/file/098a7023447feeb0b722efc9eed25f56ed3e9bc1/mail/locales/l10n-changesets.json>)
1205 ;; where the hash in the URL is the changeset from thunderbird-comm-source.
1206 (let* ((commit "938c3663efd9771a2bbdcc02d1236142424a50de")
1207 (revision "0")
1208 (version (git-version %icedove-version revision commit)))
1209 (origin
1210 (method git-fetch)
1211 (uri (git-reference
1212 (url "https://github.com/thunderbird/thunderbird-l10n")
1213 (commit commit)))
1214 (file-name (git-file-name "thunderbird-l10n" version))
1215 (sha256
1216 (base32
1217 "1ncn0rfz0g3ich7h3hc6znvndydsyzj1ml8gd31hpslcnc33ydjx")))))
1218
1219(define icedove-source
1220 (let ((name (string-append "icedove-" %icedove-version)))
1221 (origin
1222 (method computed-origin-method)
1223 (file-name (string-append name ".tar.zst"))
1224 (sha256 #f)
1225 (uri
1226 (delay
1227 (with-imported-modules (source-module-closure '((guix build utils)))
1228 #~(begin
1229 (use-modules (guix build utils)
1230 (sxml simple))
1231
1232 (set-path-environment-variable
1233 "PATH" '("bin")
1234 (list #+(canonical-package tar)
1235 #+(canonical-package zstd)))
1236
1237 ;; Extract the base Icecat tarball, renaming its top-level
1238 ;; directory.
1239 (invoke "tar" "--transform" (string-append "s,[^/]*," #$name ",")
1240 "-xf" #$icecat-140.17.0-source)
1241 (chdir #$name)
1242
1243 ;; Merge the Thunderdbird localization data.
1244 (copy-recursively #$thunderbird-comm-l10n "l10n")
1245
1246 ;; Add the Thunderbird-specific "comm" directory.
1247 (mkdir "comm")
1248 (copy-recursively #$thunderbird-comm-source "comm")
1249 (for-each make-file-writable (find-files "comm"))
1250 (delete-file "sourcestamp.txt")
1251
1252 ;; Adjust the application name.
1253 (substitute* "comm/mail/moz.configure"
1254 (("\"MOZ_APP_NAME\", \"thunderbird\"")
1255 "\"MOZ_APP_NAME\", \"icedove\""))
1256
1257 ;; Remove branding to comply with Mozilla's trademark policy
1258 (with-directory-excursion "comm/mail/branding/nightly"
1259 (delete-file "content/about-wordmark.svg")
1260 (call-with-output-file "content/about-wordmark.svg"
1261 (lambda (port)
1262 (sxml->xml '(svg (@ (xmlns "http://www.w3.org/2000/svg")
1263 (viewBox "0 0 789.1 90.78")
1264 (width "333")
1265 (height "48")
1266 (fill "#fff"))
1267 (text (@ (x "400") (y "70")
1268 (text-anchor "middle")
1269 (font-size "90"))
1270 "Icedove Daily"))
1271 port)))
1272 (substitute* '("locales/en-US/brand.properties"
1273 "locales/en-US/brand.ftl"
1274 "locales/en-US/brand.dtd"
1275 "configure.sh")
1276 (("Thunderbird") "Icedove")
1277 (("mozilla.org") "guix.gnu.org")))
1278 ;; Remove other mentions of Thunderbird in user-visible text.
1279 (with-directory-excursion "comm/mail/base/content"
1280 (substitute* '("overrides/app-license-name.html")
1281 (("Thunderbird") "Icedove")))
1282 (with-directory-excursion "comm/mail/components/"
1283 (substitute* '("MailGlue.sys.mjs"
1284 "extensions/schemas/addressBook.json"
1285 "extensions/schemas/tabs.json"
1286 "extensions/schemas/cloudFile.json"
1287 "extensions/schemas/chrome_settings_overrides.json"
1288 "extensions/schemas/windows.json"
1289 "extensions/parent/ext-mail.js"
1290 "im/messages/mail/Info.plist"
1291 "enterprisepolicies/moz.build"
1292 "enterprisepolicies/helpers/moz.build"
1293 "enterprisepolicies/schemas/moz.build")
1294 (("Thunderbird") "Icedove")))
1295 (substitute* '("devtools/startup/DevToolsStartup.sys.mjs"
1296 "comm/mailnews/base/prefs/content/accountUtils.js"
1297 "comm/mail/base/content/customizeToolbar.js"
1298 "comm/suite/components/customizeToolbar.js")
1299 (("AppConstants.MOZ_APP_NAME (.)= \"thunderbird" _ e)
1300 (format #f "AppConstants.MOZ_APP_NAME ~a= \"icedove" e)))
1301
1302 ;; Override addon URLs and settings
1303 (substitute* "comm/mail/app/profile/all-thunderbird.js"
1304 (("(pref\\(\"extensions.webservice.discoverURL\").*" _ m)
1305 (string-append m ", \"https://directory.fsf.org/wiki/Icedove\");"))
1306 (("(pref\\(\"extensions.getAddons.search.url\").*" _ m)
1307 (string-append m ", \"https://guix.gnu.org/packages\");"))
1308 (("(pref\\(\"extensions.update.enabled\").*" _ m)
1309 (string-append m ", false);"))
1310 (("(pref\\(\"extensions.systemAddon.update.enabled\").*" _ m)
1311 (string-append m ", false);"))
1312 (("(pref\\(\"lightweightThemes.update.enabled\").*" _ m)
1313 (string-append m ", false);"))
1314 (("(pref\\(\"services.settings.server\").*" _ m)
1315 (string-append m ", \"\");"))
1316
1317 ;; XXX: The autoDisableScopes is tweaked by the makeicecat
1318 ;; script, but it doesn't know about Thunderbird. This is
1319 ;; necessary to allow picking up the extensions found in the
1320 ;; system global application directory, such as the language
1321 ;; packs.
1322 (("\"extensions.autoDisableScopes\", 15")
1323 "\"extensions.autoDisableScopes\", 3")
1324
1325 ;; Set the default locale to that of the operating system.
1326 ((".*extensions.autoDisableScopes.*" anchor)
1327 (string-append anchor
1328 "pref(\"intl.locale.requested\", \"\");\n")))
1329
1330 ;; Fix more discrepancies caused by the fact that the
1331 ;; makeicecat script didn't run on the Thunderbird sources.
1332 (substitute* '("Cargo.lock"
1333 "comm/rust/Cargo.lock"
1334 "comm/rust/Cargo.toml"
1335 "gfx/qcms/Cargo.toml"
1336 "toolkit/library/rust/shared/Cargo.toml")
1337 (("IceCatGraphics") "FirefoxGraphics")
1338 (("firefox-on-glean") "icecat-on-glean"))
1339
1340 ;; Step out of the directory and create the tarball.
1341 (chdir "..")
1342 (format #t "Packing Icedove source tarball...~%")
1343 (force-output)
1344 (setenv "ZSTD_NBTHREADS" (number->string (parallel-job-count)))
1345 (invoke "tar" "cfa" #$output
1346 "--mtime=@315619200" ;1980-01-02 UTC
1347 "--owner=root:0"
1348 "--group=root:0"
1349 "--sort=name"
1350 #$name))))))))
1351
1352(define-public icedove-minimal
1353 (package
1354 (name "icedove-minimal")
1355 (version %icedove-version)
1356 (source icedove-source)
1357 (properties
1358 `((cpe-name . "thunderbird_esr")))
1359 (build-system gnu-build-system)
1360 (arguments
1361 (list
1362 #:tests? #f ;no check target
1363 #:imported-modules %cargo-utils-modules ;for `generate-all-checksums'
1364 #:modules `((guix build utils) ;find-files
1365 (sxml simple)
1366 (ice-9 regex)
1367 ,@%default-gnu-modules)
1368 #:phases
1369 #~(modify-phases %standard-phases
1370 (add-after 'unpack 'do-not-verify-vendored-rust-dependencies
1371 (lambda _
1372 (substitute* "comm/python/rocbuild/rocbuild/rust.py"
1373 (("result = check_vendored_dependencies\\(topsrcdir)")
1374 "sys.exit(0)"))))
1375 (add-after 'patch-source-shebangs 'patch-cargo-checksums
1376 (lambda _
1377 (use-modules (guix build cargo-utils))
1378 (let ((null-hash "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934\
1379ca495991b7852b855"))
1380 (for-each (lambda (file)
1381 (format #t "patching checksums in ~a~%" file)
1382 (substitute* file
1383 (("^checksum = \".*\"")
1384 (string-append "checksum = \"" null-hash "\""))))
1385 (find-files "." "Cargo.lock$"))
1386 (for-each generate-all-checksums
1387 '("services"
1388 "js"
1389 "third_party/rust"
1390 "dom/media"
1391 "dom/webauthn"
1392 "toolkit"
1393 "gfx"
1394 "storage"
1395 "modules"
1396 "xpcom/rust"
1397 "media"
1398 "mozglue/static/rust"
1399 "netwerk"
1400 "remote"
1401 "intl"
1402 "servo"
1403 "security/manager/ssl"
1404 "build"
1405 ;; Thunderbird-specific.
1406 "comm")))))
1407 (add-after 'patch-cargo-checksums 'remove-cargo-frozen-flag
1408 (lambda _
1409 ;; Remove --frozen flag from cargo invocation, otherwise it'll
1410 ;; complain that it's not able to change Cargo.lock.
1411 ;; https://bugzilla.mozilla.org/show_bug.cgi?id=1726373
1412 (substitute* "build/RunCbindgen.py"
1413 (("args.append\\(\"--frozen\"\\)") "pass"))
1414 (substitute* "config/makefiles/rust.mk"
1415 (("cargo_build_flags \\+= --frozen") ""))))
1416 ;; Fixes issue where each installation directory generates its own
1417 ;; profile (see:
1418 ;; https://trac.torproject.org/projects/tor/ticket/31457).
1419 (add-after 'patch-source-shebangs 'fix-profile-setting
1420 (lambda _
1421 (substitute* "comm/mail/moz.configure"
1422 (("\"MOZ_DEDICATED_PROFILES\", True")
1423 "\"MOZ_DEDICATED_PROFILES\", False"))))
1424 (add-after 'build 'neutralize-store-references
1425 (lambda _
1426 ;; Mangle the store references to compilers & other build tools in
1427 ;; about:buildconfig, reducing Icedove's closure significant.
1428 ;; The resulting files are saved in lib/thunderbird/omni.ja
1429 (substitute*
1430 ;; Use find because the path "obj-x86_64-pc-linux-gnu" contains
1431 ;; the architecture and the system -> more complicated.
1432 (find-files "." "buildconfig.html")
1433 (((format #f "(~a/)([0-9a-df-np-sv-z]{32})"
1434 (regexp-quote (%store-directory)))
1435 _ store hash)
1436 (string-append store
1437 (string-take hash 8)
1438 "<!-- Guix: not a runtime dependency -->"
1439 (string-drop hash 8))))))
1440 (delete 'bootstrap)
1441 (replace 'configure
1442 (lambda* (#:key native-inputs inputs configure-flags
1443 #:allow-other-keys)
1444 (let* ((bash (which "bash"))
1445 (abs-srcdir (getcwd))
1446 (srcdir (string-append "../" (basename abs-srcdir)))
1447 (flags `(,(string-append "--prefix=" #$output)
1448 ,@configure-flags))
1449 (mozconfig (string-append (getcwd) "/.mozconfig")))
1450 (setenv "SHELL" bash)
1451 (setenv "CONFIG_SHELL" bash)
1452 (setenv "QA_CONFIGURE_OPTIONS" ".*")
1453 (setenv "MOZBUILD_STATE_PATH"
1454 (string-append (getcwd) "/mach_state"))
1455 (setenv "MOZCONFIG"
1456 (string-append (getcwd) "/.mozconfig"))
1457
1458 (setenv "AR" "llvm-ar")
1459 (setenv "NM" "llvm-nm")
1460 (setenv "CC" "clang")
1461 (setenv "CXX" "clang++")
1462
1463 (setenv "MOZ_NOSPAM" "1")
1464 (setenv "MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE" "system")
1465 (setenv "GUIX_PYTHONPATH"
1466 (string-append (getcwd)
1467 "/obj-x86_64-pc-linux-gnu/_virtualenvs/build"))
1468
1469 (setenv "MOZ_BUILD_DATE" #$%icedove-build-id) ; avoid timestamp
1470 (setenv "MOZ_APP_NAME" "icedove")
1471 ;; WM_CLASS (default is "$MOZ_APP_NAME-$MOZ_UPDATE_CHANNEL").
1472 (setenv "MOZ_APP_REMOTINGNAME" "Icedove")
1473
1474 (setenv "LDFLAGS" (string-append "-Wl,-rpath=" #$output
1475 "/lib/icedove"))
1476 (mkdir-p (string-append (getcwd) "/builddir"))
1477 (with-output-to-file mozconfig
1478 (lambda ()
1479 (display
1480 (string-append
1481 "ac_add_options --allow-addon-sideload\n"
1482 "ac_add_options --with-unsigned-addon-scopes=app,system\n"
1483 "ac_add_options --disable-crashreporter\n"
1484 "ac_add_options --disable-debug\n"
1485 "ac_add_options --disable-debug-symbols\n"
1486 "ac_add_options --disable-elf-hack\n"
1487 "ac_add_options --disable-jit\n"
1488 "ac_add_options --disable-necko-wifi\n"
1489 "ac_add_options --disable-official-branding\n"
1490 "ac_add_options --disable-tests\n"
1491 "ac_add_options --disable-updater\n"
1492 "ac_add_options --disable-webrtc\n"
1493 "ac_add_options --enable-application=comm/mail\n"
1494 "ac_add_options --enable-default-toolkit=\"cairo-gtk3\"\n"
1495 "ac_add_options --enable-optimize\n"
1496 "ac_add_options --enable-pulseaudio\n"
1497 "ac_add_options --enable-release\n"
1498 "ac_add_options --enable-rust-simd\n"
1499 "ac_add_options --enable-strip\n"
1500 "ac_add_options --enable-system-ffi\n"
1501 "ac_add_options --enable-system-pixman\n"
1502 "ac_add_options --prefix=" #$output "\n"
1503 "ac_add_options --with-clang-path="
1504 (search-input-file (or native-inputs inputs)
1505 "bin/clang") "\n"
1506 "ac_add_options --with-distribution-id=org.gnu\n"
1507 "ac_add_options --with-libclang-path="
1508 #$(this-package-native-input "clang") "/lib\n"
1509 "ac_add_options --with-system-bz2\n"
1510 "ac_add_options --with-system-icu\n"
1511 "ac_add_options --with-system-jpeg\n"
1512 "ac_add_options --with-system-libevent\n"
1513 "ac_add_options --with-system-nspr\n"
1514 "ac_add_options --with-system-nss\n"
1515 "ac_add_options --with-system-zlib\n"
1516 "ac_add_options --without-wasm-sandboxed-libraries\n"
1517 "mk_add_options MOZ_MAKE_FLAGS=-j"
1518 (number->string (parallel-job-count)) "\n"))))
1519 (display (getcwd))
1520 (newline)
1521 (display "mach configure")
1522 (invoke "./mach" "configure"))))
1523 (replace 'build
1524 (lambda _ (invoke "./mach" "build")))
1525 (replace 'install
1526 (lambda _ (invoke "./mach" "install")))
1527 ;; Thunderbird doesn't provide any .desktop file.
1528 ;; See https://bugzilla.mozilla.org/show_bug.cgi?id=1637575
1529 (add-after 'install 'install-desktop-file
1530 (lambda _
1531 (let ((apps (string-append #$output "/share/applications")))
1532 (mkdir-p apps)
1533 (with-output-to-file (string-append apps "/icedove.desktop")
1534 (lambda _
1535 (format #t
1536 "[Desktop Entry]~@
1537 Name=Icedove~@
1538 Exec=~a/bin/icedove %u~@
1539 Icon=icedove~@
1540 GenericName=Mail/News Client~@
1541 Categories=Network;Email;~@
1542 Terminal=false~@
1543 StartupNotify=true~@
1544 MimeType=x-scheme-handler/mailto;~@
1545 Type=Application~@
1546 Actions=ComposeMessage;~@
1547 StartupWMClass=Icedove;~@
1548 [Desktop Action ComposeMessage]~@
1549 Name=Write new message~@
1550 Exec=~@*~a/bin/icedove -compose~%"
1551 #$output))))))
1552 (add-after 'install-desktop-file 'install-icons
1553 ;; TODO: Use actual Icedove branding icons (currently the stock
1554 ;; Thunderbird icon is used).
1555 (lambda _
1556 (with-directory-excursion "comm/mail/branding/thunderbird"
1557 (for-each
1558 (lambda (file)
1559 (let* ((size (string-filter char-numeric? file))
1560 (icons (string-append #$output "/share/icons/hicolor/"
1561 size "x" size "/apps")))
1562 (mkdir-p icons)
1563 (copy-file file (string-append icons "/icedove.png"))))
1564 '("default16.png" "default22.png" "default24.png"
1565 "default32.png" "default48.png" "default256.png")))))
1566 (add-after 'install 'wrap-program
1567 (lambda* (#:key inputs #:allow-other-keys)
1568 (let* ((lib (string-append #$output "/lib"))
1569 (gpgme #$(this-package-input "gpgme"))
1570 (gpgme-lib (string-append gpgme "/lib"))
1571 (gtk #$(this-package-input "gtk+"))
1572 (gtk-share (string-append gtk "/share"))
1573 (pulseaudio #$(this-package-input "pulseaudio"))
1574 (pulseaudio-lib (string-append pulseaudio "/lib"))
1575 (eudev #$(this-package-input "eudev"))
1576 (eudev-lib (string-append eudev "/lib"))
1577 ;; For the integration of native notifications (same reason as icecat)
1578 (libnotify #$(this-package-input "libnotify"))
1579 (libnotify-lib (string-append libnotify "/lib"))
1580 (mesa #$(this-package-input "mesa"))
1581 (mesa-lib (string-append mesa "/lib"))
1582 (pciutils #$(this-package-input "pciutils"))
1583 (pciutils-lib (string-append pciutils "/lib"))
1584 (libva #$(this-package-input "libva"))
1585 (libva-lib (string-append libva "/lib"))
1586 (libotr #$(this-package-input "libotr"))
1587 (libotr-lib (string-append libotr "/lib")))
1588 (wrap-program (car (find-files lib "^icedove$"))
1589 `("XDG_DATA_DIRS" prefix (,gtk-share))
1590 `("LD_LIBRARY_PATH" prefix
1591 ( ,pulseaudio-lib ,eudev-lib ,libnotify-lib ,gpgme-lib
1592 ,mesa-lib ,libva-lib ,libotr-lib ,pciutils-lib)))))))))
1593 (inputs
1594 (list alsa-lib
1595 bash-minimal
1596 bzip2
1597 cairo
1598 cups
1599 dbus-glib
1600 eudev
1601 ffmpeg
1602 freetype
1603 gdk-pixbuf
1604 glib
1605 gpgme
1606 gtk+
1607 hunspell
1608 icu4c-77
1609 libcanberra
1610 libevent
1611 libffi
1612 libgnome
1613 libjpeg-turbo
1614 libnotify
1615 libotr
1616 libpng-apng
1617 libva
1618 libvpx
1619 libxcomposite
1620 libxft
1621 libxinerama
1622 libxscrnsaver
1623 libxt
1624 mesa
1625 mit-krb5
1626 nspr
1627 nss-rapid
1628 pango
1629 pciutils
1630 pixman
1631 pulseaudio
1632 sqlite
1633 startup-notification
1634 unzip
1635 zip
1636 zlib))
1637 (native-inputs
1638 (list clang-20
1639 llvm-20
1640 m4
1641 nasm
1642 node-lts
1643 perl
1644 pkg-config
1645 python-wrapper
1646 rust
1647 `(,rust "cargo")
1648 rust-cbindgen
1649 which
1650 yasm))
1651 (home-page "https://www.thunderbird.net")
1652 (synopsis "Rebranded Mozilla Thunderbird email client")
1653 (description
1654 "This package provides an email client built based on Mozilla
1655Thunderbird. It supports email, news feeds, chat, calendar and contacts.")
1656 (license license:mpl2.0)))
1657
1658(define (make-l10n-package project version source locales)
1659 "Return a package for PROJECT, a symbol (either icecat or icedove), with
1660their corresponding VERSION, SOURCE and LOCALES variables."
1661 (unless (member project '(icecat icedove))
1662 (error "only icecat or icedove components are currently supported"))
1663
1664 (let ((name (if (eq? 'icecat project)
1665 "IceCat"
1666 "Icedove")))
1667 (package
1668 (name (format #f "~a-l10n" project))
1669 (version version)
1670 (source source)
1671 (outputs (cons "out" locales))
1672 (build-system gnu-build-system)
1673 (arguments
1674 (list
1675 #:modules '((guix build gnu-build-system)
1676 (guix build utils)
1677 (ice-9 format)
1678 (ice-9 ftw)
1679 (srfi srfi-1)
1680 (srfi srfi-26))
1681 #:tests? #f ;no tests, this is data
1682 #:phases
1683 #~(modify-phases %standard-phases
1684 (delete 'bootstrap)
1685 (delete 'install)
1686 (replace 'configure
1687 (lambda _
1688 ;; The following configuration is inspired by guidance at
1689 ;; https://firefox-source-docs.mozilla.org/build/buildsystem/locales.html.
1690 (call-with-output-file ".mozconfig"
1691 (lambda (p)
1692 (format p "~{~a~%~}"
1693 (list (if (eq? 'icecat '#$project)
1694 "ac_add_options --enable-project=browser"
1695 "ac_add_options --enable-project=comm/mail")
1696 "ac_add_options --disable-compile-environment"
1697 (string-append
1698 "ac_add_options --with-l10n-base="
1699 (getcwd) "/l10n")
1700 ;; Hack, otherwise the build system throws:
1701 ;; 'RuntimeError: File "brand.dtd" not found'.
1702 "ac_add_options --enable-official-branding"
1703 "mk_add_options MOZ_OBJDIR=obj"))))
1704 (setenv "CONFIG_SHELL" (which "bash"))
1705 (setenv "MOZBUILD_STATE_PATH"
1706 (string-append (getcwd) "/mach_state"))
1707 (setenv "MOZCONFIG" (string-append (getcwd) "/.mozconfig"))
1708 (setenv "MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE" "system")
1709 (setenv "BUILD_BACKENDS" "FasterMake,RecursiveMake")))
1710 (replace 'build ;build and install data files
1711 (lambda* (#:key outputs #:allow-other-keys)
1712 (define (find-file dir name)
1713 (let ((files (find-files dir name)))
1714 (when (null? files)
1715 (error "could not find file in dir" name dir))
1716 (car files)))
1717
1718 ;; Register "tb_common" as a valid site, to please the mach
1719 ;; virtualenv machinery (see:
1720 ;; <https://bugzilla.mozilla.org/show_bug.cgi?id=1986420>).
1721 (substitute* "python/mach/mach/site.py"
1722 (("\"mach\", \"build\", \"common\"" all)
1723 (string-append all ", \"tb_common\"")))
1724
1725 (for-each
1726 (lambda (l)
1727 (let* ((out (assoc-ref outputs l))
1728 ;; The older lib/$project/distribution/extensions
1729 ;; directory is deprecated. Use the newer app-global
1730 ;; directory, which is lib/$project/extensions.
1731 (ext-dir-prefix
1732 (format
1733 #f "lib/~a/~:[~;browser/~]extensions"
1734 '#$project (eq? 'icecat '#$project)))
1735 (all-ext (string-append #$output "/" ext-dir-prefix))
1736 (ext-dir (string-append out "/" ext-dir-prefix))
1737 ;; XXX: Because Icedove doesn't have a makeicedove
1738 ;; script that substitutes all the Thunderbird
1739 ;; references to Icedove, the MOZ_LANGPACK_EID
1740 ;; defined in comm/mail/locales/Makefile.in uses
1741 ;; 'thunderbird' in its ID extension rather than
1742 ;; 'icedove'.
1743 (name (format #f "langpack-~a@~a.mozilla.org.xpi"
1744 l (if (eq? 'icedove '#$project)
1745 'thunderbird
1746 '#$project))))
1747 (format #t "processing locale `~a'...~%" l)
1748 ;; TODO: Revert to use 'invoke' here, after
1749 ;; <https://bugzilla.mozilla.org/show_bug.cgi?id=1988069>
1750 ;; is fixed.
1751 (system* "./mach" "build" (string-append "langpack-" l))
1752 (mkdir-p ext-dir)
1753 (let ((xpi (find-file "obj" (string-append
1754 "\\." l "\\.langpack\\.xpi$"))))
1755 (copy-file xpi (string-append ext-dir "/" name))
1756 ;; Symlink to the main output so that a user can
1757 ;; install all of the language packs at once.
1758 (mkdir-p all-ext)
1759 (symlink (string-append ext-dir "/" name)
1760 (string-append all-ext "/" name)))))
1761 '#$locales))))))
1762 (native-inputs
1763 (list m4
1764 perl
1765 python
1766 python-aiohttp
1767 python-async-timeout
1768 python-dateutil
1769 node-lts
1770 unzip))
1771 (home-page "https://www.mozilla.org/")
1772 (synopsis (string-append "Language localization data for " name))
1773 (description (string-append "This package contains the various language
1774localization data files (language pack extensions) for " name ". The
1775individual localization packages can be installed by using the output
1776associated with their name."))
1777 (license license:mpl2.0))))
1778
1779(define-public icecat-l10n
1780 (make-l10n-package 'icecat %icecat-version icecat-source %icecat-locales))
1781
1782(define-public icedove-l10n
1783 (make-l10n-package 'icedove %icedove-version icedove-source %icedove-locales))
1784
1785;;; This hack exists because there's no way to configure extra extension
1786;;; search paths for IceCat or Icedove. The global extensions directory is
1787;;; constructed relatively to the executable file name.
1788(define (make-mozilla-with-l10n project base l10n-package)
1789 "Return a package definition for PROJECT (a symbol such as 'icecat or
1790'icedove) that combines the BASE package with L10N-PACKAGE."
1791
1792 (unless (member project '(icecat icedove))
1793 (error "only icecat or icedove components are currently supported"))
1794
1795 (let ((name (symbol->string project))
1796 (icecat? (eq? 'icecat project)))
1797 (package
1798 (inherit base)
1799 (name (symbol->string project))
1800 ;; Use the copy-build-system, as it provides the necessary UTF-8 locales
1801 ;; support.
1802 (build-system copy-build-system)
1803 (arguments
1804 (list
1805 #:imported-modules `(,@%copy-build-system-modules
1806 (guix build union))
1807 #:modules '((guix build copy-build-system)
1808 (guix build union)
1809 (guix build utils))
1810 #:phases
1811 #~(modify-phases %standard-phases
1812 (replace 'install
1813 (lambda _
1814 (union-build #$output (list #$base #$l10n-package)
1815 #:create-all-directories? #t)
1816
1817 (define* (expose name #:optional (proc copy-file)
1818 #:key (source #$base))
1819 (let ((dest (string-append #$output "/" name)))
1820 (mkdir-p (dirname dest))
1821 (proc (string-append source "/" name) dest)))
1822
1823 (let ((wrapper (string-append "lib/" #$name "/" #$name))
1824 (real-binary (string-append "lib/" #$name "/." #$name
1825 "-real"))
1826 (desktop-file (string-append "share/applications/"
1827 #$name ".desktop")))
1828 ;; Copy wrapper file.
1829 (delete-file (string-append #$output "/" wrapper))
1830 (expose wrapper)
1831
1832 ;; Recreate bin symlink.
1833 (delete-file (string-append #$output "/bin/" #$name))
1834 (symlink (string-append #$output "/" wrapper)
1835 (string-append #$output "/bin/" #$name))
1836
1837 ;; Copy actual binary.
1838 (delete-file (string-append #$output "/" real-binary))
1839 (expose real-binary)
1840
1841 ;; Copy desktop file.
1842 (delete-file (string-append #$output "/" desktop-file))
1843 (expose desktop-file)
1844
1845 ;; Adjust the references in the desktop file and wrapper.
1846 (substitute* (list (string-append #$output "/" desktop-file)
1847 (string-append #$output "/" wrapper))
1848 ((#$base) #$output)))))))))))
1849
1850(define-public icecat
1851 (make-mozilla-with-l10n 'icecat icecat-minimal icecat-l10n))
1852
1853(define-public icedove
1854 (make-mozilla-with-l10n 'icedove icedove-minimal icedove-l10n))
1855
1856(define-public icedove/wayland
1857 (package
1858 (inherit icedove-minimal)
1859 (name "icedove-wayland")
1860 (build-system trivial-build-system)
1861 (arguments
1862 (list
1863 #:modules '((guix build utils))
1864 #:builder
1865 #~(begin
1866 (use-modules (guix build utils))
1867 (let* ((exe (string-append #$output "/bin/icedove")))
1868 (mkdir-p (dirname exe))
1869 (call-with-output-file exe
1870 (lambda (port)
1871 (format port "#!~a
1872 MOZ_ENABLE_WAYLAND=1 exec ~a \"$@\""
1873 #$(file-append bash-minimal "/bin/bash")
1874 #$(file-append icedove-minimal "/bin/icedove"))))
1875 (chmod exe #o555)
1876 ;; Provide the manual and .desktop file.
1877 (copy-recursively (string-append #$icedove-minimal "/share")
1878 (string-append #$output "/share"))
1879 (substitute* (string-append #$output
1880 "/share/applications/icedove.desktop")
1881 ((#$icedove-minimal) #$output))))))
1882 (native-inputs '())
1883 (inputs '())))
1884
1885(define-public mozjs
1886 (package
1887 (name "mozjs")
1888 (version %icecat-140.17.0-version)
1889 (source (origin (inherit icecat-140.17.0-source)
1890 (patches (search-patches "mozjs-bug-1973994-fix-c-header.patch"))))
1891 (build-system gnu-build-system)
1892 (arguments
1893 (list
1894 #:imported-modules %cargo-utils-modules ;for `generate-all-checksums'
1895 #:modules `((guix build cargo-utils)
1896 ,@%default-gnu-modules)
1897 #:test-target "check-jstests"
1898 #:configure-flags
1899 #~(list
1900 ;; Disable debugging symbols to save space.
1901 "--disable-debug"
1902 "--disable-debug-symbols"
1903 ;; This is important because without it gjs will segfault during the
1904 ;; configure phase. With jemalloc only the standalone mozjs console
1905 ;; will work.
1906 "--disable-jemalloc"
1907 "--enable-tests"
1908 "--enable-hardening"
1909 "--enable-optimize"
1910 "--enable-release"
1911 "--enable-readline"
1912 "--enable-rust-simd"
1913 "--enable-shared-js"
1914 "--with-system-icu"
1915 "--with-system-nspr"
1916 "--with-system-zlib"
1917 "--with-intl-api")
1918 #:phases
1919 #~(modify-phases %standard-phases
1920 (add-after 'unpack 'python-3.11-compatibility
1921 (lambda _
1922 (substitute* '("python/mozbuild/mozpack/files.py"
1923 "python/mozbuild/mozbuild/util.py"
1924 "python/mozbuild/mozbuild/action/process_define_files.py"
1925 "python/mozbuild/mozbuild/backend/base.py"
1926 "python/mozbuild/mozbuild/preprocessor.py")
1927 (("\"rU\"") "\"r\""))))
1928 (add-after 'unpack 'restore-api-compat
1929 (lambda _
1930 (substitute* "js/public/GCAPI.h"
1931 (("enum class GCReason")
1932 "#define FIRST_FIREFOX_REASON FIRST_ICECAT_REASON
1933#define LAST_FIREFOX_REASON LAST_ICECAT_REASON
1934enum class GCReason"))))
1935 (add-after 'patch-source-shebangs 'patch-cargo-checksums
1936 (lambda _
1937 (let ((null-hash
1938 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"))
1939 (for-each (lambda (file)
1940 (format #t "patching checksums in ~a~%" file)
1941 (substitute* file
1942 (("^checksum = \".*\"")
1943 (string-append "checksum = \"" null-hash "\""))))
1944 (find-files "." "Cargo\\.lock$"))
1945 (for-each generate-all-checksums
1946 '("js" "third_party/rust")))))
1947 (replace 'configure
1948 (lambda* (#:key configure-flags #:allow-other-keys)
1949 ;; The configure script does not accept environment variables as
1950 ;; arguments. It also must be run from a different directory,
1951 ;; but not the root directory either.
1952 (mkdir "run-configure-from-here")
1953 (chdir "run-configure-from-here")
1954 ;; Configure script writes to $HOME.
1955 (setenv "HOME" (getcwd))
1956 (setenv "SHELL" (which "sh"))
1957 (setenv "CONFIG_SHELL" (which "sh"))
1958 (setenv "AUTOCONF" (which "autoconf"))
1959 (apply invoke "python" "../configure.py"
1960 "--enable-project=js"
1961 (string-append "--prefix=" #$output)
1962 configure-flags)))
1963 (add-before 'check 'adjust-tests
1964 (lambda _
1965 (with-directory-excursion "../js/src/tests"
1966 (substitute* "shell/os.js"
1967 ;; FIXME: Why does the killed process have an exit status?
1968 ((".*killed process should not have exitStatus.*")
1969 ""))
1970
1971 ;; Test failures are marked with “TEST-UNEXPECTED-FAIL”.
1972 ;;
1973 ;; Most of the timezone related failures are probably
1974 ;; attributable to our use of a system-provided icu4c library
1975 ;; instead of the bundled one.
1976 (for-each
1977 delete-file
1978 '( ;; FIXME: An one-hour difference is produced after DST
1979 ;; starting in the timezone the test suite uses.
1980 "non262/Date/15.9.5.7.js"
1981
1982 ;; The test suite expects a lightly patched ICU. Disable tests
1983 ;; that do not work with the system version. See
1984 ;; "intl/icu-patches" for clues.
1985
1986 ;; See <https://unicode-org.atlassian.net/browse/ICU-20992> and
1987 ;; <https://bugzilla.mozilla.org/show_bug.cgi?id=1636984> and
1988 ;; related patch for why this is failing.
1989 "non262/Intl/DateTimeFormat/fractional-second-digits-append-item.js"
1990 ;; FIXME: got "0 \u251CAM/PM: noon\u2524", expected "0 (AM/PM: noon)"
1991 "non262/Intl/DateTimeFormat/day-period-hour-cycle.js"
1992 ;; FIXME: got "en-US-posix", expected "en-US-POSIX".
1993 "non262/Intl/available-locales-supported.js"
1994 ;; FIXME: got "en-US", expected "en-US-POSIX"
1995 "non262/Intl/available-locales-resolved.js"
1996
1997;;; Since 115:
1998 ;; Mismatching array lengths
1999 "non262/Intl/supportedValuesOf-timeZones-canonical.js"
2000 ;; TODO: tzdata 2024a expected – find a way to regenerate
2001 ;; these generated tests
2002 "non262/Intl/DateTimeFormat/timeZone_version.js"
2003
2004 ;; FIXME: got "\uD840\uDDF2", expected "\u5047"
2005 "non262/Intl/Collator/implicithan.js"
2006 ;; FIXME: got "\uD840\uDDF2", expected "\u3467"
2007 "non262/Intl/Collator/big5han-gb2312han.js"
2008
2009 ;; Since 128:
2010 ;; FIXME: got (void 0), expected "GMT"
2011 "non262/Intl/DateTimeFormat/formatRange-timeZoneName-matches-format.js"
2012 ;; FIXME: got 7, expected 9: parts count mismatch
2013 "non262/Intl/DateTimeFormat/formatRange-timeZone-offset.js"
2014 "non262/Intl/DateTimeFormat/formatRange-timeZoneName.js"
2015
2016 ;; Since 140:
2017 ;; RangeError: invalid time zone: America/Coyhaique
2018 "non262/Temporal/ZonedDateTime/zones-and-links.js"
2019 ;; got 2042, expected 2043
2020 "non262/Temporal/Intl/consistent-dates.js"
2021 ;; got "Pacific/Auckland", expected "Antarctica/McMurdo"
2022 "non262/Intl/DateTimeFormat/timeZone_links.js"
2023 "test262/staging/sm/Temporal/ZonedDateTime/zones-and-links.js"
2024 ;; Test262Error: Expected true but got false
2025 "test262/staging/Intl402/Temporal/old/zoneddatetime-dst-corner-cases.js"
2026 ;; Test262Error: getTimeZoneTransition(next) does not return its input
2027 "test262/intl402/Temporal/ZonedDateTime/prototype/\
2028getTimeZoneTransition/result-type.js"
2029 ;; Expected SameValue («1912-01-01T00:16:08+00:00[Africa/Abidjan]», «null»
2030 "test262/intl402/Temporal/ZonedDateTime/prototype/\
2031getTimeZoneTransition/transition-at-instant-boundaries.js"
2032 ;; Expected SameValue(«1762063200000000000n», «1572760800000000000n»
2033 "test262/intl402/Temporal/ZonedDateTime/prototype/\
2034getTimeZoneTransition/specific-tzdb-values.js"
2035 ;; Expected SameValue(«"2025-03-30T03:00:00+02:00[Europe/Berlin]"»,
2036 ;; «"2020-10-25T02:00:00+01:00[Europe/Berlin]"»
2037 "test262/intl402/Temporal/ZonedDateTime/prototype/\
2038getTimeZoneTransition/nanoseconds-subtracted-or-added-at-dst-transition.js"
2039 ;; TypeError: can't access property "epochNanoseconds",
2040 ;; before.getTimeZoneTransition(...) is null
2041 "test262/intl402/Temporal/ZonedDateTime/prototype/\
2042getTimeZoneTransition/transitions-close-together.js"
2043
2044 ;; Since 140.11:
2045 "non262/Date/time-zones-historic.js"
2046 )))))
2047 (add-before 'check 'pre-check
2048 (lambda _
2049 (setenv "JSTESTS_EXTRA_ARGS"
2050 (string-join
2051 (list
2052 ;; Do not run tests marked as "random".
2053 "--exclude-random"
2054 ;; Exclude web platform tests.
2055 "--wpt=disabled"
2056 ;; Respect the daemons configured number of jobs.
2057 (string-append "--worker-count="
2058 (number->string (parallel-job-count)))))))))))
2059 (native-inputs
2060 (list autoconf
2061 llvm ;for llvm-objdump
2062 m4
2063 perl
2064 pkg-config
2065 python-wrapper
2066 rust
2067 `(,rust "cargo")
2068 rust-cbindgen))
2069 (inputs
2070 (list icu4c-77 readline zlib))
2071 (propagated-inputs
2072 (list nspr)) ; in the Requires.private field of mozjs-*.pc
2073 (home-page
2074 "https://spidermonkey.dev/")
2075 (synopsis "Mozilla JavaScript engine")
2076 (description "SpiderMonkey is Mozilla's JavaScript engine written
2077in C/C++.")
2078 (license license:mpl2.0))) ; and others for some files
2079
2080(define-public mozjs-128
2081 (package
2082 (inherit mozjs)
2083 (version "128.3.1")
2084 (source (origin
2085 (method url-fetch)
2086 ;; TODO: Switch to IceCat source once available on ftp.gnu.org.
2087 (uri (string-append "https://ftp.mozilla.org/pub/firefox"
2088 "/releases/" version "esr/source/firefox-"
2089 version "esr.source.tar.xz"))
2090 (sha256
2091 (base32
2092 "1a3h7p7126pxzpidb1lqckvhfh1had805mai4l96mnc878phbx61"))
2093 ;; 0ad requires this version of mozjs, which surfaces a bug
2094 ;; related to improper garbage collection.
2095 ;; See https://gitea.wildfiregames.com/0ad/0ad/issues/8757,
2096 ;; https://codeberg.org/guix/guix/issues/10467.
2097 (patches
2098 (search-patches "mozjs-fix-garbage-collector-tracer.patch"))))
2099 (arguments
2100 (substitute-keyword-arguments arguments
2101 ((#:configure-flags flags)
2102 #~(delete "--enable-rust-simd" #$flags))
2103 ((#:phases phases)
2104 #~(modify-phases #$phases
2105 (replace 'adjust-tests
2106 (lambda _
2107 (with-directory-excursion "../js/src/tests"
2108 (substitute* "shell/os.js"
2109 ;; FIXME: Why does the killed process have an exit status?
2110 ((".*killed process should not have exitStatus.*")
2111 ""))
2112
2113 ;; This was fixed sometime between 102.15.1 and 115.11.0.
2114 ;; These tests are supposed to be skipped on all 64-bit systems.
2115 #$@(if (target-riscv64?)
2116 #~((substitute* '("non262/Array/regress-157652.js"
2117 "non262/regress/regress-422348.js")
2118 (("mips64") "mips64|riscv64")))
2119 #~())
2120
2121 ;; FIXME: An one-hour difference is produced after DST
2122 ;; starting in the timezone the test suite uses.
2123 (delete-file "non262/Date/15.9.5.7.js")
2124
2125 ;; The test suite expects a lightly patched ICU. Disable tests
2126 ;; that do not work with the system version. See
2127 ;; "intl/icu-patches" for clues.
2128
2129 ;; See <https://unicode-org.atlassian.net/browse/ICU-20992> and
2130 ;; <https://bugzilla.mozilla.org/show_bug.cgi?id=1636984> and
2131 ;; related patch for why this is failing.
2132 (delete-file "non262/Intl/DateTimeFormat/\
2133fractional-second-digits-append-item.js")
2134 ;; FIXME: got "0 \u251CAM/PM: noon\u2524", expected "0 (AM/PM: noon)"
2135 (delete-file "non262/Intl/DateTimeFormat/day-period-hour-cycle.js")
2136 ;; FIXME: got "en-US-posix", expected "en-US-POSIX".
2137 (delete-file "non262/Intl/available-locales-supported.js")
2138 ;; FIXME: got "en-US", expected "en-US-POSIX"
2139 (delete-file "non262/Intl/available-locales-resolved.js")
2140
2141 ;;; Since 115:
2142 ;; Mismatching array lengths
2143 (delete-file "non262/Intl/supportedValuesOf-timeZones-canonical.js")
2144 ;; FIXME: got "America/Santa_Isabel", expected "America/Tijuana":
2145 ;; America/Santa_Isabel -> America/Tijuana
2146 (delete-file "non262/Intl/DateTimeFormat/timeZone_backward_links.js")
2147 ;; TODO: tzdata 2024a expected – find a way to regenerate
2148 ;; these generated tests
2149 (delete-file "non262/Intl/DateTimeFormat/timeZone_version.js")
2150
2151 ;; FIXME: got "\uD840\uDDF2", expected "\u5047"
2152 (delete-file "non262/Intl/Collator/implicithan.js")
2153 ;; FIXME: got "\uD840\uDDF2", expected "\u3467"
2154 (delete-file "non262/Intl/Collator/big5han-gb2312han.js")
2155
2156 ;; Since 128:
2157 ;; FIXME: got (void 0), expected "GMT"
2158 (delete-file "non262/Intl/DateTimeFormat/formatRange-timeZoneName-matches-format.js")
2159 ;; FIXME: got 7, expected 9: parts count mismatch
2160 (delete-file "non262/Intl/DateTimeFormat/formatRange-timeZone-offset.js")
2161 (delete-file "non262/Intl/DateTimeFormat/formatRange-timeZoneName.js"))))))))
2162 (inputs
2163 (list icu4c-73 readline zlib))))
2164
2165(define-public firefox-decrypt
2166 (package
2167 (name "firefox-decrypt")
2168 (version "1.1.1")
2169 (source (origin
2170 (method git-fetch)
2171 (uri (git-reference
2172 (url "https://github.com/Unode/firefox_decrypt")
2173 (commit version)))
2174 (file-name (git-file-name name version))
2175 (sha256
2176 (base32
2177 "0dnyl5z7kcgmgdgbz7vg8ha21pk9jiympvq0qc97lgdcdd8wxy0w"))))
2178 (build-system trivial-build-system)
2179 (inputs
2180 (list nss python))
2181 (arguments
2182 `(#:modules ((guix build utils))
2183 #:builder
2184 (begin
2185 (use-modules (guix build utils))
2186 (setenv "PATH"
2187 (string-append
2188 (assoc-ref %build-inputs "python") "/bin"))
2189 (copy-file (string-append (assoc-ref %build-inputs "source")
2190 "/firefox_decrypt.py")
2191 "firefox_decrypt.py")
2192 (substitute* "firefox_decrypt.py"
2193 (("/usr/bin/env python3") (which "python3"))
2194 (("libnss3.so") (string-append (assoc-ref %build-inputs "nss")
2195 "/lib/nss/libnss3.so")))
2196 (install-file "firefox_decrypt.py" (string-append %output "/bin"))
2197 #t)))
2198 (home-page "https://github.com/Unode/firefox_decrypt/")
2199 (synopsis "Tool to extract passwords from Mozilla profiles")
2200 (description "Firefox Decrypt is a tool to extract passwords from
2201Mozilla (Firefox, Waterfox, Thunderbird, SeaMonkey) profiles.")
2202 (license license:gpl3+)))
2203
2204(define-public lz4json
2205 (package
2206 (name "lz4json")
2207 (version "2")
2208 (source
2209 (origin
2210 (method git-fetch)
2211 (uri
2212 (git-reference
2213 (url "https://github.com/andikleen/lz4json")
2214 (commit (string-append "v" version))))
2215 (file-name (git-file-name name version))
2216 (sha256
2217 (base32 "1xxn8yzr6j8j6prmbj6mxspdczigarfiv3vlm9k70yxmky65ijh3"))))
2218 (build-system gnu-build-system)
2219 (native-inputs (list pkg-config))
2220 (inputs (list lz4))
2221 (arguments
2222 `(#:tests? #f ; no check target
2223 #:phases
2224 (modify-phases %standard-phases
2225 (delete 'configure) ; no configure script
2226 (replace 'install ; no install target
2227 (lambda* (#:key outputs #:allow-other-keys)
2228 (let* ((out (assoc-ref outputs "out"))
2229 (bin (string-append out "/bin"))
2230 (man (string-append out "/share/man/man1")))
2231 (install-file "lz4jsoncat" bin)
2232 (install-file "lz4jsoncat.1" man)))))
2233 #:make-flags `(,(string-append "CC=" ,(cc-for-target)))))
2234 (home-page "https://github.com/andikleen/lz4json")
2235 (synopsis "C decompress tool for mozilla lz4json format")
2236 (description
2237 "@code{lz4json} is a little utility to unpack lz4json files as generated
2238by Firefox's bookmark backups and session restore. This is a different format
2239from what the normal lz4 utility expects. The data is dumped to stdout.")
2240 (license license:bsd-2)))