[Guide] Build LBRY Desktop on Devuan Linux (32 bit) [step by step instructions]

I found a post about someone wanting a 32 bit build
. The answer was to build it from source. But there is no easy to
follow guide out there on how to exactly do it. So I took the effort,
went through the trouble and documented the process. Here is the
resulting guide.

I still find ways to use 32 bit x86 machines because I have at least
one and I don’t like to contribute to landfill by throwing away a
perfectly working machine.

Devuan is a distro similar to Debian but
with an emphasis on init freedom. People who have older hardware
that can’t take the resource use of SystemD or doesn’t like SystemD
will love Devuan (as I do). Devuan Daedalus is similar to Debian
Testing/Unstable.

Although this guide may also work for a 64 bit x86_64 Devuan Daedalus
install, I can’t guarantee anything.

Friendly warning, although I took care to not include any third
party repos (they don’t work anyways on i686), it is still a good idea
to use a test install to do this, or have a complete backup before
continuing.

If machine gets too hot during build

If your laptop is getting too hot, it may automatically shut down
in the middle of a build process to stop damage to your hardware
from over-heating. To keep the laptop system cool:

  • Remove obstacles from around vents and ensure air flow around
    the machine; with additionally things like pointing a running table
    fan and lifting up with books on two opposing sides to ensure air
    flow at the bottom
  • sudo apt install tlp may work with no further configs

These 2 above are enough most of the times. If this doesn’t help:

There are also cpulimit commands and make -j hints throughout
this guide to make the load lighter.

A. Build lbrynet

LBRY Desktop needs lbrynet daemon. So we need to build it first.

Prepare Python 3.7

We need to build lbrynet with python 3.7 due this bug:

Because of issue #2769 at the moment the lbrynet daemon will only work correctly with Python 3.7. If Python 3.8+ is used, the daemon will start but the RPC server may not accept messages, returning the following:

Could not connect to daemon. Are you sure it’s running?

Don’t be scared! Building Python isn’t too complicated and doesn’t take
too long even on weak hardware.

cd ~/Downloads
# by all means, update PYVER to latest 3.7.x version below
# see: https://www.python.org/downloads/
PYVER=3.7.16
wget https://www.python.org/ftp/python/$PYVER/Python-$PYVER.tar.xz.asc
wget https://www.python.org/ftp/python/$PYVER/Python-$PYVER.tar.xz
# Got the gpg fingerprint below from the download page under
# "OpenPGP Public Keys" heading
gpg --keyserver keyserver.ubuntu.com --recv 2D347EA6AA65421D --recv FB9921286F5E1540
gpg --verify Python-$PYVER.tar.xz.asc
# If it says 'Good signature from "Ned Deily (Python release
# signing key) <nad@python.org>"' then it's a good copy.
# If it doesn't say above, discard the copy and download again.

cd $(mktemp -d)  # temp dir to extract
tar -xJvf ~/Downloads/Python-$PYVER.tar.xz
sudo mv Python-$PYVER /opt/
cd /opt/Python-$PYVER
sudo apt install build-essential zlib1g-dev libncurses5-dev \
  libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev \
  libffi-dev curl libbz2-dev -y
./configure --enable-optimizations --enable-shared
make -j 2  # change 2 to how many cores you want to dedicate to this
sudo make altinstall  # to install alongside system python
sudo ldconfig /opt/Python-$PYVER  # important, don't skip
python3.7 --version  # should say Python 3.7.x

# python headers
sudo ln -s /opt/Python-3.7.16/Include/ /usr/include/python3.7
# for pyconfig to work later during build
cp /opt/Python-3.7.16/pyconfig.h /opt/Python-3.7.16/Include/

Build lbrynet

lbry-sdk project builds lbrynet which is the daemon that
LBRY Desktop relies on to communicate over LBRY protocol.

mkdir -p ~/Projects ; cd ~/Projects  # or anywhere you keep git repos
# this is for latest master. if you want a specific tag, just pass -b
# e.g. git clone ... -b vX.Y.Z ...
# check https://github.com/lbryio/lbry-sdk/releases for tags
git clone --depth 1 https://github.com/lbryio/lbry-sdk.git
cd lbry-sdk
python3.7 -m venv lbry-venv
source lbry-venv/bin/activate
python --version  # it should say "Python 3.7.x"

# solution to some header related issues (may need to run only once):
rm -rf lbry-venv/include
mkdir -p lbry-venv/include
ln -s /opt/Python-3.7.16/Include/ lbry-venv/include/python3.7  # https://stackoverflow.com/a/45080012

# We'll need to run make install later. We'll come back to it.
# But first need some requirements built...

install boost from source

lbry-sdk make install requires libboost_python37.so, so we’ll need
to build boost from source while being inside the Python 3.7
lbry-venv. Just installing boost packages from repo won’t work.

cd ..  # without quitting out of venv, we'll need that

Go to https://github.com/boostorg/boost/tags in a web browser.
Note the latest version. When writing this it was at 1.81.0, so
I did…

git clone --depth 1 -b boost-1.81.0 https://github.com/boostorg/boost
cd boost
git submodule update --init --recursive --depth 1  # clone submodules too
./bootstrap.sh --prefix=/usr/
./b2  # or "cpulimit -l 200 -- ./b2" if you want to limit cpu usage

When finished it should say something like:

The Boost C++ Libraries were successfully built!

The following directory should be added to compiler include paths:

	/home/username/Projects/boost

The following directory should be added to linker library paths:

	/home/username/Projects/boost/stage/lib

To install:

su -c './b2 install'  # don't use sudo

The output may have something like this:

...updating xx targets...
common.copy /usr/lib/libboost_python37.so.1.81.0
common.copy /usr/lib/cmake/boost_python-1.81.0/libboost_python-variant-shared-py3.7.cmake
ln-UNIX /usr/lib/libboost_python37.so
common.copy /usr/lib/libboost_python37.a
common.copy /usr/lib/cmake/boost_python-1.81.0/libboost_python-variant-static-py3.7.cmake
...updated xx targets...

Build libtorrent from source

lbry-sdk make install requires libtorrent==2.0.6 and installing any
other version from apt repo (like 2.0.8 currently available) won’t work.
Even this version 2.0.6 may change in future, so run something like
grep libtorrent ../lbry-sdk/setup.py to confirm. If it is
different than 2.0.6, change it in instructions below.

cd ..
# change the version if it showed different output on above grep command
git clone --depth 1 -b v2.0.6 https://github.com/arvidn/libtorrent
cd libtorrent
git submodule update --init
sudo apt install -y libboost1.81-tools-dev # for b2

We need a fix
for a rule "version.boost-build" unknown error. Save this in a
file called myfix.patch:

--- Jamfile.orig	2023-02-23 22:43:22.352030368 -0800
+++ Jamfile	2023-02-23 22:43:01.940030266 -0800
@@ -22,6 +22,8 @@
 ECHO "LDFLAGS =" $(LDFLAGS) ;
 ECHO "OS =" [ os.name ] ;
 
+jam-version = [ modules.peek : JAM_VERSION ] ;
+
 if $(BOOST_ROOT)
 {
 	ECHO "building boost from source directory: " $(BOOST_ROOT) ;
@@ -163,10 +165,11 @@
 		# which only works on ELF targets with gcc
 		result += <linkflags>-Wl,--export-dynamic <linkflags>-rdynamic ;
 	}
-	else
+	else if [ version.version-less $(jam-version) : 1990 0 ]
 	{
-		# backtraces don't work with visibility=hidden, so we only add that in
-		# the else-block
+		# the visibility feature was introduced in boost-1.69. This was close to
+		# when the verisoning scheme changed from year to (low) version numbers.
+		# in boost-1.70
 		result += <visibility>hidden ;
 	}
 
@@ -940,8 +943,10 @@
 	# package.paths was introduced in boost-1.70 (2018.02)
 	# however, boost build's versioning scheme changed in boost-1.71 to version
 	# 4.0
-	local boost-build-version = [ SPLIT_BY_CHARACTERS [ version.boost-build ] : "-" ] ;
-	if [ version.version-less [ SPLIT_BY_CHARACTERS $(boost-build-version[1]) : "." ] : 2018 03 ]
+	# so, if versions are 4.0+ we want to use package.paths, but if it's a year,
+	# say 2018, that means it's old and we use the fallback below. Any version <
+	# 1990 is considered the 4.0 and later numbering scheme.
+	if [ version.version-less 1990 0 : $(jam-version) ]
 	{
 		import option ;
 		import property ;

Now apply the patch:

patch -u -b Jamfile -i myfix.patch

Then continue:

make -j 2  # change 2 to cores to use or "cpulimit --limit 100 -- make"

It should end with something like:

gcc.compile.c++ bin/gcc-12/release/address-model-64/cxxstd-14-iso/threading-multi/visibility-hidden/src/pe_crypto.o
gcc.link.dll bin/gcc-12/release/address-model-64/cxxstd-14-iso/threading-multi/visibility-hidden/libtorrent-rasterbar.so.2.0.6
...updated xxxx targets...

Continue:

su -c 'make install'  # Not sudo because it uses system python. So we need su -c.
python3 setup.py build   # if machine gets hot: cpulimit --limit 100 -- python3 setup.py build
su -c 'python3 setup.py install'  # su -c is to use python3.7, not sudo

It should end with something like:

Extracting libtorrent-2.0.6-py3.7-linux-i686.egg to /home/username/Projects/lbry-sdk/lbry-venv/lib/python3.7/site-packages
Adding libtorrent 2.0.6 to easy-install.pth file

Installed /home/username/Projects/lbry-sdk/lbry-venv/lib/python3.7/site-packages/libtorrent-2.0.6-py3.7-linux-i686.egg
Processing dependencies for libtorrent==2.0.6
Finished processing dependencies for libtorrent==2.0.6

Finish lbrynet build

Try this:

cd ../lbry-sdk
# install deps
su -c 'make -j 2 install'  # change 2 to cores to use

To verify:

(lbry-venv) $ which lbrynet
/opt/lbry-sdk/lbry-venv/bin/lbrynet
or perhaps:
/home/username/Projects/lbry-sdk/lbry-venv/bin/lbrynet

Note this path, or just put it in a variable…

lbrynet_orig=$(which lbrynet)

Do not deactivate the lbry-venv yet, because we’ll need it during
building LBRY Desktop.

B. Build LBRY Desktop

I found a useful post
by @Madiator2011 which basically describes the whole process:

You will need to build both lbrynet ( Pyinstaller detect arch of OS and build correct binary) and LBRY App.
Here comes a step by step guide:

	Download source of lbrynet
	Clone LBRY Desktop App
	Copy builded daemon binary to LBRY-Desktop-Folder/static/daemon (you will need create that folder) make sure you give binary executable permision.
	Compile LBRY App
	Enjoy app on 32-bits :smiley:

Prepping the LBRY Desktop source

cd ../  # back to Projects or where you put your repos
# this is cloning master. check the releases page for tags
# and add it. eg. git clone ... -b vX.Y.Z https://github...
git clone --depth 1 https://github.com/lbryio/lbry-desktop
cd lbry-desktop
# https://forum.lbry.com/t/where-to-download-lbry-for-32-bit-linux/69/4
mkdir -p static/daemon
cp $lbrynet_orig static/daemon

sudo apt install -y yarnpkg
yarnpkg  # to install deps. in Devuan "yarn" is run with "yarnpkg".

If you get “Error: Couldn’t allocate enough memory…
at ZipFS.allocateBuffer”, like below:

➤ YN0013: │ yocto-queue@npm:0.1.0 can't be found in the cache and will be fetched from the remote r
➤ YN0001: │ Error: Couldn't allocate enough memory
	at ZipFS.allocateBuffer ([worker eval]:1:41340)
	at ZipFS.allocateSource ([worker eval]:1:41776)
	at ZipFS.setFileSource ([worker eval]:1:42050)
	at ZipFS.writeFileSync ([worker eval]:1:46835)
	at extractArchiveTo ([worker eval]:1:461957)
	at async MessagePort.<anonymous> ([worker eval]:1:463328)
➤ YN0000: └ Completed in 21m 2s
➤ YN0000: Failed with errors in 21m 3s

then try running yarnpkg again.

If this gets inturrupted again and again, try changing yarn mirror.

When it is complete it should say something like:

➤ YN0007: │ highlight.js@npm:9.18.5 must be built because it never has been before or the last one failed
➤ YN0007: │ core-js-pure@npm:3.23.3 must be built because it never has been before or the last one failed
➤ YN0007: │ lbry@workspace:. must be built because it never has been before or the last one failed
➤ YN0000: └ Completed in xxm xs
➤ YN0000: Done with warnings in xxm xxs

Run:

cp .env.defaults .env

Building LBRY Desktop binaries

Run this to build:

yarnpkg dist --linux dir
# fix "Error: Failed to load image from path 'static/img/tray/default/tray.png'" error
cp -rv dist/electron/static dist/electron/linux-ia32-unpacked/
# the above may still not work. let me know in a reply if you know
# how to fix.

Here dir is used. If you want details and options,
check here.
Full list of options are: AppImage, flatpak, snap, deb, rpm, freebsd,
pacman, p5p, apk, 7z, zip, tar.xz, tar.lz, tar.gz, tar.bz2, dir

If download is failing, try (download - How to increase the timeout for `yarn install` - Stack Overflow) add --network-timeout 1000000000:

yarnpkg dist --linux dir --network-timeout 1000000000

To build AppImage:

yarnpkg dist --linux AppImage

To build all:

yarnpkg dist

When done check inside dist directory to see build outputs:

dist/electron/linux-ia32-unpacked : binaries as is without packaging/compression
dist/electron/LBRY_0.53.9.AppImage : AppImage
dist/electron/LBRY_0.53.9.deb : debian .deb package

If you want to use the AppImage, copy LBRY_0.53.9.AppImage somewhere,
for example, ~/bin/, make sure it is executable
(chmod +x LBRY_0.53.9.AppImage) and run it.

You can optionally create
2 dirs named LBRY_0.53.9.AppImage.home and
LBRY_0.53.9.AppImage.config to keep files created by AppImage within
these 2 dirs. When you get a new version, rename the dirs to reflect
the version.

I haven’t tried the .deb since AppImage does what I need already. But
it should be as simple as sudo dpkg -i dist/electron/LBRY_0.53.9.deb
and if any deps have issues sudo apt install -f

Resources:

https://github.com/lbryio/lbry-sdk/blob/master/INSTALL.md

https://trendoceans.com/install-boost-library-for-c/

https://www.linuxcapable.com/how-to-install-python-3-7-on-debian-11-bullseye/

This guide is provided under Creative Commons CC0 1.0 Universal license. Feel free to use it for any purposes, modify it or do almost anything basically.

Just noticed something. I didn’t use $PYVER on certain commands. Sorry about that!

Can’t edit post because not enough trust level, so here are they corrected:

# python headers
sudo ln -s /opt/Python-$PYVER/Include/ /usr/include/python3.7
# for pyconfig to work later during build
cp /opt/Python-$PYVER/pyconfig.h /opt/Python-$PYVER/Include/
# solution to some header related issues (may need to run only once):
...
ln -s /opt/Python-$PYVER/Include/ lbry-venv/include/python3.7  # https://stackoverflow.com/a/45080012

I included comments around them so that it’s easy to find.