nixpkgs/pkgs/applications/office/libreoffice/default.nix
2026-06-21 16:18:37 +00:00

896 lines
21 KiB
Nix

{
stdenv,
fetchurl,
fetchgit,
fetchpatch2,
fetchFromGitLab,
lib,
pam,
python3,
python3Packages,
libxslt,
perl,
perlPackages,
box2d_2,
gettext,
zlib,
libjpeg,
liblangtag,
expat,
freetype,
libwpd,
libxml2,
db,
curl,
fontconfig,
libsndfile,
neon,
bison,
flex,
zip,
unzip,
fast-float,
md4c,
gtk3,
libmspack,
getopt,
file,
cairo,
which,
icu,
boost,
boost188,
jdk21,
ant,
cups,
libixion,
libxtst,
libxi,
libxinerama,
libxext,
libxdmcp,
libxaw,
libx11,
libpthread-stubs,
libxshmfence,
fontforge,
jre21_minimal,
openssl,
gperf,
cppunit,
poppler,
util-linux,
librsvg,
libGLU,
libGL,
bsh,
coinmp,
libwps,
libabw,
libargon2,
libmysqlclient,
autoconf,
automake,
openldap,
bash,
hunspell,
librdf_rasqal,
librdf_redland,
nss,
nspr,
libwpg,
dbus-glib,
clucene-core_2,
libcdr,
lcms2,
unixodbc,
mdds,
sane-backends,
mythes,
libexttextcat,
libvisio,
pkg-config,
bluez5,
libtool,
libatomic_ops,
graphite2,
harfbuzz,
libodfgen,
libzmf,
librevenge,
libe-book,
libmwaw,
glm,
gst_all_1,
gdb,
adwaita-icon-theme,
glib,
ncurses,
libepoxy,
gpgme,
gpgmepp,
libwebp,
abseil-cpp,
libfreehand,
libepubgen,
libetonyek,
libpng,
liborcus,
libxcrypt,
langs ? [
"ar"
"ca"
"cs"
"da"
"de"
"en-GB"
"en-US"
"eo"
"es"
"fi"
"fr"
"hu"
"it"
"ja"
"ko"
"nl"
"pl"
"pt"
"pt-BR"
"ro"
"ru"
"sk"
"sl"
"tr"
"uk"
"zh-CN"
"zh-TW"
],
withFonts ? false,
withHelp ? true,
withJava ? true,
kdeIntegration ? false,
variant ? "fresh",
debugLogging ? variant == "still",
qt6,
kdePackages,
symlinkJoin,
libpq,
makeFontsConf,
amiri,
caladea,
carlito,
culmus,
dejavu_fonts,
rubik,
liberation-sans-narrow,
liberation_ttf_v2,
libertine,
linux-libertine-g,
noto-fonts,
noto-fonts-lgc-plus,
noto-fonts-cjk-sans,
rhino,
lp_solve,
xmlsec,
libcmis,
frozen-containers,
}:
assert builtins.elem variant [
"fresh"
"still"
"collabora"
"collabora-coda"
];
let
inherit (lib)
flatten
flip
concatMapStrings
concatStringsSep
getDev
getLib
optionals
optionalString
;
fontsConf = makeFontsConf {
fontDirectories = [
amiri
caladea
carlito
culmus
dejavu_fonts
rubik
liberation-sans-narrow
liberation_ttf_v2
libertine
linux-libertine-g
noto-fonts-lgc-plus
noto-fonts
noto-fonts-cjk-sans
];
};
jre' = jre21_minimal.override {
modules = [
"java.base"
"java.desktop"
"java.logging"
"java.sql"
];
};
mdds_2_1 = mdds.overrideAttrs {
version = "2.1.1";
src = fetchFromGitLab {
owner = "mdds";
repo = "mdds";
rev = "2.1.1";
hash = "sha256-a412LpgDiYM8TMToaUrTlHtblYS1HehzrDOwvIAAxiA=";
};
};
# required for libreoffice-collabora version 25.04.9-4
libixion_0_19 = libixion.overrideAttrs {
version = "0.19.0";
src = fetchFromGitLab {
owner = "ixion";
repo = "ixion";
rev = "0.19.0";
hash = "sha256-BrexWRaxrLTWuoU62kqws3tlSqVOHecSV5MXc4ZezFs=";
};
buildInputs = [
boost188
mdds_2_1
python3
];
patches = [
# fix build with gcc 15, Add a missing <cstdint> include
(fetchpatch2 {
url = "https://gitlab.com/ixion/ixion/-/merge_requests/70.patch";
hash = "sha256-FzU/aejcMktrDQql5pzobiq6BJXryIXQXZTBWCkyqtU=";
})
];
};
# required for libreoffice-collabora version 25.04.9-4
liborcus_0_19 = liborcus.overrideAttrs {
version = "0.19.2";
src = fetchFromGitLab {
owner = "orcus";
repo = "orcus";
rev = "0.19.2";
hash = "sha256-+9C52H99c/kL5DEIoXV+WcLnTftRbicRLQN/FdIXBw8=";
};
buildInputs = [
boost188
libixion_0_19
mdds_2_1
python3
zlib
];
patches = [
# fix build with gcc 15, Add missing <cstdint> includes
(fetchpatch2 {
url = "https://gitlab.com/orcus/orcus/-/merge_requests/200.patch";
hash = "sha256-CZVw1+ri6UO56Bg/Y27W6G8JkGU6xDInd7fABr6i+7g=";
})
];
};
# required for libreoffice-still version 25.8.5.2
liborcus_0_20 = liborcus.overrideAttrs {
version = "0.20.1";
src = fetchFromGitLab {
owner = "orcus";
repo = "orcus";
rev = "0.20.1";
hash = "sha256-+YTK0EPgGHN4yKurJjuWWrAHzgtbc1dOvtppcvuRei4=";
};
buildInputs = [
boost188
libixion
mdds
python3
zlib
];
};
importVariant = f: import (./. + "/src-${variant}/${f}");
# Update these files with:
# nix-shell maintainers/scripts/update.nix --argstr package libreoffice-$VARIANT.unwrapped
version = importVariant "version.nix";
srcsAttributes = {
main = importVariant "main.nix";
help = importVariant "help.nix";
translations = importVariant "translations.nix";
deps = importVariant "deps.nix";
};
srcs = {
third_party = map (
x:
(fetchurl {
inherit (x) url sha256 name;
})
// {
inherit (x) md5name md5;
}
) srcsAttributes.deps;
translations = srcsAttributes.translations { inherit fetchurl fetchgit; };
help = srcsAttributes.help { inherit fetchurl fetchgit; };
};
kdeDependencies = [
qt6.qtbase.out # has a dev output but you cannot find the headers there
qt6.qtmultimedia.out
kdePackages.kconfig
kdePackages.kcoreaddons
kdePackages.ki18n
kdePackages.kio
kdePackages.kwindowsystem
];
mkKdeDeps =
pkgs: func:
symlinkJoin {
name = "libreoffice-kde-dependencies-${version}";
paths = flatten (
map (e: [
(func e)
]) pkgs
);
};
# See `postPatch` for details
kdeDepsIncludes = mkKdeDeps kdeDependencies getDev;
kdeDepsLibs = mkKdeDeps kdeDependencies getLib;
tarballPath = "external/tarballs";
in
stdenv.mkDerivation (finalAttrs: {
pname = "libreoffice";
inherit version;
src = srcsAttributes.main { inherit fetchurl fetchgit; };
postUnpack = ''
mkdir -v $sourceRoot/${tarballPath}
${flip concatMapStrings srcs.third_party (f: ''
ln -sfv ${f} $sourceRoot/${tarballPath}/${f.md5name}
ln -sfv ${f} $sourceRoot/${tarballPath}/${f.name}
'')}
''
+ (
if (variant != "collabora" && variant != "collabora-coda") then
''
ln -sv ${srcs.help} $sourceRoot/${tarballPath}/${srcs.help.name}
ln -svf ${srcs.translations} $sourceRoot/${tarballPath}/${srcs.translations.name}
tar -xf ${srcs.help}
tar -xf ${srcs.translations}
''
else
''
cp -r --no-preserve=mode ${srcs.help}/. $sourceRoot/helpcontent2/
cp -r --no-preserve=mode ${srcs.translations}/. $sourceRoot/translations/
''
);
patches = [
# Skip some broken tests:
# - tdf160386 does not fall back to a CJK font properly for some reason
# - the remaining tests have notes in the patches
# FIXME: get rid of this ASAP
./skip-broken-tests.patch
(./skip-broken-tests- + variant + ".patch")
# Don't detect Qt paths from qmake, so our patched-in onese are used
./dont-detect-qt-paths-from-qmake.patch
# Fix build with Poppler 26.02
(fetchpatch2 {
url = "https://gitlab.archlinux.org/archlinux/packaging/packages/libreoffice-still/-/raw/25.8.7-2/fix_build_with_poppler_26.02.0.patch";
hash = "sha256-IInhSoqTemDITB+AtkvVa9eGbodTbUGSpMMpC9N/mmg=";
})
# Fix build with Poppler 26.04
(fetchpatch2 {
url = "https://gitlab.archlinux.org/archlinux/packaging/packages/libreoffice-still/-/raw/25.8.7-2/fix_build_with_poppler_26.04.0.patch";
hash = "sha256-I9owj/NTCTi6ISszuasH410NLlhunPn/Ig22tenu8tw=";
})
# Fix build with Poppler 26.05
(fetchpatch2 {
url = "https://gitlab.archlinux.org/archlinux/packaging/packages/libreoffice-still/-/raw/25.8.7-2/fix_build_with_poppler_26.05.0.patch";
hash = "sha256-7wdiciTf/LrTk0MibBBYGliWRCvK1rtTGESgH7db1I4=";
})
# Fix build with Poppler 26.06
(fetchpatch2 {
url = "https://gitlab.archlinux.org/archlinux/packaging/packages/libreoffice-still/-/raw/25.8.7-3/fix_build_with_poppler_26.06.0.patch";
hash = "sha256-j66IsrzaqQ55MRVzhlw25guuoDtxx1D4XeJsBhgWP2c=";
})
]
++ lib.optionals (variant != "fresh") [
# Fix build with Poppler 26.01
(fetchpatch2 {
url = "https://gitlab.archlinux.org/archlinux/packaging/packages/libreoffice-still/-/raw/25.8.7-2/fix_build_with_poppler_26.01.0.patch";
hash = "sha256-5JTTvJFIV5MG0Gz7y46wAr3q9tWdSVoZ9TJQlMJVqBc=";
})
]
++ lib.optionals (variant != "collabora" && variant != "collabora-coda") [
# Revert part of https://github.com/LibreOffice/core/commit/6f60670877208612b5ea320b3677480ef6508abb that broke zlib linking
./readd-explicit-zlib-link.patch
]
++ lib.optionals (variant == "collabora" || variant == "collabora-coda") [
# Backport patch to fix build with Poppler 25.09
(fetchpatch2 {
url = "https://github.com/LibreOffice/core/commit/7848e02819c007026952a3fdc9da0961333dc079.patch";
includes = [ "sdext/*" ];
hash = "sha256-Nw6GFmkFy13w/ktCxw5s7SHL34auP1BQ9JvQnQ65aVU=";
})
# Fix build with Poppler 25.10
(fetchpatch2 {
url = "https://gitlab.archlinux.org/archlinux/packaging/packages/libreoffice-still/-/raw/f5241554e4a0f6fd95ac4e5cc398a30243407e6a/fix_build_with_poppler_25.10.patch";
hash = "sha256-lbPOkc1HeT5Qsp6XfVyVJtmvSL68qTrmbd3q9lvKSu8=";
})
./fix-unpack-collabora.patch
];
postPatch = ''
# configure checks for header 'gpgme++/gpgmepp_version.h',
# and if it is found (no matter where) uses a hardcoded path
# in what presumably is an effort to make it possible to write
# '#include <context.h>' instead of '#include <gpgmepp/context.h>'.
#
# Fix this path to point to where the headers can actually be found instead.
substituteInPlace configure.ac --replace-fail \
'GPGMEPP_CFLAGS=-I/usr/include/gpgme++' \
'GPGMEPP_CFLAGS=-I${lib.getDev gpgmepp}/include/gpgme++'
# Fix for Python 3.12
substituteInPlace configure.ac --replace-fail distutils.sysconfig sysconfig
'';
nativeBuildInputs = [
autoconf
automake
bison
flex
fontforge
gdb
gettext
gperf
icu
libmysqlclient
libtool
libxml2
libxslt
perl
perlPackages.ArchiveZip
perlPackages.IOCompress
pkg-config
python3
unzip
zip
]
++ optionals kdeIntegration [
qt6.qtbase
]
++ optionals withJava [
ant
jdk21
]
++ optionals (lib.versionAtLeast version "26.2.1.2") [
python3Packages.afdko
];
buildInputs =
finalAttrs.passthru.gst_packages
++ [
# Make libpng not handle APNG images, so LibreOffice's own handler kicks in
# This should be ordered first, so it gets picked up before any other
# propagated libpng
# See: https://www.mail-archive.com/libreoffice@lists.freedesktop.org/msg334080.html
(libpng.override { apngSupport = false; })
coinmp
abseil-cpp
bluez5
boost
box2d_2
cairo
clucene-core_2
cppunit
cups
curl
db
dbus-glib
expat
file
fontconfig
freetype
getopt
glib
glm
adwaita-icon-theme
gpgme
gpgmepp
graphite2
gtk3
(harfbuzz.override { withIcu = true; })
hunspell
icu
lcms2
libGL
libGLU
libtool
libx11
libxaw
libxdmcp
libxext
libxi
libxinerama
libxtst
libabw
libargon2
libatomic_ops
libcdr
libcmis
libfreehand
libe-book
libepoxy
libepubgen
libetonyek
libexttextcat
libjpeg
liblangtag
libmspack
libmwaw
libodfgen
libpthread-stubs
librdf_redland
librevenge
librsvg
libsndfile
libvisio
libwpd
libwpg
libwps
libxcrypt
libxml2
libxshmfence
libxslt
libzmf
libwebp
lp_solve
mdds
mythes
ncurses
neon
nspr
nss
openldap
openssl
pam
poppler
libpq
python3
sane-backends
unixodbc
util-linux
which
xmlsec
zlib
frozen-containers
]
++ optionals kdeIntegration [
qt6.qtbase
kdePackages.kcoreaddons
kdePackages.kio
]
++ optionals withJava [
jre'
]
++ optionals (variant == "collabora" || variant == "collabora-coda") [
fast-float
liborcus_0_19
mdds_2_1
md4c
]
++ optionals (variant == "still") [
liborcus_0_20
]
++ optionals (variant == "fresh") [
fast-float
liborcus
md4c
];
preConfigure = ''
configureFlagsArray=(
"--with-parallelism=$NIX_BUILD_CORES"
# here because we need to be very specific about spaces
"--with-lang=${concatStringsSep " " langs}"
);
patchShebangs .
NOCONFIGURE=1 ./autogen.sh
''
+ optionalString kdeIntegration ''
# configure.ac assumes that the first directory that contains headers and
# libraries during its checks contains *all* the relevant headers/libs which
# obviously doesn't work for us, so we have 2 options:
#
# 1. patch configure.ac in order to specify the direct paths to various Qt/KDE
# dependencies which is ugly and brittle, or
#
# 2. use symlinkJoin to pull in the relevant dependencies and just patch in
# that path which is *also* ugly, but far less likely to break
#
# The 2nd option is not very Nix'y, but I'll take robust over nice any day.
# Additionally, it's much easier to fix if LO breaks on the next upgrade (just
# add the missing dependencies to it).
export QT6INC=${kdeDepsIncludes}/include
export QT6LIB=${kdeDepsLibs}/lib
export KF6INC="${kdeDepsIncludes}/include ${kdeDepsIncludes}/include/KF6"
export KF6LIB=${kdeDepsLibs}/lib
'';
configureFlags = [
# Explicitly passing in --host even on non-cross, because
# LibreOffice will attempt to detect WSL and cross-compile
# itself to Windows automatically, and we don't want it
# doing that.
"--host=${stdenv.hostPlatform.config}"
"--without-buildconfig-recorded"
(lib.withFeature withHelp "help")
"--with-boost=${getDev boost}"
"--with-boost-libdir=${getLib boost}/lib"
"--with-vendor=NixOS"
"--disable-report-builder"
"--disable-online-update"
"--enable-python=system"
"--enable-dbus"
"--enable-release-build"
"--enable-epm"
(lib.withFeature withJava "java")
# Without these, configure does not finish
"--without-junit"
# Schema files for validation are not included in the source tarball
"--without-export-validation"
# We do tarball prefetching ourselves
"--disable-fetch-external"
"--enable-build-opensymbol"
# I imagine this helps. Copied from go-oo.
# Modified on every upgrade, though
"--disable-odk"
"--disable-firebird-sdbc"
(lib.withFeature withFonts "fonts")
"--without-doxygen"
"--with-system-afdko"
"--with-system-cairo"
"--with-system-coinmp"
"--with-system-fast-float"
"--with-system-headers"
"--with-system-libabw"
"--with-system-libcmis"
"--with-system-libfreehand"
"--with-system-libepubgen"
"--with-system-libetonyek"
"--with-system-liblangtag"
"--with-system-libs"
"--with-system-libwps"
"--with-system-lpsolve"
"--with-system-mdds"
"--with-system-openldap"
"--with-system-openssl"
"--with-system-orcus"
"--with-system-postgresql"
"--with-system-xmlsec"
"--with-system-frozen"
# TODO: package these as system libraries
"--without-system-altlinuxhyph"
"--without-system-libeot"
"--without-system-libmspub"
"--without-system-libnumbertext"
"--without-system-libpagemaker"
"--without-system-libstaroffice"
"--without-system-libqxp"
"--without-system-dragonbox"
"--without-system-libfixmath"
# requires an oddly specific, old version
"--without-system-hsqldb"
# searches hardcoded paths that are wrong
"--without-system-zxing"
# is packaged but headers can't be found because there is no pkg-config file
"--without-system-zxcvbn"
"--without-system-java-websocket"
]
++ optionals kdeIntegration [
"--enable-kf6"
"--enable-qt6"
]
++ optionals withJava [
"--with-system-rhino"
"--with-rhino-jar=${rhino}/share/java/js.jar"
"--with-system-beanshell"
"--with-ant-home=${ant.home}"
"--with-beanshell-jar=${bsh}"
];
env = {
# FIXME: this is a hack, because the right cflags are not being picked up
# from rasqal's .pc file. Needs more investigation.
NIX_CFLAGS_COMPILE =
"-I${librdf_rasqal}/include/rasqal"
+ (lib.optionalString debugLogging " -DSAL_LOG_WARN=1 -DSAL_LOG_INFO=1 ");
# Provide all the fonts used in tests.
FONTCONFIG_FILE = fontsConf;
};
makeFlags = [ "SHELL=${bash}/bin/bash" ];
enableParallelBuilding = true;
buildTargets = [ "build-nocheck" ];
doCheck = true;
preCheck = ''
export HOME=$(pwd)
''
+ lib.optionalString (variant == "collabora" || variant == "collabora-coda") ''
export XDG_RUNTIME_DIR=$(mktemp -d)
# tests try to access x11 and fail
export GST_GL_WINDOW=dummy
export GST_VIDEOSINK=fakesink
export GST_AUDIOSINK=fakesink
'';
checkTarget = concatStringsSep " " [
"unitcheck"
"slowcheck"
"--keep-going" # easier to debug test failures
];
postInstall = optionalString (variant != "collabora" && variant != "collabora-coda") ''
mkdir -p $out/{include,share/icons}
cp -r include/LibreOfficeKit $out/include/
cp -r sysui/desktop/icons/hicolor $out/share/icons
# Rename icons for consistency
for file in $out/share/icons/hicolor/*/apps/*; do
mv $file "$(dirname $file)/libreoffice-$(basename $file)"
done
ln -s $out/lib/libreoffice/share/xdg $out/share/applications
# Unversionize desktop files
. ./bin/get_config_variables PRODUCTVERSION
for file in $out/lib/libreoffice/share/xdg/*.desktop; do
substituteInPlace $file \
--replace-fail "LibreOffice $PRODUCTVERSION" "LibreOffice" \
--replace-warn "Icon=libreoffice$PRODUCTVERSION" "Icon=libreoffice" \
--replace-fail "Exec=libreoffice$PRODUCTVERSION" "Exec=libreoffice"
done
'';
# Wrapping is done in ./wrapper.nix
dontWrapQtApps = true;
__structuredAttrs = true;
strictDeps = true;
passthru = {
inherit srcs;
jdk = if withJava then jre' else null;
python = python3; # for unoconv
updateScript = [
./update.sh
# Pass it this file name as argument
(builtins.unsafeGetAttrPos "pname" finalAttrs.finalPackage).file
# And the variant
variant
];
inherit kdeIntegration;
# For the wrapper.nix
inherit gtk3;
# Although present in qtPackages, we need qtbase.qtPluginPrefix and
# qtbase.qtQmlPrefix
inherit (qt6) qtbase;
gst_packages = with gst_all_1; [
gst-libav
gst-plugins-bad
gst-plugins-base
gst-plugins-good
gst-plugins-ugly
gstreamer.out
];
qmlPackages = [
kdePackages.ki18n
kdePackages.knotifications
qt6.qtdeclarative
qt6.qtmultimedia
qt6.qtwayland
kdePackages.solid
kdePackages.sonnet
];
qtPackages = [
kdePackages.kauth
kdePackages.kcompletion
kdePackages.kconfigwidgets
kdePackages.kglobalaccel
kdePackages.ki18n
kdePackages.kio
kdePackages.kitemviews
kdePackages.ktextwidgets
kdePackages.kwidgetsaddons
kdePackages.kwindowsystem
kdePackages.kxmlgui
kdePackages.phonon
qt6.qtbase
qt6.qtdeclarative
qt6.qtmultimedia
qt6.qtsvg
qt6.qttools
qt6.qtwayland
kdePackages.sonnet
];
};
# libreoffice tries to reference the BUILDCONFIG (e.g. PKG_CONFIG_PATH)
# in the binary causing the closure size to blow up because of many unnecessary
# dependencies to dev outputs. This behavior was patched away in nixpkgs
# (see above), make sure these don't leak again by accident.
# FIXME: disabled for kdeIntegration builds because the weird symlinkJoin setup
# leaks all the -dev dependencies :(
disallowedRequisites = lib.optionals (!kdeIntegration) (
lib.concatMap (x: lib.optional (x ? dev) x.dev) finalAttrs.buildInputs
);
requiredSystemFeatures = [ "big-parallel" ];
meta = {
changelog = "https://wiki.documentfoundation.org/ReleaseNotes/${lib.versions.majorMinor version}";
description = "Comprehensive, professional-quality productivity suite, a variant of openoffice.org";
homepage = "https://libreoffice.org/";
# at least one jar in dependencies
sourceProvenance = with lib.sourceTypes; [ binaryBytecode ];
license = with lib.licenses; [
mpl20
lgpl3Plus
asl20
];
maintainers = with lib.maintainers; [ raskin ];
platforms = lib.platforms.linux;
mainProgram = "libreoffice";
};
})