Skip to content

Provide native lib for libsignal

Markus Ueberall edited this page Oct 14, 2024 · 50 revisions

Native libraries

signal-cli depends on the libsignal-client library. It is a rust library and needs to be compiled for a specific processor architecture and operating system that it will be used on.

signal-cli releases include the pre-compiled binaries for x86_64 Linux (with a recent enough version of glibc, see #643), Windows and macOS. For other platforms the library needs to be compiled from source.

Pre-built

Builds for some additional platforms are available in

  • https://github.com/exquo/signal-libs-build/
    • Linux:
      • amd64/x86_64 (variant 1 requires glibc v2.28 or newer, variant 2 requires musl libc)
      • arm64/aarch64, armv7, i386 (these require glibc v2.29 or newer)
    • macOS: amd64/x86_64, arm64/aarch64 (these require Darwin v14 or newer)
    • Windows: amd64/x86_64
  • https://gitlab.com/packaging/libsignal-client/
    • Linux:
      • amd64/x86_64 (requires glibc v2.17 or newer)
      • arm64/aarch64, armv7 (these require glibc v2.28 or newer)
  • https://media.projektzentrisch.de/temp/signal-cli/
    • Linux: amd64/x86_64, arm64/aarch64, armv7, i686, loong64, mips64, mips64el, mips, mipsel, powerpc, ppc64, ppc64el, riscv64, s390x, sparc64
      • all artefacts require glibc v2.29 (riscv64: v2.28; loong64: v2.36) or newer
  • https://media.projektzentrisch.de/temp/signal-cli/tests/
    • Artefacts that require musl instead of glibc (only briefly tested in Alpine Linux containers):
      • libsignal_jni_soNNNN_ubuntu2004_{amd64,i686,arm64,armv7,ppc64el,riscv64,s390x}-musl.gz
    • Artefacts cross-built against header files and libraries of previous, still supported Ubuntu LTS releases:
      • libsignal_jni_soNNNN_ubuntu1804_{powerpc,ppc64,ppc64el,riscv64}.gz (these require glibc v2.27 or newer)
      • libsignal_jni_soNNNN_ubuntu1804_{amd64,i686,arm64,armv7,mips64,mips64el,mips,mipsel,s390x,sparc64}.gz (these require glibc v2.25 or newer)
      • libsignal_jni_soNNNN_ubuntu1604_{ppc64,ppc64el}.gz (these require glibc v2.22 or newer)
      • libsignal_jni_soNNNN_ubuntu1604_{amd64,i686,arm64,armv7,mips64,mips64el,mips,mipsel,powerpc,s390x,sparc64}.gz (these require glibc v2.18 or newer)
    • Artefacts cross-built against header files and libraries of the unsupported older Ubuntu release 13.10:
      • libsignal_jni_soNNNN_ubuntu1310_arm64.gz (requires glibc v2.17 or newer)
      • libsignal_jni_soNNNN_ubuntu1310_{amd64,armv7,i686}.gz (these require glibc v2.16 or newer)

Manual build

Dependencies

  • JDK
  • gradle
  • rust (Guide here)
  • protocol buffer compiler ("apt install protobuf-compiler")

Download libsignal-client source

Clone libsignal-client with git, or download the "Source code" file from the releases page (see below for choosing the version from the releases).

Determine the required libsignal-client version

Every signal-cli release requires a specific version of libsignal-client. The version number is a part of a libsignal-client-<VERSION>.jar filename in signal-cli's lib directory. For instance, for signal-cli v0.10.5, the file is

signal-cli-0.10.5/lib/libsignal-client-0.15.0.jar

This is the file path if you have downloaded a signal-cli release. If you have built signal-cli from source, the path will be

signal-cli/build/install/signal-cli/lib/libsignal-client-0.15.0.jar

So the required libsignal-client version is 0.15.0.

Build

Once everything is setup, navigate to the root of the libsignal-client codebase:

$ cd java
$ # Prevent building the android library
$ sed -i "s/include ':android'//" settings.gradle
$ ./build_jni.sh desktop

Then the native lib can be found in the libsignal-client sub-directory: target/release/libsignal_jni.so (the file extension will be .dylib on MacOS and .dll on Windows, instead of .so).

Using the new libsignal-client lib file

Once you have your library file, it can be bundled in the root of the libsignal-client-*.jar file (but only for one architecture at a time).

First, the currently bundled file needs to be removed:

zip -d signal-cli/lib/libsignal-client-*.jar libsignal_jni.so

For signal-cli to be able to use the newly compiled library file, it can either be bundled into the .jar file with

zip signal-cli/lib/libsignal-client-*.jar libsignal_jni.so

or be placed on the Java library path (see below). Only if there is no bundled file will libsignal search the library path (java.library.path) for the .dylib/.so/.dll file.

Note: on Windows, bundling the compiled signal_jni.dll file does not seem to work: see #517. (According a comment in that thread, bundling does work if the files are renamed).

Java library path

Finding the default java.library.path

You can run the following command to get the value of java.library.path on your system:

java -XshowSettings:properties -version 2>&1 | grep java.library.path

Note that there may be multiple paths to choose from, they are separated with a colon.

Overriding java.library.path

If your java.library.path doesn't have any usable paths or you wish to not use the system defaults, then you can override the paths by modifying the final line of build/install/signal-cli/bin/signal-cli

JAVA_LIBRARY_PATH="-Djava.library.path=/your/java/library/path"
exec "$JAVACMD" "$JAVA_LIBRARY_PATH" "$@"

Make sure to place your .dylib/.so/.dll file in that folder. Be aware that this method isn't ideal since if you rebuild signal-cli, then the script may be regenerated and you'll need to set this again.