Building LibreOffice Online for Debian
How to build LibreofficeOnline against stock LibreOffice on Debian Stretch
Debian, Development
Table of Contents
DISCLAIMER: I never did proceed with this project beyond building the packages. I can offer no helpful support regarding getting it running.
LibreOffice Online is a very cool project by the fine people at Collabora to bring the LibreOffice core functionality into a web browser. In effect, it’s a Free Software version of the Google Docs suite of productivity tools, allowing one or many people to edit and save documents in a browser.
The software builds on the LibreOffice core code, and currently is only distributed as a Docker image, obtainable from the link above. However, my BLSE2 platform does not support Docker now, or at any time in the foreseeable future [aside: maybe I’ll write my reasoning out, one day], and is based entirely around Debian and the idea of “use the package manager as much as possible”. So I set out to build everything myself.
This however was no small task - there’s precious little usable information in any one place on how to do this, especially not from the official Collabora site that just wants you to use the Docker image [re-aside: yea, that’s one reason I hate Docker…]. Luckily, a GitHub user by the name of m-jowlett
has written about his processes in a log over at his GitHub page [m-jowett/log.md
should this link eventually rot]. His guide is however extremely rough, as well as using Ubuntu and building for integration with another project featuring OwnCloud. It however gave me most of what I needed to get going with this, including help integrating the final package with my OwnCloud instance(s).
As mentioned briefly above, my philosophy in BLSE2 is “use a package” - this is a core feature of Debian, and one of the most solid examples of quality forethought in design in the Free Software world. By separating applications from their libraries, you keep security updates easy and with minimal administrative work. As such, I always choose to build a package if possible, and luckily with LibreOffice Online I can. And it’s right there in the repo! A huge win in my mind, especially considering my initial fear of a program distributed as a Docker Image [re-re-aside: poor dependency life-cycle management and monolithic software bundles - another reason I hate Docker; but I digress]. As this is a brand-new project and I’m a keen dist-upgrade
er, I’ve gone with the brand-new Stretch (9.0) release in the amd64
arch - you should probably be running the same, but 32-bit will work too.
$ cat /etc/debian_version
9.0
$ uname -a
Linux libreoffice-online 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26) x86_64 GNU/Linux
So without further ado, here’s how to build LibreOffice Online on Debian Stretch!
Installing the [Easy] Dependencies
The m-jowlett
guide lists a couple of dependencies: libpng12-dev
, libcap-dev
, libtool
, m4
, and automake
, and I’ll add in fakeroot
, debhelper
, dh-systemd
, and the build-essential
metapackage to build the Debian packages, as well as unixodbc-dev
which is required by the POCO build process below. The only one to cause problems in Stretch is libpng12-dev
: we need the libpng-dev
package instead, which installs libpng16-dev
. The version bump doesn’t seem to affect anything negatively, however. And of course, we need the full libreoffice
suite and it’s build-deps installed as well, python-polib
, nodejs-legacy
and node-jake
to grab some modules during the build, as well as libghc-zlib-bindings-dev
and libghc-zlib-dev
which pulls in ghc
.
$ sudo apt install libpng-dev libcap-dev libtool m4 automake fakeroot debhelper dh-systemd build-essential unixodbc-dev libreoffice python-polib nodejs-legacy node-jake libghc-zlib-bindings-dev libghc-zlib-dev
$ sudo apt build-dep libreoffice
Building POCO
The one dependency that is hard is libpoco-dev
. LibreOffice Online makes extensive use of JSON processing using libpoco
. However, there’s a problem: the author of JSON decided it was a bright idea to troll(?) the Free Software community, and added a problematic line to his otherwise-MIT licensed code. “The Software shall be used for Good, not Evil.” As a result, JSON doesn’t fit the Debian Free Software Guidelines and isn’t present in any Debian packages, and while Debian Stretch contains libpoco
of a version we require, the extremely-critical-to-LOOL JSON parsing library is disabled in the code. So, we have to build the libpoco
packages ourselves with JSON support, and then install them as dependencies.
First, we start with a bare Stretch machine with the above dependencies installed and several GB of free space, and then create a directory to contain our libpoco
build. We then download both the Debian source package and the Git repository fetching the same version branch.
$ mkdir ~/libpoco
$ cd ~/libpoco/
$ apt-get source libpoco-dev
$ git clone --recursive --depth 1 --branch poco-1.7.6-release https://github.com/pocoproject/poco.git
$ ls
poco poco-1.7.6+dfsg1 poco_1.7.6+dfsg1-5.debian.tar.xz poco_1.7.6+dfsg1-5.dsc poco_1.7.6+dfsg1.orig.tar.bz2
Note the +dfsg
tag to the source packages - this is indicative that the Debian maintainer modified the package to comply with the DFSG. Luckily though, all they did was set some package rules to avoid building the JSON component, and then removed the relevant source. By cloning the official repo, we can then combine the debian/
folder from the source package, with modifications, and the upstream source in order to build the JSON libraries. Just “don’t use it for evil”!
First we create our “source” tar
archive for the package build process (the name is explained below), then copy over, clean, and commit the stock debian/
folder - I recommend doing this for all your custom packaging as it makes retracing your changes far easier!
$ tar -cvJf poco_1.7.6-lool.orig.tar.xz poco/
$ cp -a poco-1.7.6+dfsg1/debian poco/
$ cd poco/
$ git checkout -b debian
$ dh_clean
$ git add debian/
$ git commit -m "Initial debian folder from Stretch source package"
Now we can begin modifying the Debian package rules. This is fairly straightforward even without Debian packaging experience. I’ll indicate the file edits with vim <filename>
; you can replace the vim
with the editor of you choice. The output that follows is a basic git
-style diff of the changes, as generated as the changes are committed to the custom branch.
The first target is the changelog
file, to tell it we have a new version. Note that the version string (lool-1
) is chosen specifically because it is “higher” than the official package’s +dfsg1
string. You can validate this yourself using dpkg --compare-versions
. This ensures that our custom packages will supersede the official ones, should you commit them to a custom repo and upgrade, though in this guide we install them locally with dpkg
. Note that the formatting of this file must match exactly, including every space and the full date, but feel free to edit the note and name/email as you desire - this is irrelevant unless you intend to distribute the packages.
$ vim debian/changelog
@@ -1,3 +1,9 @@
+poco (1.7.6-lool-1) stable; urgency=medium
+
+ * A custom build of 1.7.6 including non-DFSG JSON libraries for LibreOffice Online
+
+ -- Your Name <you@example.com> Tue, 06 Jul 2017 23:47:21 -0400
+
poco (1.7.6+dfsg1-5) unstable; urgency=medium
* Add missing dependencies (Closes: #861682)
The next file to edit is the control
file. In here, we add an entry for the libpocojson46
package that will also be built with libpoco-dev
. This edit should not require any changes from what is presented here.
$ vim debian/control
@@ -228,3 +228,19 @@ Description: C++ Portable Components (POCO) Zip library
consistent and easy to maintain.
.
This package provides the POCO Zip library.
+
+Package: libpocojson46
+Architecture: any
+Depends: libpocofoundation46 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
+Description: C++ Portable Components (POCO) JSON library
+ The POCO C++ Libraries are a collection of open source C++ class libraries
+ that simplify and accelerate the development of network-centric, portable
+ applications in C++. The libraries integrate perfectly with the C++ Standard
+ Library and fill many of the functional gaps left open by it.
+ .
+ POCO is built strictly using standard ANSI/ISO C++, including the standard
+ library. The contributors attempt to find a good balance between using advanced
+ C++ features and keeping the classes comprehensible and the code clean,
+ consistent and easy to maintain.
+ .
+ This package provides the POCO JSON library.
Next we edit the rules
file to remove the exclusion of the JSON component.
$ vim debian/rules
@@ -4,7 +4,7 @@ DPKG_EXPORT_BUILDFLAGS = 1
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
include /usr/share/dpkg/buildflags.mk
-CONFFLAGS = --prefix=/usr --no-samples --no-tests --unbundled --everything --omit=JSON --cflags="-DPOCO_UTIL_NO_JSONCONFIGURATION" --odbc-lib=/usr/lib/$(DEB_HOST_MULTIARCH)/
+CONFFLAGS = --prefix=/usr --no-samples --no-tests --unbundled --everything --odbc-lib=/usr/lib/$(DEB_HOST_MULTIARCH)/
# Disable parallel build on armel and mipsel
ifneq (,$(filter $(DEB_BUILD_ARCH),armel mipsel))
Now we remove the patches that disabled JSON support in the package. First we remove the patch, then we remove the series
entry for it.
$ rm debian/patches/0006-Disable-JSON-targets-in-Makefiles.patch
$ vim debian/patches/series
@@ -6,7 +6,6 @@ no-link-dl-rt.patch #could be removed now
# patches for build/rules/*
no-debug-build.patch
no-strip-release-build.patch
-0006-Disable-JSON-targets-in-Makefiles.patch
# upstream patches
0007-Add-patch-for-OpenSSL-1.1.0.patch
Finally we remove the old lintian overrides (no longer needed) and create the install
file for our new libpocojson46
package.
$ rm debian/source.lintian-overrides
$ vim debian/libpocojson46.install
@@ -0,0 +1 @@
+usr/lib/libPocoJSON.so.*
We can now build the package; I use -j4
on my quad-vCPU build machine but you should adjust this based on your core count for best performance. Note also that we’re using sudo
here; for whatever reason, trying to compile libpoco
without root causes a spew of error messages like object 'libfakeroot-sysv.so' from LD_PRELOAD cannot be preloaded
, on both my testing machines.
$ sudo dpkg-buildpackage -us -uc -j4
[lots of output]
dpkg-buildpackage: info: full upload (original source is included)
That last line indicates that the build succeeded; above it, we see a long list of generated packages in the parent directory. Move up a directory, remove the unneeded dbgsym
packages, and install all the rest. Note the sudo
commands again (due to the permissions of dpkg-buildpackage
).
$ cd ..
$ sudo rm *-dbgsym_*.deb
$ sudo dpkg -i *.deb
We now have a working set of POCO libraries and can now begin building LibreOffice Online itself!
Building LibreOffice Online
Once the dependencies are in place building the LibreOffice Online package itself is actually fairly straightforward - the repo contains a working debian
folder, though it too requires some tweaking to build properly.
Begin by making a new directory, and cloning the git repo; I’m using version 2.1.2 as it’s the latest stable one at the time of writing. Note that because the LibreOffice Online developers use tags, we have to actually cd
into and git checkout
the right version before we proceed. Then, as we did for POCO, make a tar
archive for the package build to use containing the source before we start editing anything.
$ mkdir ~/loolwsd
$ cd ~/loolwsd/
$ git clone https://github.com/LibreOffice/online.git
$ cd online/
$ git checkout -b debian tags/2.1.2
$ cd ..
$ tar -cvJf loolwsd_2.1.2.orig.tar.xz online/
$ cd online
We now need to do a some editing of the Debian control files, similar to POCO. First we add a changelog
entry (as is customary).
$ vim debian/changelog
@@ -1,3 +1,9 @@
+loolwsd (2.1.2-7) stable; urgency=medium
+
+ * Custom build of 2.1.2 for Debian Stretch
+
+ -- Your Name <you@example.com> Tue, 06 Jul 2017 23:47:21 -0400
+
loolwsd (2.1.2-6) unstable; urgency=medium
* see the git log: http://col.la/cool21
Next we edit the control
file. By default, LibreOffice online depends on the collaboraofficebasis5.3
suite, however we can override that and allow it to run against the stock Stretch libreoffice
package. While the diff is long, simply search for the first instance of collabora
on that line and delete everything after it, as well as the entry for libssl1.0.0
which is obsolete in Stretch and should be present by default anyways.
$ vim debian/control
@@ -8,7 +8,7 @@ Standards-Version: 3.9.7
Package: loolwsd
Section: web
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, adduser, fontconfig, libsm6, libssl1.0.0, libodbc1, libxinerama1, libcairo2, libgl1-mesa-glx, libcups2, libdbus-glib-1-2, cpio, collaboraofficebasis5.3-calc (>= 5.3.10.15), collaboraofficebasis5.3-core (>= 5.3.10.15), collaboraofficebasis5.3-graphicfilter (>= 5.3.10.15), collaboraofficebasis5.3-images (>= 5.3.10.15), collaboraofficebasis5.3-impress (>= 5.3.10.15), collaboraofficebasis5.3-ooofonts (>= 5.3.10.15), collaboraofficebasis5.3-writer (>= 5.3.10.15), collaboraoffice5.3 (>= 5.3.10.15), collaboraoffice5.3-ure (>= 5.3.10.15), collaboraofficebasis5.3-en-us (>= 5.3.10.15), collaboraofficebasis5.3-en-us-calc (>= 5.3.10.15), collaboraofficebasis5.3-en-us-res (>= 5.3.10.15), collaboraofficebasis5.3-noto-fonts (>= 5.3.10.15), collaboraofficebasis5.3-draw (>= 5.3.10.15), collaboraofficebasis5.3-extension-pdf-import (>= 5.3.10.15)
+Depends: ${shlibs:Depends}, ${misc:Depends}, adduser, fontconfig, libsm6, libodbc1, libxinerama1, libcairo2, libgl1-mesa-glx, libcups2, libdbus-glib-1-2, cpio, libreoffice
Description: LibreOffice Online WebSocket Daemon
LOOLWSD is a daemon that talks to web browser clients and provides LibreOffice
services.
Next we edit the rules
to add a few missing things. First, we add some additional configuration flags for disabling SSL (instead use a forward proxy; this also prevents build errors) and specifying the library directory; this is needed for the build process to find the libreoffice
libraries. We also add a call to autogen.sh
in the configuration step (missing inexplicably in this version), as well as overrides to the auto-build (to allow -jX
flags to work).
@@ -5,7 +5,7 @@ DPKG_EXPORT_BUILDFLAGS = 1
include /usr/share/dpkg/default.mk
-CONFFLAGS = --enable-silent-rules --prefix=/usr --localstatedir=/var --sysconfdir=/etc --with-lokit-path=`pwd`/bundled/include $(CONFIG_OPTIONS)
+CONFFLAGS = --enable-silent-rules --disable-ssl --prefix=/usr --localstatedir=/var --sysconfdir=/etc --with-lokit-path=`pwd`/bundled/include --libdir=/usr/lib/x86_64-linux-gnu $(CONFIG_OPTIONS)
# Avoid setcap when doing "make", when building for packaging
# the setcap is done at installation time
@@ -16,10 +16,14 @@ export BUILDING_FROM_RPMBUILD=yes
dh $@ --with=systemd
override_dh_auto_configure:
+ ./autogen.sh
./configure $(CONFFLAGS)
override_dh_auto_test:
# do not test
+override_dh_auto_build:
+ dh_auto_build --parallel $(MAKEARGS)
+
override_dh_installinit:
# no init.d scripts here, assume systemd
Now we have to write some patches. quilt
is a phenomenal tool for this, and I recommend reading up on it, but for simplicity I’ll provide the patch files as-is. First create a debian/patches
folder and create a series
file in it.
$ mkdir debian/patches
$ vim debian/patches/series
@@ -0,0 +1,2 @@
+enable-ssl-always
+fix-libpath
Next we create the two patch files. The first is to enable SSL support always - this seems to contradict the above change to disable SSL, but otherwise the build process fails. The second fixes up the location of the libreoffice
libraries so the amd64
-only build can find where they exist in Stretch amd64
.
Note: to avoid showing a diff of a diff, the following two entries are the verbatim contents of the file
$ vim debian/patches/enable-ssl-always
Description: Enable SSL always
Ensure that SSL is always enabled during build
.
loolwsd (2.1.2-7) stable; urgency=medium
.
* Custom build of 2.1.2 for Debian Stretch
Author: Your Name <you@example.com>
---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:
Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2017-06-23
--- loolwsd-2.1.2.orig/Makefile.am
+++ loolwsd-2.1.2/Makefile.am
@@ -38,9 +38,9 @@ endif
AM_LDFLAGS = -pthread -Wl,-E,-rpath,/snap/loolwsd/current/usr/lib $(ZLIB_LIBS)
-if ENABLE_SSL
+#if ENABLE_SSL
AM_LDFLAGS += -lssl -lcrypto
-endif
+#endif
loolwsd_fuzzer_CPPFLAGS = -DKIT_IN_PROCESS=1 -DFUZZER=1 -DTDOC=\"$(abs_top_srcdir)/test/data\" $(AM_CPPFLAGS)
$ vim debian/patches/fix-libpath
Description: Fix the LibreOffice library path
Ensure that the build can find the LibreOffice files
.
loolwsd (2.1.2-7) stable; urgency=medium
.
* Custom build of 2.1.2 for Debian Stretch
Author: Your Name <you@example.com>
---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:
Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2017-06-23
--- loolwsd-2.1.2.orig/configure.ac
+++ loolwsd-2.1.2/configure.ac
@@ -166,7 +166,7 @@ AS_IF([test -n "$with_lokit_path"],
[CPPFLAGS="$CPPFLAGS -I${with_lokit_path}"])
lokit_msg="$with_lokit_path"
-LO_PATH="/usr/lib64/libreoffice"
+LO_PATH="/usr/lib/libreoffice"
JAIL_PATH=not-set
SYSTEMPLATE_PATH=not-set
have_lo_path=false
One final tweak to perform is to edit the systemd unit file to point to the libreoffice
templates directory rather than the Collabora one, and change the Red Hat-specific EnvironmentFile
directive to the Debian one (which isn’t installed by default but can be used if needed).
$ vim debian/loolwsd.service
@@ -3,8 +3,8 @@ Description=LibreOffice Online WebSocket Daemon
After=network.target
[Service]
-EnvironmentFile=-/etc/sysconfig/loolwsd
-ExecStart=/usr/bin/loolwsd --version --o:sys_template_path=/opt/lool/systemplate --o:lo_template_path=/opt/collaboraoffice5.3 --o:child_root_path=/opt/lool/child-roots --o:file_server_root_path=/usr/share/loolwsd
+EnvironmentFile=-/etc/default/loolwsd
+ExecStart=/usr/bin/loolwsd --version --o:sys_template_path=/opt/lool/systemplate --o:lo_template_path=/usr/lib/libreoffice --o:child_root_path=/opt/lool/child-roots --o:file_server_root_path=/usr/share/loolwsd
User=lool
KillMode=control-group
Restart=always
Now we install some required npm
dependencies; the nodejs-legacy
package will provide our npm
; don’t install the npm
package itself as this will cause dependency hell. I do this in the main homedir to avoid putting cruft into the source directories.
$ cd ~
$ npm install uglify-js exorcist d3 evol-colorpicker bootstrap eslint browserify-css d3
Finally, we can build the LibreOffice Online package.
$ cd ~/loolwsd/online/
$ sudo dpkg-buildpackage -us -uc -j4
[lots of output]
dpkg-buildpackage: info: full upload (original source is included)
$ cd ..
Install the resulting deb
file and we’re set - LibreOffice Online, in a Debian package. To install it on another machine, all we need are the packages generated by this guide (libpoco-dev
and friends, and loolwsd
).
Bonus - Changing the LibreOffice Online directory
By default, the LibreOffice Online package installs the main components of the loolwsd
service under /opt/lool
. I’m not a fan of putting anything under /opt
however, and in BLSE2 everything that is per-server and not automated via configuration management goes under /srv
. If you also desire this, it’s very straightforward to edit the Debian configuration to support installing to an arbitrary target directory before building the package.
$ cd ~/loolwsd/online/
$ vim debian/loolwsd.postinst.in
@@ -7,24 +7,24 @@ case "$1" in
setcap cap_fowner,cap_mknod,cap_sys_chroot=ep /usr/bin/loolforkit || true
setcap cap_sys_admin=ep /usr/bin/loolmount || true
- adduser --quiet --system --group --home /opt/lool lool
+ adduser --quiet --system --group --home /srv/lool lool
mkdir -p /var/cache/loolwsd && chown lool: /var/cache/loolwsd
rm -rf /var/cache/loolwsd/*
chown lool: /etc/loolwsd/loolwsd.xml
chmod 640 /etc/loolwsd/loolwsd.xml
# We assume that the LibreOffice to be used is built TDF-style
- # and installs in @LO_PATH@, and that /opt/lool is
+ # and installs in @LO_PATH@, and that /srv/lool is
# on the same file system
- rm -rf /opt/lool
- mkdir -p /opt/lool/child-roots
- chown lool: /opt/lool
- chown lool: /opt/lool/child-roots
+ rm -rf /srv/lool
+ mkdir -p /srv/lool/child-roots
+ chown lool: /srv/lool
+ chown lool: /srv/lool/child-roots
fc-cache @LO_PATH@/share/fonts/truetype
- su lool --shell=/bin/sh -c "loolwsd-systemplate-setup /opt/lool/systemplate @LO_PATH@ >/dev/null 2>&1"
+ su lool --shell=/bin/sh -c "loolwsd-systemplate-setup /srv/lool/systemplate @LO_PATH@ >/dev/null 2>&1"
;;
esac
$ vim debian/loolwsd.service
@@ -4,7 +4,7 @@ After=network.target
[Service]
EnvironmentFile=-/etc/default/loolwsd
-ExecStart=/usr/bin/loolwsd --version --o:sys_template_path=/opt/lool/systemplate --o:lo_template_path=/usr/lib/libreoffice --o:child_root_path=/opt/lool/child-roots --o:file_server_root_path=/usr/share/loolwsd
+ExecStart=/usr/bin/loolwsd --version --o:sys_template_path=/srv/lool/systemplate --o:lo_template_path=/usr/lib/libreoffice --o:child_root_path=/srv/lool/child-roots --o:file_server_root_path=/usr/share/loolwsd
User=lool
KillMode=control-group
Restart=always
I hope this helps you avoid many hours of headache! I’ll document the configuration and integration of LibreOffice Online in another post. Happy building!