TL;DR:
Dependencies you will need:
- kf6-archive (not obtainable in normal ubuntu package sources), which needs:
- Extra Cmake Modules (not obtainable in ubuntu package sources)
- Qt 6.8.2 or newer (Qt from ubuntu package source is too old, so install it from the Online Installer)
- Qt Keychain (obtainable in ubuntu package sources but also with the Qt Online Installer)
- the standard toolchain (C compilers and cmake etc.)
Introduction
Nextcloud Desktop is a free, open source cloud synchronization client, which I love. It automatically synchronizes files in the local filesystem with the remote cloud storage. For example, I organize my countless passwords with a password manager. It stores them in an encrypted database. I can sync this database to a Nextcloud and then access it from another device, let’s say my phone. There are providers in Europe who offer a few GB of free Nextcloud storage. I use those so I do not have to ship my password database across the atlantic to some Amazon AWS server.
My issue
Let’s say, I add a new password on my PC, but have no internet connection enabled. But yesterday, I also added a new password on my phone, which was already synchronized with the cloud. Now, Nextcloud Desktop is quite clever – as soon as I switch on the Internet connection, it will detect that there are synchronization conflicts. I can then manually resolve the conflict.
Which is great, but also quite annoying if it happens a lot, to be honest. Unfortunately, this used to happen a lot. Why? I do not know, but if I was running Windows instead of Linux Mint as an OS, I would not face such problems. The general population of PC users consists mostly of windows users, then mac, and the very small remaining niche uses diverse linux distro, and an even smaller niche uses other operating systems. On windows, the Nextcloud Desktop client is working fine (mostly). On my Linux Mint machine, it used to work, but since a few updates of both my OS and the Nextcloud Desktop Client, everything is broken. Most of the time, the client was stuck in offline mode, even though it had access to the internet. When it went online once in a blue moon, the client never downloaded new stuff, but spent all the time trying to figure out what had changed in my filesystem. I relied heavily on the sync to work, and it was rather annoying to add new passwords from my phone only and not being able to access them on my PC.
A potential fix
At first, I patiently waited for updates of the client. They came, but did not solve my issue. So I searched the Nextcloud Desktop Github repository for issues coming from people who experienced the same problem. It turns out that many people had the same problem, and someone already created a fix and submitted a pull request (#7745). However, it was not merged into the official main branch yet, and it will not be until the next major version (3.16).
What I did not see is that on each pull request, an .AppImage file is built automatically by a bot. If I had seen this, a whole afternoon of figuring out and installing dependencies would have been saved. So you could stop at this time and just use the .AppImage file. But if you are curiuos like me, and eager to procrastinate on some real life stuff, let’s compile it from source. The assignment: Build the nextcloud client from source, using the pull request as a basis.
Before you attempt this, beware: The development version of Nextcloud Desktop may mess up your important data. Just saying.
Cloning the client repo
The github repo which contains the source code of Nextcloud Desktop, does offer some advice to developers on how to build the client from source for developing purposes. They „strongly recommend“ using a docker environment which was provided. But I don’t want to use the client only inside a confined environment, I want to use it for „production“. For sure, it must be possible to compile in a docker environment and then use the binaries in a „normal“ desktop environment, but I don’t know how to do this.
So I set on my journey to compile Nextcloud Desktop from source without any knowledge of the dependencies I would need to fulfill.
Cloning the github repo was the first challenge. First, I wanted to find out how to clone the bugfix branch only (named bugfix/preventWrongPermissionsDetectionOnLinuxNtfs) and not the whole thing with all branches. This was my solution:
git clone -b bugfix/preventWrongPermissionsDetectionOnLinuxNtfs --single-branch https://github.com/nextcloud/desktop
But it failed to download several times, and I suspect that happened because it was still quite big. So I went on to find possible fixes on StackOverflow. The solution was to lower git’s HTTP version to 1.1. Don’t ask me why this worked.
git config --global http.version HTTP/1.1
Try to build from source
Now, with the repo downloaded, comes the next step: Trying to build the source code into a binary executable.
First, create a folder where the build is going to end up. Preferably next to the downloaded repo, but it is up to you. I chose to name it „desktop-build“ and place it next to the dowloaded repo („desktop“). Then cd into the „desktop-build“ folder, and run cmake.
cmake -S ../desktop -DCMAKE_BUILD_TYPE=debug
Which, of course, did not work instantly. It told me that Qt could not be found. So let’s go for a dive into dependency hell!
Qt
Qt is a widely used framework for development of graphical applications. Until a few years ago, there was Qt 5, now there is Qt 6. The ubuntu package managers contain several development packages for Qt 6, which I had to find first. But later, it turns out that those were too old, so feel free to skip my attempts to install Qt from official packages sources. I had to install Qt with the official Qt online installer anyway in the end. But at first, I hoped to get away with using my apt package manager only and not having to create an account at Qt and use their official online installer. A great tip to find packages on debian based distros is to use apt search qt6 (replace qt6 with whatever you are looking for). Another needed dependency is Qt-Keychain, which is used to communicate with the credential storage of your OS. The main Qt components come with the qt6-base-dev package and its dependencies.
sudo apt install qtkeychain-qt6-dev qt6-base-dev
After this, I retried the cmake command. Yay! Qt6 and Qt-Keychain were found. Now, the next dependency was missing: kf6-archive.
kf6-archive
This is a program for dealing with archives, like .zip files for example. It belongs to the KDE Desktop Environment. Which unfortunately is not the environment that I use on Linux Mint (Cinnamon). So, needless to say, the kf6-archive package is not in the official PPAs – only for kubuntu, which is the KDE-based distribution of Ubuntu. So, give up – or try building kf6-archive from source? Build it from source. Cloning the github repo is the first step. Then I made a build directory, a place for the built files to go into. Change into that directory, and try to build it with cmake.
git clone https://github.com/KDE/karchive
mkdir karchive-build
cd karchive-build
cmake -DCMAKE_BUILD_TYPE=release -S ../karchive -B .
For sure, this did not work straight out of the box. It turns out, kf6-archive needs Extra Cmake Modules (ECM), an other part of the KDE ecosystem.
Extra Cmake Modules
There are various ecm-packages in the official ubuntu package sources, but none of them were the dependency that kf6-archive wanted to build upon.
So, next step: Install Extra Cmake Modules from source.
git clone https://invent.kde.org/frameworks/extra-cmake-modules
mkdir ecm-build
cd ecm-build
cmake -DCMAKE_BUILD_TYPE=debug -S ../extra-cmake-modules -B .
make
make install
Now, this compiled like a charm without any missing dependencies. Unbelievable!
Try to compile kf6-archive
So, now go to the karchive-build folder and retry compilation of kf6-archive:
cd ../karchive-build
cmake -DCMAKE_BUILD_TYPE=release -S ../karchive -B .
This still failed, because the Qt6 version from the ubuntu package sources was not new enough. To install a new version of Qt6, you have to use the online installer from Qt and register with a free account. I tried to avoid this, but now this is the only way forward.
Install Qt 6.8.2 with the online installer
The Qt installer comes as a ~80 MB .run file, which prompts your Qt account credentials, license agreements and then lets you choose the components you want to install. In my case, I only wanted to install Qt 6.8.2 and not the associated Studios / Suites for Developers. I had to uncheck a lot of boxes, and still the download is 4.7 GB (and 14 GB of disk space required…). So time to clean up my hard drive to make some space and then go for a walk.
Unfortunately, I installed Qt6 to the default location, which was in my home directory. That meant, it was not automatically found by cmake. I think you are supposed to put it in a place like /opt/qt/, I could have gone forward and uninstalled and reinstall it to the correct location, but that would have taken ages with my slow internet connection. Instead, for the compilation of kf6-archive, I supplied an argument that tells cmake where to look for the Qt6 qmake executable.
cmake -S ../karchive -DCMAKE_BUILD_TYPE=debug -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_PREFIX_PATH=~/Qt/6.8.2/gcc_64
make
make install
This worked, finally.
Compile Nextcloud Desktop
With kf6-archive in place, the compilation of Nextcloud Desktop could finally be attempted.
cd ../desktop-build
cmake -S ../desktop -DCMAKE_BUILD_TYPE=debug -DCMAKE_PREFIX_PATH=~/Qt/6.8.2/gcc_64
make
-- Build of crashreporter disabled.
556d26c6f19b37c4940572c57d078044eb5b2eb1
-- GIT_SHA1 556d26c6f19b37c4940572c57d078044eb5b2eb1
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Performing Test HAVE_STDATOMIC
-- Performing Test HAVE_STDATOMIC - Success
-- Found WrapAtomic: TRUE
Compiling with updater
-- Could NOT find Sphinx (missing: SPHINX_EXECUTABLE)
-- Checking for module 'cloudproviders'
-- Package 'cloudproviders', required by 'virtual:world', not found
-- Found OpenGL: /usr/lib/x86_64-linux-gnu/libGL.so
-- Enable use of Qt6 WebEngine module
-- Using Qt 6.8.2 (/home/elbe/Qt/6.8.2/gcc_64/bin/qmake)
-- Performing Test WITH_FPIC
-- Performing Test WITH_FPIC - Success
-- Performing Test WITH_STACK_PROTECTOR
-- Performing Test WITH_STACK_PROTECTOR - Success
-- Looking for argp.h
-- Looking for argp.h - found
-- Looking for utimes
-- Looking for utimes - found
-- Looking for lstat
-- Looking for lstat - found
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
list of plugins suffix;cfapi;xattr
discovery suffix
/home/elbe/Dokumente/Github/desktop-3.16.0-rc2/src/libsync/vfs/suffix
/home/elbe/Dokumente/Github/desktop-3.16.0-rc2/src/libsync/vfs/suffix suffix
-- Added vfsPlugin without tests: suffix
discovery cfapi
/home/elbe/Dokumente/Github/desktop-3.16.0-rc2/src/libsync/vfs/cfapi
/home/elbe/Dokumente/Github/desktop-3.16.0-rc2/src/libsync/vfs/cfapi cfapi
-- Added vfsPlugin without tests: cfapi
discovery xattr
/home/elbe/Dokumente/Github/desktop-3.16.0-rc2/src/libsync/vfs/xattr
/home/elbe/Dokumente/Github/desktop-3.16.0-rc2/src/libsync/vfs/xattr xattr
-- Added vfsPlugin without tests: xattr
CMake Warning at src/gui/CMakeLists.txt:4 (find_package):
By not providing "FindKF6GuiAddons.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"KF6GuiAddons", but CMake did not find one.
Could not find a package configuration file provided by "KF6GuiAddons" with
any of the following names:
KF6GuiAddonsConfig.cmake
kf6guiaddons-config.cmake
Add the installation prefix of "KF6GuiAddons" to CMAKE_PREFIX_PATH or set
"KF6GuiAddons_DIR" to a directory containing one of the above files. If
"KF6GuiAddons" provides a separate development package or SDK, be sure it
has been installed.
Generating state icons from SVG in path: /home/elbe/Dokumente/Github/desktop-3.16.0-rc2/theme/colored/
-- Generate state-error-16.png
-- Generate state-error-32.png
-- Generate state-error-64.png
-- Generate state-error-128.png
-- Generate state-error-256.png
-- Generate state-offline-16.png
-- Generate state-offline-32.png
-- Generate state-offline-64.png
-- Generate state-offline-128.png
-- Generate state-offline-256.png
-- Generate state-ok-16.png
-- Generate state-ok-32.png
-- Generate state-ok-64.png
-- Generate state-ok-128.png
-- Generate state-ok-256.png
-- Generate state-pause-16.png
-- Generate state-pause-32.png
-- Generate state-pause-64.png
-- Generate state-pause-128.png
-- Generate state-pause-256.png
-- Generate state-sync-16.png
-- Generate state-sync-32.png
-- Generate state-sync-64.png
-- Generate state-sync-128.png
-- Generate state-sync-256.png
-- Generate state-warning-16.png
-- Generate state-warning-32.png
-- Generate state-warning-64.png
-- Generate state-warning-128.png
-- Generate state-warning-256.png
Generating state icons from SVG in path: /home/elbe/Dokumente/Github/desktop-3.16.0-rc2/theme/black/
-- Generate state-error-16.png
-- Generate state-error-32.png
-- Generate state-error-64.png
-- Generate state-error-128.png
-- Generate state-error-256.png
-- Generate state-info-16.png
-- Generate state-info-32.png
-- Generate state-info-64.png
-- Generate state-info-128.png
-- Generate state-info-256.png
-- Generate state-offline-16.png
-- Generate state-offline-32.png
-- Generate state-offline-64.png
-- Generate state-offline-128.png
-- Generate state-offline-256.png
-- Generate state-ok-16.png
-- Generate state-ok-32.png
-- Generate state-ok-64.png
-- Generate state-ok-128.png
-- Generate state-ok-256.png
-- Generate state-pause-16.png
-- Generate state-pause-32.png
-- Generate state-pause-64.png
-- Generate state-pause-128.png
-- Generate state-pause-256.png
-- Generate state-sync-16.png
-- Generate state-sync-32.png
-- Generate state-sync-64.png
-- Generate state-sync-128.png
-- Generate state-sync-256.png
-- Generate state-warning-16.png
-- Generate state-warning-32.png
-- Generate state-warning-64.png
-- Generate state-warning-128.png
-- Generate state-warning-256.png
Generating state icons from SVG in path: /home/elbe/Dokumente/Github/desktop-3.16.0-rc2/theme/white/
-- Generate state-error-16.png
-- Generate state-error-32.png
-- Generate state-error-64.png
-- Generate state-error-128.png
-- Generate state-error-256.png
-- Generate state-info-16.png
-- Generate state-info-32.png
-- Generate state-info-64.png
-- Generate state-info-128.png
-- Generate state-info-256.png
-- Generate state-offline-16.png
-- Generate state-offline-32.png
-- Generate state-offline-64.png
-- Generate state-offline-128.png
-- Generate state-offline-256.png
-- Generate state-ok-16.png
-- Generate state-ok-32.png
-- Generate state-ok-64.png
-- Generate state-ok-128.png
-- Generate state-ok-256.png
-- Generate state-pause-16.png
-- Generate state-pause-32.png
-- Generate state-pause-64.png
-- Generate state-pause-128.png
-- Generate state-pause-256.png
-- Generate state-sync-16.png
-- Generate state-sync-32.png
-- Generate state-sync-64.png
-- Generate state-sync-128.png
-- Generate state-sync-256.png
-- Generate state-warning-16.png
-- Generate state-warning-32.png
-- Generate state-warning-64.png
-- Generate state-warning-128.png
-- Generate state-warning-256.png
-- Generate 16-Nextcloud-icon.png
-- Generate 24-Nextcloud-icon.png
-- Generate 32-Nextcloud-icon.png
-- Generate 48-Nextcloud-icon.png
-- Generate 64-Nextcloud-icon.png
-- Generate 128-Nextcloud-icon.png
-- Generate 256-Nextcloud-icon.png
-- Generate 512-Nextcloud-icon.png
-- Generate 1024-Nextcloud-icon.png
-- Found SharedMimeInfo: /usr/bin/update-mime-database (found version "2.1")
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
Dolphin plugin disabled: KDE Frameworks 5 and 6 not found
-- Could NOT find CMocka (missing: CMOCKA_LIBRARIES CMOCKA_INCLUDE_DIR)
-- The following OPTIONAL packages have been found:
* PdfLatex
* Qt6WebEngineCoreTools (required version >= 6.8.2)
* OpenGL
* XKB (required version >= 0.5.0), XKB API common to servers and clients., <http://xkbcommon.org>
* Vulkan
* Qt6QuickTools (required version >= 6.8.2)
* Qt6QmlTools (required version >= 6.8.2)
* WrapVulkanHeaders
* Qt6GuiTools (required version >= 6.8.2)
* Qt6WidgetsTools (required version >= 6.8.2)
* Qt6DBusTools (required version >= 6.8.2)
* Qt6WebSockets
* Qt6Sql
* Qt6Svg
* Qt6QuickControls2
* Qt6CoreTools (required version >= 6.8.2)
* Qt6LinguistTools (required version >= 6.5.0)
* SharedMimeInfo, A database of common MIME types, <https://freedesktop.org/wiki/Software/shared-mime-info/>
* Qt6Test (required version >= 6.8.0)
-- The following REQUIRED packages have been found:
* Inotify
* OpenSSL (required version >= 1.1)
* ZLIB
* SQLite3 (required version >= 3.9.0)
* PkgConfig
* Qt6WebEngineCore (required version >= 6.8.0), Qt6 WebEngine component.
* Qt6WebEngineWidgets (required version >= 6.8.0), Qt6 WebEngineWidgets component.
* Qt6Network (required version >= 6.5.0), Qt6 Network component.
* Qt6Concurrent (required version >= 6.5.0), Qt6 Concurrent component.
* Qt6QuickWidgets (required version >= 6.5.0), Qt6 QuickWidgets component.
* Qt6Keychain
* KF6Archive
* Qt6Xml (required version >= 6.8.0), Qt6 Xml component.
* Qt6 (required version >= 6.8.0)
* Qt6Core5Compat (required version >= 6.8.0), Qt6 Core5Compat component.
-- The following OPTIONAL packages have not been found:
* Sphinx
* Qt6QmlCompilerPlusPrivateTools (required version >= 6.8.2)
* Cups
* KF6GuiAddons
* Doxygen
* KF5KIO (required version >= 5.16)
* KF6KIO (required version >= 5.240)
* CMocka
-- Configuring done
-- Generating done
-- Build files have been written to: /home/elbe/Dokumente/Github/desktop-3.16.0-rc2-build
All dependencies were found. It took some time to compile, but it worked! And in the end, I had the executable binaries in my „desktop-build“ folder. The sync client can now be started with ./bin/nextcloud
when . is the folder where you built it. The client is working, and for the first time in months, it started to sync all the files that had been added to the cloud in the meantime from other devices.
It can be useful to remove all Nextcloud accounts from previous configurations (you do not have to delete the data folders, just remove the accounts) and then log in again with the same accounts.
Thanksgiving
Big Thanks to the contributors of the Nextcloud Desktop client, it is an awesome application. My gratitude goes especially towards @mgallien who created this pull request and made it work.
Installing the nemo integration in Linux Mint
How to get sync icons with your file manager in Linux Mint? For all major file managers (dolphin, nautilus, nemo, caja), there are python scripts that enable the integration of Nextcloud. This means having sync icons on the files and a context menu for sharing links etc.
For nemo, first install nemo-python
sudo apt install nemo-python
Then go to your build folder. There should be a folder called “shell_integrations”.
The nemo extension python script can be found at YOUR_BUILD_FOLDER/shell_integration/nautilus/syncstate_nemo.py
.
Open a terminal and copy this file to /usr/share/nemo-python/extensions
and rename it to synstate-Nextcloud.py
sudo cp /home/elbe/Dokumente/Github/desktop-3.16.0-build/shell_integration/nautilus/syncstate_nemo.py ./syncstate-Nextcloud.py
Then quit nemo
nemo -q
And just restart it by opening a folder.
Nemo will only load the script and display the icons, if the Nextcloud client is running already at the time Nemo is started.