+++ Categories = ["Development","Systems Administration"] Tags = ["Development","Systems Administration"] Description = "How to build LibreofficeOnline against stock Libreoffice on Debian Stretch" date = "2017-07-06T22:44:53-04:00" title = "Building LibreOffice Online for Debian" type = "post" weight = 1 draft = true +++ LibreOffice Online is a very cool project by the fine people at [Collabora](https://www.collaboraoffice.com/code/) 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 forseeable 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-asside: 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](https://gist.github.com/m-jowett/0f28bff952737f210574fc3b2efaa01a) [`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 I can, 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-asside: poor dependency lifecycle 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. 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`: you 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`. ``` 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 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](https://wiki.debian.org/qa.debian.org/jsonevil). As a result, 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 `; 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 commited 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 your custom packages will supercede 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, and 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 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, you should see a long list of generated packages in the parent directory. Change there, 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. Begin by making a separate 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 devs 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 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 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. ``` $ 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, libssl1.0.0, 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 (user something as a forward proxy, also prevents build errors) and specifying the library directory; this is needed for the build proess 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) and the shlibdeps steps (to avoid more errors). ``` @@ -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 --- 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: , Bug: Bug-Debian: https://bugs.debian.org/ Bug-Ubuntu: https://launchpad.net/bugs/ Forwarded: Reviewed-By: 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 --- 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: , Bug: Bug-Debian: https://bugs.debian.org/ Bug-Ubuntu: https://launchpad.net/bugs/ Forwarded: Reviewed-By: 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 ``` Now we install some required `npm` dependencies; the `nodejs-legacy` dependency should have provided `npm`; don't install the `npm` package itself as this will cause dependency hell. ``` 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 you're set - LibreOffice Online, in a Debian package. To install it on another machine, all you need are the packages generated by this guide (`libpoco-dev` and friends, and `loolwsd`). I hope this helps you avoid many hours of headache! I'll document the configuration and integration of LibreOffice Online in another post. Happy editing!