Guide on how to build & install Krita in Virtual Machine running Fedora 35 + Installing Xencelabs Driver

I moved heaven and Earth to Build and Install the Krita app in a Virtual Machine, so I can use my Xencelabs Drawing Tablet in Fedora 35. Because the Dev team has stopped updating it.

I’ve download the Xencelabs Driver, the dependency packages to build the Krita app from source-code, and the Krita source-code itself. Then moved it over to the VM with a USB stick and toggling USB pass-through. This wouldn’t have been possible unless I had the assistance of the A.I. Kimi K2 and Gemini 3

Note: This requires a CPU with Integrated Graphics.


Setting Up Fedora 35 in a VM with GNOME Boxes

Download Fedora 35 Workstation .iso from the archives. Look for the file: Fedora-Workstation-Live-x86_64-35-1.2.iso

Use this image to create a VM in the Gnome Boxes app. 15GB seems to be the ideal size. 3.6GB is required for the distro but Xencelabs, Krita, and the building tools need to be installed as well. There’s a bug when selecting a disk to install to. You need to click on your disk drive, rescan disks, then exit the menu.

After Fedora 35 is installed, immediately turn off internet access.

Download the source-code for the stable release of Krita: KDE - Experience Freedom!
This guide was made for krita-5.2.13.tar.gz. A more recent release may still be compatible.

Download the Xencelabslinux_1.3.4-26 driver.

Copy both these files onto the USB you’ll be using to transfer files to the VM.

Installing and Building Krita for Fedora 35

Step 1: Create a sandbox directory to pass to the --installroot option.

mkdir -p /home/user-name/tmp_f35_sandbox
mkdir -p /home/user-name/Software/krita-deps-f35
cd Software/krita-deps-f35

Be sure to replace user-name with your actual log-in name!!

This sandbox directory will be located in the /media/ directory. Clean it up later.


Step 2: Download the specific .x86_64 dependencies from the Fedora 35 Archive.

Replace user-name with your actual log-in name.

sudo dnf download --releasever=35 \
  --installroot=/home/user-name/tmp_f35_sandbox \
  --destdir=/home/user-name/Software/krita-deps-f35 \
  --resolve \
  --repofrompath=f35archive,https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/35/Everything/x86_64/os/ \
  --disablerepo=* --enablerepo=f35archive \
  --nogpgcheck \
  --skip-unavailable \
  cmake.x86_64 extra-cmake-modules gcc-c++.x86_64 make.x86_64 \
  qt5-qtbase-devel.x86_64 qt5-qtmultimedia-devel.x86_64 qt5-qtsvg-devel.x86_64 \
  qt5-qtx11extras-devel.x86_64 kf5-kconfigwidgets-devel.x86_64 kf5-kcoreaddons-devel.x86_64 \
  kf5-kguiaddons-devel.x86_64 kf5-ki18n-devel.x86_64 kf5-kitemviews-devel.x86_64 \
  kf5-kwidgetsaddons-devel.x86_64 kf5-kwindowsystem-devel.x86_64 kf5-kcrash-devel.x86_64 \
  kf5-karchive-devel.x86_64 kf5-kio-devel.x86_64 kf5-kcompletion-devel.x86_64 kf5-kconfig-devel.x86_64 \
  kf5-kdbusaddons-devel.x86_64 kf5-kglobalaccel-devel.x86_64 kf5-kjobwidgets-devel.x86_64 \
  kf5-knotifications-devel.x86_64 kf5-ktextwidgets-devel.x86_64 kf5-kxmlgui-devel.x86_64 \
  kf5-sonnet-devel.x86_64 gsl-devel.x86_64 lcms2-devel.x86_64 exiv2-devel.x86_64 openjpeg2-devel.x86_64 \
  poppler-qt5-devel.x86_64 python3-devel.x86_64 boost-devel.x86_64 eigen3-devel fftw-devel.x86_64 \
  libwebp-devel.x86_64 libzip-devel.x86_64 giflib-devel.x86_64 sqlite-devel.x86_64 \
  LibRaw-devel.x86_64 jsoncpp.x86_64 rhash.x86_64 opencv-devel.x86_64 \
  libXi-devel.x86_64 libX11-devel.x86_64 libXext-devel.x86_64 libXfixes-devel.x86_64 \
  libXrender-devel.x86_64 libxcb-devel.x86_64 xcb-util-devel.x86_64 xcb-util-keysyms-devel.x86_64 \
  xcb-util-image-devel.x86_64 xcb-util-wm-devel.x86_64 \
  libpng-devel.x86_64 libjpeg-turbo-devel.x86_64 libtiff-devel.x86_64 \
  freetype-devel.x86_64 libmypaint-devel.x86_64 openexr-devel.x86_64 \
  xsimd-devel.x86_64 python3-pyqt5-devel.x86_64 python3-sip-devel.x86_64 \
  quazip-qt5-devel.x86_64 opencolorio-devel.x86_64 fftw3-devel.x86_64 \
  fontconfig-devel.x86_64 fribidi-devel.x86_64 \
  immer-devel zug-devel lager-devel

These development build tools (Specific to F35) need to be downloaded on Fedora 43 or your internet working machine.

It includes dependencies for Base, X11, lager, and Image files.

Verify if all the files are accounted for (This should output 935):

ls | wc -l

Download 3rd-Party packages that need to be installed separately

Download the master-branch .zip files.

Create a new folder called 3rd-party in your Downloads directory and place the Immer, Zug, Xsimd, Lager, HarfBuzz, and Libunibreak files into it. This is where it will be extracted in. Move the file to your USB.

If there are any error messages, check if your replaced user-name with your computers actual Log-in name.

Since the sudo command was used to download the dependencies, file permissions may need to be changed before they can be drag-dropped to the USB.


Step 3: Copy all the files onto the USB by drag-dropping them in File Explorer app.

The USB stick needs to have the Xencelabslinux_1.3.4-26, the krita-*.tar.gz file, krita-deps-f35, and 3rd-party onto the USB stick.

Open the Fedora 35 VM and enable the USB in the VM by clicking on the button with the three vertical dots in the Top-right corner of the Boxes app window. Click on preferences, then navigate to the Devices & Shares tab.

If your switching the USB between your host machine and your VM, the permissions may need to be changed.

Find out what your USB name is:

ls /run/media/$USER/

External devices often mount with root:root ownership. Change it to your USER:

sudo chown -R $USER:$USER /run/media/$USER/USB_LABEL

Replace USB_LABEL with your actual device name.

This grants you full ownership, automatically enabling read, write, create, and delete permissions.

If needed, explicitly set permissions:

sudo chmod -R u+rwx /run/media/$USER/USB_LABEL

The krita-deps-f35 folder may have files that require you to change their permissions before you can move them.

Replace user-name with your Computers Log-in name

sudo chmod -R 777 /home/user-name/Software/krita-deps-f35

Step 4: Install the dependencies into the VM

In the VM, create a Software directory in the /home then drag-drop the files into this directory.

Alternatively, use the CLT to create the directory and move the files.

mkdir -p /home/user-name/Software 

Find out the name of your USB.

/run/media/user-name

Replace user-name with your Computers Log-in name

Double-tap the TAB key to auto-complete the name of the USB.

Then type the rest

cp -rv /run/media/user-name/USB/* Software/

Navigate to the krita-deps-f35 folder:

cd Software/krita-deps-f35

The “Basic” identity package that conflicts with Workstation version of Fedora needs to be removed.

rm fedora-release-common-*.rpm fedora-release-*.rpm 2>/dev/null

Install the packages:

sudo dnf install --disablerepo=* --nogpgcheck ./*.rpm

–disablerepo=* will treat the current directory as the only source of packages.

Double check if libXi-devel is installed:

rpm -q libXi-devel

Step 5: Install the non-RPM files

An individual directory will be made for Immer, Zug, and Lager when they’re unzipped. They will each have their own build folder where they’ll be installed to the VM.

Go back to the parent directory (Software).

cd ..

Enter the 3rd-party directory

cd 3rd-party

Install immer (Enter these commands individually)

unzip immer-master.zip
cd immer-master
mkdir -p build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
  -Dimmer_BUILD_TESTS=OFF \
  -Dimmer_BUILD_EXAMPLES=OFF \
  -Dimmer_BUILD_DOCS=OFF \
  -Dimmer_BUILD_EXTRAS=OFF
sudo make install
cd ../..

The cd ../.. will return you to the 3rd-party directory.

Install zug

unzip zug-master.zip
cd zug-master
mkdir -p build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
  -Dzug_BUILD_TESTS=OFF \
  -Dzug_BUILD_EXAMPLES=OFF \
  -Dzug_BUILD_DOCS=OFF
sudo make install
cd ../..

Install lager

unzip lager-master.zip
cd lager-master
mkdir -p build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
  -Dlager_BUILD_TESTS=OFF \
  -Dlager_BUILD_EXAMPLES=OFF \
  -Dlager_BUILD_DOCS=OFF
sudo make install
cd ../..

Install xsimd

tar -xzf xsimd-*.tar.gz
cd xsimd-*
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
  -DBUILD_TESTS=OFF \
  -DBUILD_EXAMPLES=OFF \
  -DBUILD_BENCHMARKS=OFF
sudo make install
cd ../..

Install hafbuzz

tar -xzf harfbuzz-*.tar.gz
cd harfbuzz-*
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
  -DHB_HAVE_FREETYPE=ON \
  -DBUILD_SHARED_LIBS=ON
sudo make install

Install libunibreak (Needs to be version 5.1 or above)

tar -xzf libunibreak-*.tar.gz
cd libunibreak-*
mkdir build && cd build

This library uses Autotools (configure), not CMake

../configure --prefix=/usr
make
sudo make install
cd ../../..

Step 6: Bug Fix

The fftw3-devel package package is missing one specific file. But it provides the essential header (fftw3.h) and library file (libfftw3.so) that Krita requires to build. Create a dummy file and fix the error.

sudo touch /usr/lib64/cmake/fftw3/FFTW3LibraryDepends.cmake

Link ALL headers from openjpeg-2.4/*.h subdirectory to /usr/include

sudo ln -s /usr/include/openjpeg-2.4/*.h /usr/include/

Step 7: Build the Krita app

Make sure your in the Software directory with pwd

Unzip the tarball file of the Krita source-code and create a directory for krita-build

tar -xzf krita-5.2.13.tar.gz
mkdir -p krita-build && cd krita-build

Be sure to replace user-name with your VM’s Log-in name!

cmake ../krita-5.2.13 \
  -DCMAKE_INSTALL_PREFIX=/home/user-name/krita-install \
  -DCMAKE_BUILD_TYPE=Release \
  -DBUILD_TESTING=OFF \
  -DHAVE_LIBHEIF=OFF \
  -DMOD_PYTHON=OFF \
  -DENABLE_JPEG_TURBO=OFF \
  -DENABLE_KSEEXPR=OFF \
  -DENABLE_OPENCOLORIO=OFF \
  -DENABLE_JPEGXL=OFF \
  -DENABLE_MLT=OFF \
  -DENABLE_KDcraw=OFF
make -j$(nproc)
make install

Step 8: Placing the Krita app icon in the GNOME activities bar

cd back to the home directory

cd

Open the text editor:

nano ~/.local/share/applications/krita.desktop

Copy and paste the text below into the editor:

Make sure to replace user-name so it matches your current log-in name.

[Desktop Entry]
Type=Application
Name=Krita (Custom)
GenericName=Digital Painting
Comment=Create digital art and painting
# We use 'env' to set the library paths before launching the executable
Exec=env LD_LIBRARY_PATH=/home/user-name/krita-install/lib64:$LD_LIBRARY_PATH QT_PLUGIN_PATH=/home/user-name/krita-install/lib64/plugins:$QT_PLUGIN_PATH /home/user-name/krita-install/bin/krita %F
Icon=krita
Terminal=false
Categories=Graphics;2DGraphics;RasterGraphics;
MimeType=application/x-krita;image/openraster;image/png;image/jpeg;
StartupNotify=true

Note on the Icon:
If the icon shows up as a generic “gear” or missing symbol, you might need to point the Icon= line to the specific icon file. Krita usually installs one here:
/home/user-name/krita-install/share/icons/hicolor/256x256/apps/krita.png

Save and Apply:

  1. Press Ctrl+O then Enter to save.
  2. Press Ctrl+X to exit.
  • Make the file executable (sometimes required):
chmod +x ~/.local/share/applications/krita.desktop

The icon should appear instantly in your Activities bar.
If it doesn’t: Log out and log back in.

Step 9: Clean-up on main host computer

The tmp_f35_sandbox file should be in your /home directory on your host computer.


Install the Xencelabs driver

Go to the Software directory where the Xencelabslinux_1.3.4-26.zip is located.

cd Software/
unzip Xencelabslinux_1.3.4-26.zip
cd Xencelabslinux_1.3.4-26-RC/
sudo dnf install --disablerepo=* --nogpgcheck *.rpm

Create a copy of the VM within Boxes and save the files in a folder such as Boxes-VM.


I see now what they call ‘dependency hell’. I only discovered that Krita had an AppImage while making this tutorial.

The makers of the Xencelab tablets actually used to maintain their driver for 8+ distros. But the dev team probably didn’t find it cost effective to update them. An easy fix if they had just realeased a flatpak or AppImage.

As for Krita, the devs need to juggle X11 and Wayland. Even on my host computer, I can only open the app through the GNOME package manager. Dynamically linked packages may save a lot of space, but having compatability across multiple distro’s is the priority.

There’s a Linux Driver for the XP-pen Tablets, but it has the same issue as Xencelabs Tablets. The transition from X11 to Wayland.

If you want to help, send an E-mail to the XenceLabs support team at SupportNorthAmerica@xencelabs.com and ask them to create a flatpak, AppImage, docker file, or other suitable package format that runs on any Linux distribution.

And that they can use A.I. to assist them in writing the Driver package. Such as the paid version of Kimi K2 ( Moderato), which grants access to ‘Kimi For Coding’. Or Gemini 3 Pro.

You could even use your own preferred A.I. to write the E-mail for you.

Since Fedora 35 doesn’t have File-share, there’s another way to move files besides USB-passthrough. It’s called NFS but the nfs-utils needs to be specific for Fedora 35 and installed manually.

Offline NFS Setup for Fedora 35 in GNOME Boxes

Step 1: Download the nfs-utils files on your Host Machine

Create a directory for the packages:

cd Downloads
mkdir nfs-f35 && cd nfs-f35

Download nfs-utils for Fedora 35:

wget https://dl.fedoraproject.org/pub/archive/fedora/linux/releases/35/Server/x86_64/os/Packages/n/nfs-utils-2.5.4-2.rc3.fc35.x86_64.rpm

Also download rpcbind (Required dependency):

dnf download --releasever=35 --disablerepo=* --enablerepo=fedora --arch=x86_64 rpcbind

Verify downloads:

ls -lh *.rpm

Step 2: Transfer Files to Your Fedora 35 VM

Create ISO Image of Files (Or pass them over with a USB stick):

mkisofs -o nfs-tools-f35.iso -J -R *.rpm

In GNOME Boxes:

  1. Right-click VM → Preferences

  2. Go to Devices & SharesCDROM/DVD Drive

  3. Remove Fedora-Workstation-Live-x86_64-35-1.2.iso

  4. Click + and select nfs-tools-f35.iso from the
    nfs-f35 folder in your Downloads

In the VM, mount the CD:

sudo mkdir -p /mnt/cdrom
sudo mount /dev/sr0 /mnt/cdrom
mkdir -p ~/nfs-install
cp /mnt/cdrom/*.rpm ~/nfs-install/
cd ~/nfs-install

Mount the Fedora-Workstation-Live-x86_64-35-1.2.iso back in the DVD drive afterwards.

Step 3: Install nfs-utils And rpcbind In Your Fedora 35 VM

Install both packages offline:

sudo dnf install --disablerepo=* --nogpgcheck *.rpm

Verify installation:

rpm -q nfs-utils rpcbind

Enable and start rpcbind (Required for NFS):

sudo systemctl enable --now rpcbind

Step 4: Configure Host Server & Firewall

Create the folder you want to share:

mkdir -p /home/$USER/boxes-fileshare

Set permissions so the Fedora 35 VM can write to it:

chmod 777 /home/$USER/boxes-fileshare

Step 5: Configure /etc/exports on Host:

sudo nano /etc/exports

Define the share by adding this line to the bottom of the file:

Replace YOUR_USERNAME with your log-in name

/home/YOUR_USERNAME/boxes-fileshare 192.168.122.0/24(rw,sync,no_subtree_check)

Then reload the exports with:

sudo exportfs -arv

Step 6: Open Firewall on Host

On your Host machine, specifically open the ports only for the virtualization interface (virbr0). Not the whole Wi-Fi/LAN:

sudo firewall-cmd --permanent --zone=libvirt --add-service=nfs
sudo firewall-cmd --permanent --zone=libvirt --add-service=rpc-bind
sudo firewall-cmd --permanent --zone=libvirt --add-service=mountd
sudo firewall-cmd --reload

Start the Server:

sudo systemctl enable --now nfs-server
sudo exportfs -arv

Switch to your Fedora 35 VM and confirm connectivity:

ping -c 4 192.168.122.1
showmount -e 192.168.122.1

This should now list your /home/.../boxes-fileshare directory.

Step 7: Mounting the Shared Folder To Swap Files

Link the Folders

Create a folder in your VM where the files will appear:

mkdir -p ~/boxes-fileshare

Mount the share (Link your Host folder to this new VM folder):

Replace YOUR_USERNAME with your log-in name

sudo mount -t nfs 192.168.122.1:/home/USER-NAME/boxes-fileshare ~/boxes-fileshare

Open your Files app in the VM and look inside the boxes-fileshare folder in your Home directory.

Open the fstab file inside your VM:

sudo nano /etc/fstab

Add this single line at the very bottom:

Replace YOUR_USERNAME with your log-in name

192.168.122.1:/home/YOUR-USERNAME/boxes-fileshare /home/YOUR-USERNAME/boxes-fileshare nfs rw,_netdev 0 0

Verify with:

sudo mount -a

Due to the GVFS NFS backend (gvfs-nfs) not being installed in the Fedora 35 VM, GNOME Files cannot connect to the server in ‘Other Locations’. It must be done in the CLT.