Building and running Signal Desktop on the Librem 5

Here is the story of my efforts to try out Signal on the Librem 5. TL;DR: a bit messy to install, but it does work, to some extent.

A lot of this is based on https://github.com/BernardoGiordano/signal-desktop-pi4/blob/master/install.sh but modified as needed.

This is about the “desktop” version of Signal, the idea being that the Librem 5 is like a regular computer (not Android and not iOS) and therefore the mobile Signal app cannot be expected to work (because that is only for Android or iOS), however Signal Desktop can work.

It is a little tricky because the usual version of Signal Desktop is for the x86_64 architecture, while the Librem 5 has a aarch64 (also called arm64) CPU so we need a aarch64 build of the program.

A word of warning if you are going to try this: the instructions here are my best attempt at putting everything together after getting it to work, I might have missed some part(s). Let me know if it does not work for you, then I will try to add any missing pieces.

Starting from the build instructions at https://github.com/signalapp/Signal-Desktop/blob/development/CONTRIBUTING.md that says “First, you’ll need Node.js which matches our current version”.

Node.js is some large javascript thing which I am not very familiar with, but it turned out that it is straightforward to build, it only takes a long time.

The Node.js version that Signal wants currently is 14.16.0 and the source code is at https://github.com/nodejs/node with instructions at https://github.com/nodejs/node/blob/master/BUILDING.md

To build and install Node.js version 14.16.0 on the Librem 5, we can do this:

git clone https://github.com/nodejs/node.git
cd node/
git checkout v14.16.0
./configure
# Changed to -j2 because -j4 used too much memory
make -j2   # this takes 4-5 hours
sudo make install

After that, we can check it by running node --version which should output the version number “v14.16.0”.
Now the Node.js stuff is installed in /usr/local/bin/node so we can remove the ~/node directory to free up some disk space.

Apart from Node.js another thing we need is the RingRTC library built for arm64. Building that seem to require very much disk space so it the build would not fit on my L5, I resorted to building it on a x86_64 laptop running Debian 11, as follows (mostly taken from the “ringrtc-linux” part in https://github.com/dennisameling/signal-native-deps/blob/main/.github/workflows/build.yaml):

git clone https://github.com/signalapp/ringrtc.git
cd ringrtc
sudo apt-get install -y crossbuild-essential-arm64
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
rustup target add aarch64-unknown-linux-gnu
make electron PLATFORM=unix NODEJS_ARCH=arm64
# the above fails with a suggestion to run the following to fix it:
src/webrtc/src/build/linux/sysroot_scripts/install-sysroot.py --arch arm64
# after that try again, then it works:
make electron PLATFORM=unix NODEJS_ARCH=arm64

Now the file we need has been built, it is at src/node/build/linux/libringrtc-arm64.node
Copy the libringrtc-arm64.node from the Debian 11 computer to the Librem 5.

Now, back on the Librem 5, prepare some things we need for the Signal build (most of this comes from https://github.com/BernardoGiordano/signal-desktop-pi4/blob/master/install.sh):

# Get this git repo that contains a kind of "node" package including a libringrtc-arm64.node file:
git clone https://github.com/lsfxz/signal-ringrtc-node.git
# Copy our own libringrtc-arm64.node file to replace the one that was in the repo
cp libringrtc-arm64.node signal-ringrtc-node/build/linux/libringrtc-arm64.node

The reason the above is needed has something to do with a different glibc version being expected by the libringrtc-arm64.node file that was in that repo, while the libringrtc-arm64.node built in Debian 11 expects the same glibc version that exists on the L5 (glibc 2.31 instead of 2.32 or something).

# better-sqlite3
git clone --depth=1 https://github.com/heftig/better-sqlite3
cd better-sqlite3
# apply patch https://github.com/BernardoGiordano/signal-desktop-pi4/blob/master/better-sqlite3.patch
patch -Np1 -i ../better-sqlite3.patch
cd ..

# libsignal-client
git clone https://github.com/signalapp/libsignal-client.git
cd libsignal-client
npm i -g yarn
yarn install
yarn tsc
mkdir -p prebuilds/linux-arm64
mv ./build/Release/libsignal_client_linux_arm64.node prebuilds/linux-arm64/node.napi.node
cd ..

# libzkgroup
git clone https://github.com/signalapp/signal-zkgroup-node.git zkgroup
git clone https://github.com/signalapp/zkgroup.git libzkgroup
cd libzkgroup
make libzkgroup
cp -av target/release/libzkgroup.so ../zkgroup/libzkgroup-arm64.so
cd ..

Now we can get the Signal-Desktop repo and build it:

git clone https://github.com/signalapp/Signal-Desktop.git
cd Signal-Desktop
# Now modify a few lines in package.json to point to our special versions of some dependencies that we prepared above
sed -r 's#("zkgroup": ").*"#\1file:../zkgroup"#' -i package.json
sed -r 's#("ringrtc": ").*"#\1file:../signal-ringrtc-node"#' -i package.json
sed -r 's#("better-sqlite3": ").*"#\1file:../better-sqlite3"#' -i package.json
sed -r 's#("@signalapp/signal-client": ").*"#\1file:../libsignal-client"#' -i package.json
# Apply patch https://github.com/BernardoGiordano/signal-desktop-pi4/blob/master/yarn.lock.patch
patch yarn.lock < ../yarn.lock.patch
# Get dependencies and do a production build
sudo yarn install
sudo yarn generate
sudo yarn run-s --print-label build:grunt build:typed-scss build:webpack
sudo SIGNAL_ENV=production yarn build:electron --arm64 --linux --dir --config.directories.output=release

This gives the “signal-desktop” executable in Signal-Desktop/release/linux-arm64-unpacked/signal-desktop and we can run it from there. What I did was to create a small wrapper script with the full path to the executable and then put the wrapper script in /home/purism/run and then open the terminal app and run it as ./run and then Signal starts. First it showed the QR code to link to a “primary mobile device” (because Signal folks decided that only Android or iOS can be “primary” devices, silly but that’s how it is). I linked to an Android phone and then could communicate back and forth using “note to self” in Signal. It looks like this:

This was after changing the display scaling setting in phosh to 100% (meaning double the normal screen resolution), otherwise it does not fit very well. I suppose one possible quick-and-dirty fix for that would be to simply reduce the width of the left panel which otherwise takes almost the whole screen width, but I did not try that yet.

The build procedure above is unfortunately quite complicated, but it’s the best I could come up with at the moment. If you know a better and/or easier way, please comment. :slight_smile:

16 Likes

Loved. Then unloved. And then loved again so I could love it twice. Great job! Can’t wait to try it!

3 Likes

Guess it might defeat the purpose (not desktop Signal client), but if you wanted to try another method Waydroid + Signal has been reported to work on the PinePhone so I don’t see why it couldnt on the Librem5 - https://github.com/waydroid/waydroid

Article of one users experience here - https://www.kirsle.net/waydroid-on-the-pinephone-is-a-game-changer

This also looks interesting if you like the terminal and don’t need all of Signal’s features (has not implemented them all yet) - https://github.com/boxdot/gurk-rs

3 Likes

Thanks for testing @Skalman
I am also impressed how far waydroid has already come. And that it can run that good on a (low powered) pinephone.

  • Once warmed up, it runs fast! After that first app launch it works really well! Launching a new Android app has the app window appear within just a couple of seconds. I was easily able to run ~6 Android apps or so at the same time without the phone showing signs of being burdened yet. I haven’t stress tested how far I can push that, though.
  • Scrolling and animations are “smooth” - not as fast and snappy as a flagship Android phone, but not as slow and choppy as some Linux apps either! Twitter for Android is very usable where all the other options on the Pinephone were sub-par (Firefox struggles on their mobile site, Chromium is better but has its own rendering issues and blurry text, etc.)

Being able to use some android apps will make my L5 a daily driver from the start. :slight_smile:

Well, I guess what they want to express is that you need a SIM. Maybe the desktop version can be tweaked in that direction. (Or someone builds a monstrosity that runs the Waydroid version automatically in the background only to enable the desktop version :stuck_out_tongue:)

I tried to follow your guiding, but it stopped at the start because this was missing:

sudo apt install python3-distutils
sudo apt install g++

./configure
Node.js configure: Found Python 3.9.2...
INFO: configure completed successfully

Now it is compiling with make -j2

1 Like

With arm64 becoming more common in laptops as well (PineBook Pro, new Apple MacBooks), I’m hoping that Signal upstream at some point provides arm64 builds themselves. This is great in the meantime though.

I was reading in advance through your guide about the RingRTC library … I have no Debian system to build this (only FreeBSD and Ubuntu). In the L5 there are 22 GByte free, isn’t this enough? If not, can you share this lib somehow for the L5? If not, I could stop the 5 hour building of node.js :frowning: Thanks.

Sadly at present waydroid does not work on the Librem 5. Just tested this morning. Causes the gui to lock up. https://github.com/waydroid/waydroid/issues/158

I’ve found the axolotl arm64 build for mobian to work reasonably well for my own Signal needs. The QT UI isn’t ideal and has some quirks (in particular with different QT apps fighting for keyboard input sometimes) but it does work and does fit.

4 Likes

Thanks for testing, I hadn’t seen a lot of discussion over it with the Librem5 - I know others will appreciate your link!

I’m now stuck in this:

purism@pureos:~/guru/ringrtc$ make electron PLATFORM=unix NODEJS_ARCH=arm64
Electron: Preparing workspace for unix
Downloading WebRTC dependencies to /home/purism/guru/ringrtc/src/webrtc from version 4389k
/home/purism/guru/ringrtc/bin/gsync-webrtc: 33: gclient: not found
make: *** [Makefile:75: electron] Error 127

Which pkg provides this gclient?

It’s part of something called “depot_tools” which I forgot to mention, you can get that by cloning https://chromium.googlesource.com/chromium/tools/depot_tools.git and then add the path to your PATH env variable. I don’t know if there is any debian package that provides, maybe there is, probably something related to chromium development then because depot_tools is according to the readme file “Tools for working with Chromium development”.

For me, 22 GB did not seem to be enough, but you can always try. You could also try adding extra storage to your L5, either put in a microSD card or attach an external USB drive and do the build on that disk space.

I could, but I’d like to avoid it, from a security perspective we should avoid using random binaries shared by random forum members such as myself. :slight_smile:

The make fetched with a lot of git processes for some 3 hours some 10 Gb of sources before starting compilations. I stopped it and will look for an external disk.

With the external disk the problem will be the supply of power for that many hours of download and building. Does the make allow to interrupt w/o starting from scratch again?

I thought again and better and will not proceed with building signal from 10 Gbyte sources from Google from which nobody knows what it might contain.

Signal is not good program if you are trying to use de-googled phone. The last time I tried to side-load the apk file it refused to start because I didn’t have Google-play services running.

I think that if you have Google Play Services installed, Signal requires it to be running, but if Google Play Services are not installed, then Signal should work.

2 Likes

I’ve got a LineageOS 18.1 de-googled Pixel 4a running signal app no problem since it uses MicroG instead of GAPPS which is the simple solution.

1 Like

Dont have a screenshot but on my last phone with all the Google apps disabled via ADB the Signal apk (official download) gave me a popup that it would still try to use Google Play Services since it was detected.

On my current phone without Google at all the apk works fine (runs the notification service in the background)

1 Like

But this fails to install:

sudo apt install ./axolotl_1.0.5-1_arm64.deb
[sudo] password for purism: 
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Note, selecting 'axolotl' instead of './axolotl_1.0.5-1_arm64.deb'
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 axolotl : Depends: libc6 (>= 2.32) but 2.31-13 is to be installed
E: Unable to correct problems, you have held broken packages.
1 Like