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.