1{
2 stdenv,
3 runCommand,
4 fetchurl,
5 fetchgit,
6 fetchpatch2,
7 lib,
8 pam,
9 python311,
10 libxslt,
11 perl,
12 perlPackages,
13 box2d_2,
14 gettext,
15 zlib,
16 libjpeg,
17 liblangtag,
18 expat,
19 freetype,
20 libwpd,
21 libxml2,
22 db,
23 curl,
24 fontconfig,
25 libsndfile,
26 neon,
27 bison,
28 flex,
29 zip,
30 unzip,
31 gtk3,
32 libmspack,
33 getopt,
34 file,
35 cairo,
36 which,
37 icu,
38 boost,
39 jdk21,
40 ant,
41 cups,
42 xorg,
43 fontforge,
44 jre21_minimal,
45 openssl,
46 gperf,
47 cppunit,
48 poppler,
49 util-linux,
50 librsvg,
51 libGLU,
52 libGL,
53 bsh,
54 coinmp,
55 libwps,
56 libabw,
57 libargon2,
58 libmysqlclient,
59 autoconf,
60 automake,
61 openldap,
62 bash,
63 hunspell,
64 librdf_rasqal,
65 librdf_redland,
66 nss,
67 nspr,
68 libwpg,
69 dbus-glib,
70 clucene_core_2,
71 libcdr,
72 lcms2,
73 unixODBC,
74 mdds,
75 sane-backends,
76 mythes,
77 libexttextcat,
78 libvisio,
79 pkg-config,
80 bluez5,
81 libtool,
82 libatomic_ops,
83 graphite2,
84 harfbuzz,
85 libodfgen,
86 libzmf,
87 librevenge,
88 libe-book,
89 libmwaw,
90 glm,
91 gst_all_1,
92 gdb,
93 adwaita-icon-theme,
94 glib,
95 ncurses,
96 libepoxy,
97 gpgme,
98 libwebp,
99 abseil-cpp,
100 libepubgen,
101 libetonyek,
102 liborcus,
103 libpng,
104 libxcrypt,
105 langs ? [
106 "ar"
107 "ca"
108 "cs"
109 "da"
110 "de"
111 "en-GB"
112 "en-US"
113 "eo"
114 "es"
115 "fi"
116 "fr"
117 "hu"
118 "it"
119 "ja"
120 "ko"
121 "nl"
122 "pl"
123 "pt"
124 "pt-BR"
125 "ro"
126 "ru"
127 "sk"
128 "sl"
129 "tr"
130 "uk"
131 "zh-CN"
132 "zh-TW"
133 ],
134 withFonts ? false,
135 withHelp ? true,
136 kdeIntegration ? false,
137 qtbase ? null,
138 qtx11extras ? null,
139 qtwayland ? null,
140 ki18n ? null,
141 kconfig ? null,
142 kcoreaddons ? null,
143 kio ? null,
144 kwindowsystem ? null,
145 variant ? "fresh",
146 debugLogging ? variant == "still",
147 symlinkJoin,
148 libpq,
149 makeFontsConf,
150 amiri,
151 caladea,
152 carlito,
153 culmus,
154 dejavu_fonts,
155 rubik,
156 liberation-sans-narrow,
157 liberation_ttf_v2,
158 libertine,
159 libertine-g,
160 noto-fonts,
161 noto-fonts-lgc-plus,
162 noto-fonts-cjk-sans,
163 rhino,
164 lp_solve,
165 xmlsec,
166 libcmis,
167 # The rest are used only in passthru, for the wrapper
168 kauth ? null,
169 kcompletion ? null,
170 kconfigwidgets ? null,
171 kglobalaccel ? null,
172 kitemviews ? null,
173 knotifications ? null,
174 ktextwidgets ? null,
175 kwidgetsaddons ? null,
176 kxmlgui ? null,
177 phonon ? null,
178 qtdeclarative ? null,
179 qtmultimedia ? null,
180 qtquickcontrols ? null,
181 qtsvg ? null,
182 qttools ? null,
183 solid ? null,
184 sonnet ? null,
185}:
186
187assert builtins.elem variant [
188 "fresh"
189 "still"
190 "collabora"
191];
192
193let
194 inherit (lib)
195 flatten
196 flip
197 concatMapStrings
198 concatStringsSep
199 getDev
200 getLib
201 optionals
202 optionalString
203 ;
204
205 notoSubset =
206 suffixes:
207 runCommand "noto-fonts-subset" { } ''
208 mkdir -p "$out/share/fonts/noto/"
209 ${concatMapStrings (x: ''
210 cp "${noto-fonts}/share/fonts/noto/NotoSans${x}["*.[ot]tf "$out/share/fonts/noto/"
211 '') suffixes}
212 '';
213
214 fontsConf = makeFontsConf {
215 fontDirectories = [
216 amiri
217 caladea
218 carlito
219 culmus
220 dejavu_fonts
221 rubik
222 liberation-sans-narrow
223 liberation_ttf_v2
224 libertine
225 libertine-g
226 # Font priority issues in some tests in Still
227 noto-fonts-lgc-plus
228 (if variant == "fresh" then noto-fonts else (notoSubset [ "Arabic" ]))
229 noto-fonts-cjk-sans
230 ];
231 };
232
233 jre' = jre21_minimal.override {
234 modules = [
235 "java.base"
236 "java.desktop"
237 "java.logging"
238 "java.sql"
239 ];
240 };
241
242 importVariant = f: import (./. + "/src-${variant}/${f}");
243 # Update these files with:
244 # nix-shell maintainers/scripts/update.nix --argstr package libreoffice-$VARIANT.unwrapped
245 version = importVariant "version.nix";
246 srcsAttributes = {
247 main = importVariant "main.nix";
248 help = importVariant "help.nix";
249 translations = importVariant "translations.nix";
250 deps = (importVariant "deps.nix") ++ [
251 # TODO: Why is this needed?
252 (rec {
253 name = "unowinreg.dll";
254 url = "https://dev-www.libreoffice.org/extern/${md5name}";
255 sha256 = "1infwvv1p6i21scywrldsxs22f62x85mns4iq8h6vr6vlx3fdzga";
256 md5 = "185d60944ea767075d27247c3162b3bc";
257 md5name = "${md5}-${name}";
258 })
259 ];
260 };
261 srcs = {
262 third_party = map (
263 x:
264 (fetchurl {
265 inherit (x) url sha256 name;
266 })
267 // {
268 inherit (x) md5name md5;
269 }
270 ) srcsAttributes.deps;
271 translations = srcsAttributes.translations { inherit fetchurl fetchgit; };
272 help = srcsAttributes.help { inherit fetchurl fetchgit; };
273 };
274
275 qtMajor = lib.versions.major qtbase.version;
276
277 # See `postPatch` for details
278 kdeDeps = symlinkJoin {
279 name = "libreoffice-kde-dependencies-${version}";
280 paths = flatten (
281 map
282 (e: [
283 (getDev e)
284 (getLib e)
285 ])
286 [
287 qtbase
288 qtmultimedia
289 qtx11extras
290 kconfig
291 kcoreaddons
292 ki18n
293 kio
294 kwindowsystem
295 ]
296 );
297 };
298 tarballPath = "external/tarballs";
299
300in
301stdenv.mkDerivation (finalAttrs: {
302 pname = "libreoffice";
303 inherit version;
304
305 src = srcsAttributes.main { inherit fetchurl fetchgit; };
306
307 postUnpack = ''
308 mkdir -v $sourceRoot/${tarballPath}
309
310 ${flip concatMapStrings srcs.third_party (f: ''
311 ln -sfv ${f} $sourceRoot/${tarballPath}/${f.md5name}
312 ln -sfv ${f} $sourceRoot/${tarballPath}/${f.name}
313 '')}
314
315 ''
316 + (
317 if (variant != "collabora") then
318 ''
319 ln -sv ${srcs.help} $sourceRoot/${tarballPath}/${srcs.help.name}
320 ln -svf ${srcs.translations} $sourceRoot/${tarballPath}/${srcs.translations.name}
321
322 tar -xf ${srcs.help}
323 tar -xf ${srcs.translations}
324 ''
325 else
326 ''
327 cp -r --no-preserve=mode ${srcs.help}/. $sourceRoot/helpcontent2/
328 cp -r --no-preserve=mode ${srcs.translations}/. $sourceRoot/translations/
329 ''
330 );
331
332 patches = [
333 # Skip some broken tests:
334 # - tdf160386 does not fall back to a CJK font properly for some reason
335 # - the remaining tests have notes in the patches
336 # FIXME: get rid of this ASAP
337 ./skip-broken-tests.patch
338 (./skip-broken-tests- + variant + ".patch")
339
340 # Don't detect Qt paths from qmake, so our patched-in onese are used
341 ./dont-detect-qt-paths-from-qmake.patch
342
343 # Revert part of https://github.com/LibreOffice/core/commit/6f60670877208612b5ea320b3677480ef6508abb that broke zlib linking
344 ./readd-explicit-zlib-link.patch
345
346 # Backport patch to fix build with Poppler 25.05
347 # FIXME: conditionalize/remove as upstream updates
348 (fetchpatch2 {
349 url = "https://github.com/LibreOffice/core/commit/0ee2636304ac049f21415c67e92040f7d6c14d35.patch";
350 includes = [ "sdext/*" ];
351 hash = "sha256-8yipl5ln1yCNfVM8SuWowsw1Iy/SXIwbdT1ZfNw4cJA=";
352 })
353 ]
354 ++ lib.optionals (lib.versionOlder version "24.8") [
355 (fetchpatch2 {
356 name = "icu74-compat.patch";
357 url = "https://gitlab.archlinux.org/archlinux/packaging/packages/libreoffice-fresh/-/raw/main/libreoffice-7.5.8.2-icu-74-compatibility.patch?ref_type=heads.patch";
358 hash = "sha256-OGBPIVQj8JTYlkKywt4QpH7ULAzKmet5jTLztGpIS0Y=";
359 })
360 ]
361 ++ lib.optionals (variant == "collabora") [
362 ./fix-unpack-collabora.patch
363 ];
364
365 postPatch = ''
366 # configure checks for header 'gpgme++/gpgmepp_version.h',
367 # and if it is found (no matter where) uses a hardcoded path
368 # in what presumably is an effort to make it possible to write
369 # '#include <context.h>' instead of '#include <gpgmepp/context.h>'.
370 #
371 # Fix this path to point to where the headers can actually be found instead.
372 substituteInPlace configure.ac --replace-fail \
373 'GPGMEPP_CFLAGS=-I/usr/include/gpgme++' \
374 'GPGMEPP_CFLAGS=-I${gpgme.dev}/include/gpgme++'
375
376 # Fix for Python 3.12
377 substituteInPlace configure.ac --replace-fail distutils.sysconfig sysconfig
378 '';
379
380 nativeBuildInputs = [
381 ant
382 autoconf
383 automake
384 bison
385 flex
386 fontforge
387 gdb
388 gettext
389 gperf
390 icu
391 jdk21
392 libmysqlclient
393 libtool
394 libxml2
395 libxslt
396 perl
397 perlPackages.ArchiveZip
398 perlPackages.IOCompress
399 pkg-config
400 python311
401 unzip
402 zip
403 ]
404 ++ optionals kdeIntegration [
405 qtbase
406 ];
407
408 buildInputs =
409 finalAttrs.passthru.gst_packages
410 ++ [
411 # Make libpng not handle APNG images, so LibreOffice's own handler kicks in
412 # This should be ordered first, so it gets picked up before any other
413 # propagated libpng
414 # See: https://www.mail-archive.com/libreoffice@lists.freedesktop.org/msg334080.html
415 (libpng.override { apngSupport = false; })
416 coinmp
417 abseil-cpp
418 bluez5
419 boost
420 box2d_2
421 cairo
422 clucene_core_2
423 cppunit
424 cups
425 curl
426 db
427 dbus-glib
428 expat
429 file
430 fontconfig
431 freetype
432 getopt
433 glib
434 glm
435 adwaita-icon-theme
436 gpgme
437 graphite2
438 gtk3
439 (harfbuzz.override { withIcu = true; })
440 hunspell
441 icu
442 jre'
443 lcms2
444 libGL
445 libGLU
446 libtool
447 xorg.libX11
448 xorg.libXaw
449 xorg.libXdmcp
450 xorg.libXext
451 xorg.libXi
452 xorg.libXinerama
453 xorg.libXtst
454 libabw
455 libargon2
456 libatomic_ops
457 libcdr
458 libcmis
459 libe-book
460 libepoxy
461 libepubgen
462 libetonyek
463 libexttextcat
464 libjpeg
465 liblangtag
466 libmspack
467 libmwaw
468 libodfgen
469 liborcus
470 xorg.libpthreadstubs
471 librdf_redland
472 librevenge
473 librsvg
474 libsndfile
475 libvisio
476 libwpd
477 libwpg
478 libwps
479 libxcrypt
480 libxml2
481 xorg.libxshmfence
482 libxslt
483 libzmf
484 libwebp
485 lp_solve
486 mdds
487 mythes
488 ncurses
489 neon
490 nspr
491 nss
492 openldap
493 openssl
494 pam
495 poppler
496 libpq
497 python311
498 sane-backends
499 unixODBC
500 util-linux
501 which
502 xmlsec
503 zlib
504 ]
505 ++ optionals kdeIntegration [
506 qtbase
507 qtx11extras
508 kcoreaddons
509 kio
510 ];
511
512 preConfigure = ''
513 configureFlagsArray=(
514 "--with-parallelism=$NIX_BUILD_CORES"
515 # here because we need to be very specific about spaces
516 "--with-lang=${concatStringsSep " " langs}"
517 );
518
519 patchShebangs .
520
521 NOCONFIGURE=1 ./autogen.sh
522 ''
523 + optionalString kdeIntegration ''
524 # configure.ac assumes that the first directory that contains headers and
525 # libraries during its checks contains *all* the relevant headers/libs which
526 # obviously doesn't work for us, so we have 2 options:
527 #
528 # 1. patch configure.ac in order to specify the direct paths to various Qt/KDE
529 # dependencies which is ugly and brittle, or
530 #
531 # 2. use symlinkJoin to pull in the relevant dependencies and just patch in
532 # that path which is *also* ugly, but far less likely to break
533 #
534 # The 2nd option is not very Nix'y, but I'll take robust over nice any day.
535 # Additionally, it's much easier to fix if LO breaks on the next upgrade (just
536 # add the missing dependencies to it).
537 export QT${qtMajor}INC=${kdeDeps}/include
538 export QT${qtMajor}LIB=${kdeDeps}/lib
539 export KF${qtMajor}INC="${kdeDeps}/include ${kdeDeps}/include/KF${qtMajor}"
540 export KF${qtMajor}LIB=${kdeDeps}/lib
541 '';
542
543 configureFlags = [
544 # Explicitly passing in --host even on non-cross, because
545 # LibreOffice will attempt to detect WSL and cross-compile
546 # itself to Windows automatically, and we don't want it
547 # doing that.
548 "--host=${stdenv.hostPlatform.config}"
549 "--without-buildconfig-recorded"
550
551 (lib.withFeature withHelp "help")
552 "--with-boost=${getDev boost}"
553 "--with-boost-libdir=${getLib boost}/lib"
554 "--with-beanshell-jar=${bsh}"
555 "--with-vendor=NixOS"
556 "--disable-report-builder"
557 "--disable-online-update"
558 "--enable-python=system"
559 "--enable-dbus"
560 "--enable-release-build"
561 "--enable-epm"
562 "--with-ant-home=${ant.home}"
563
564 # Without these, configure does not finish
565 "--without-junit"
566
567 # Schema files for validation are not included in the source tarball
568 "--without-export-validation"
569
570 # We do tarball prefetching ourselves
571 "--disable-fetch-external"
572 "--enable-build-opensymbol"
573
574 # I imagine this helps. Copied from go-oo.
575 # Modified on every upgrade, though
576 "--disable-odk"
577 "--disable-firebird-sdbc"
578 (lib.withFeature withFonts "fonts")
579 "--without-doxygen"
580
581 "--with-system-beanshell"
582 "--with-system-cairo"
583 "--with-system-coinmp"
584 "--with-system-headers"
585 "--with-system-libabw"
586 "--with-system-libcmis"
587 "--with-system-libepubgen"
588 "--with-system-libetonyek"
589 "--with-system-liblangtag"
590 "--with-system-libs"
591 "--with-system-libwps"
592 "--with-system-lpsolve"
593 "--with-system-mdds"
594 "--with-system-openldap"
595 "--with-system-openssl"
596 "--with-system-orcus"
597 "--with-system-postgresql"
598 "--with-system-xmlsec"
599
600 # TODO: package these as system libraries
601 "--without-system-altlinuxhyph"
602 "--without-system-frozen"
603 "--without-system-libfreehand"
604 "--without-system-libmspub"
605 "--without-system-libnumbertext"
606 "--without-system-libpagemaker"
607 "--without-system-libstaroffice"
608 "--without-system-libqxp"
609 "--without-system-dragonbox"
610 "--without-system-libfixmath"
611
612 # requires an oddly specific, old version
613 "--without-system-hsqldb"
614
615 # searches hardcoded paths that are wrong
616 "--without-system-zxing"
617
618 # is packaged but headers can't be found because there is no pkg-config file
619 "--without-system-zxcvbn"
620 ]
621 ++ optionals kdeIntegration [
622 "--enable-kf${qtMajor}"
623 "--enable-qt${qtMajor}"
624 ]
625 ++ optionals (kdeIntegration && qtMajor == "5") [
626 "--enable-gtk3-kde5"
627 ]
628 ++ (
629 if variant == "fresh" || variant == "collabora" then
630 [
631 "--with-system-rhino"
632 "--with-rhino-jar=${rhino}/share/java/js.jar"
633
634 "--without-system-java-websocket"
635 ]
636 else
637 [
638 # our Rhino is too new for older versions
639 "--without-system-rhino"
640 ]
641 );
642
643 env = {
644 # FIXME: this is a hack, because the right cflags are not being picked up
645 # from rasqal's .pc file. Needs more investigation.
646 NIX_CFLAGS_COMPILE =
647 "-I${librdf_rasqal}/include/rasqal"
648 + (lib.optionalString debugLogging " -DSAL_LOG_WARN=1 -DSAL_LOG_INFO=1 ");
649
650 # Provide all the fonts used in tests.
651 FONTCONFIG_FILE = fontsConf;
652 };
653
654 makeFlags = [ "SHELL=${bash}/bin/bash" ];
655
656 enableParallelBuilding = true;
657
658 buildTargets = [ "build-nocheck" ];
659
660 # Disable tests for the Qt5 build, as they seem even more flaky
661 # than usual, and we will drop the Qt5 build after 24.11 anyway.
662 doCheck = !(kdeIntegration && qtMajor == "5");
663
664 preCheck = ''
665 export HOME=$(pwd)
666 '';
667
668 checkTarget = concatStringsSep " " [
669 "unitcheck"
670 "slowcheck"
671 "--keep-going" # easier to debug test failures
672 ];
673
674 postInstall = optionalString (variant != "collabora") ''
675 mkdir -p $out/{include,share/icons}
676
677 cp -r include/LibreOfficeKit $out/include/
678 cp -r sysui/desktop/icons/hicolor $out/share/icons
679
680 # Rename icons for consistency
681 for file in $out/share/icons/hicolor/*/apps/*; do
682 mv $file "$(dirname $file)/libreoffice-$(basename $file)"
683 done
684
685 ln -s $out/lib/libreoffice/share/xdg $out/share/applications
686
687 # Unversionize desktop files
688 . ./bin/get_config_variables PRODUCTVERSION
689 for file in $out/lib/libreoffice/share/xdg/*.desktop; do
690 substituteInPlace $file \
691 --replace-fail "LibreOffice $PRODUCTVERSION" "LibreOffice" \
692 --replace-warn "Icon=libreoffice$PRODUCTVERSION" "Icon=libreoffice" \
693 --replace-fail "Exec=libreoffice$PRODUCTVERSION" "Exec=libreoffice"
694 done
695 '';
696
697 # Wrapping is done in ./wrapper.nix
698 dontWrapQtApps = true;
699
700 strictDeps = true;
701
702 passthru = {
703 inherit srcs;
704 jdk = jre';
705 python = python311; # for unoconv
706 updateScript = [
707 ./update.sh
708 # Pass it this file name as argument
709 (builtins.unsafeGetAttrPos "pname" finalAttrs.finalPackage).file
710 # And the variant
711 variant
712 ];
713 inherit kdeIntegration;
714 # For the wrapper.nix
715 inherit gtk3;
716 # Although present in qtPackages, we need qtbase.qtPluginPrefix and
717 # qtbase.qtQmlPrefix
718 inherit qtbase;
719 gst_packages = with gst_all_1; [
720 gst-libav
721 gst-plugins-bad
722 gst-plugins-base
723 gst-plugins-good
724 gst-plugins-ugly
725 gstreamer
726 ];
727 qmlPackages = [
728 ki18n
729 knotifications
730 qtdeclarative
731 qtmultimedia
732 qtquickcontrols
733 qtwayland
734 solid
735 sonnet
736 ];
737 qtPackages = [
738 kauth
739 kcompletion
740 kconfigwidgets
741 kglobalaccel
742 ki18n
743 kio
744 kitemviews
745 ktextwidgets
746 kwidgetsaddons
747 kwindowsystem
748 kxmlgui
749 phonon
750 qtbase
751 qtdeclarative
752 qtmultimedia
753 qtsvg
754 qttools
755 qtwayland
756 sonnet
757 ];
758 };
759
760 # libreoffice tries to reference the BUILDCONFIG (e.g. PKG_CONFIG_PATH)
761 # in the binary causing the closure size to blow up because of many unnecessary
762 # dependencies to dev outputs. This behavior was patched away in nixpkgs
763 # (see above), make sure these don't leak again by accident.
764 # FIXME: disabled for kdeIntegration builds because the weird symlinkJoin setup
765 # leaks all the -dev dependencies :(
766 disallowedRequisites = lib.optionals (!kdeIntegration) (
767 lib.concatMap (x: lib.optional (x ? dev) x.dev) finalAttrs.buildInputs
768 );
769
770 requiredSystemFeatures = [ "big-parallel" ];
771
772 meta = {
773 changelog = "https://wiki.documentfoundation.org/ReleaseNotes/${lib.versions.majorMinor version}";
774 description = "Comprehensive, professional-quality productivity suite, a variant of openoffice.org";
775 homepage = "https://libreoffice.org/";
776 # at least one jar in dependencies
777 sourceProvenance = with lib.sourceTypes; [ binaryBytecode ];
778 license = with lib.licenses; [
779 mpl20
780 lgpl3Plus
781 asl20
782 ];
783 maintainers = with lib.maintainers; [ raskin ];
784 platforms = lib.platforms.linux;
785 mainProgram = "libreoffice";
786 };
787})