-
Notifications
You must be signed in to change notification settings - Fork 49
Providing your own Libsodium
Let's say you're interested in building for Mac, Windows. Linux and Android. This means you need 4 files:
- Mac:
libsodium.dylib
..dylib
means shared library for MacOS. - Windows:
libsodium.dll
..dll
means shared library for Windows. - Linux:
libsodium.so
..so
means shared library for Linux and Android. - Android:
libsodium.so
..so
means shared library for Linux and Android.
Well, the Windows libsodium.dll
is provided for you in the mingw releases. Easy π
But if you really want to compile it, you'll have to download extra dependencies using sudo apt-get
or whatever your package manager is. Then run the Windows build scripts in the build
folder.
$ ./configure
$ cd build
$ ./msys2-win64
Or you can use Zig to cross compile this: https://libsodium.gitbook.io/doc/installation#compiling-with-zig
Get the latest stable release. Gain access to a Linux machine and compile it on there using:
$ ./configure
$ make && make check
$ sudo make install
Then it should appear somewhere installed under the directory /usr/
.
Or you can use Zig to cross compile this: https://libsodium.gitbook.io/doc/installation#compiling-with-zig
Get the latest stable release. You can cross compile for Mac on Linux by running ./dist-build/osx.sh
. Or if you have a Mac and have Homebrew then just run:
$ brew install libsodium
In the installation output, take note of where it installs libsodium.dylib
.
You can use Zig to cross compile this: https://libsodium.gitbook.io/doc/installation#compiling-with-zig
Get the latest stable release. You can cross compile for Android on Linux by running ./dist-build/android-<abi>.sh
, where <abi>
is the name of the ABI you want to generate a libsodium.so
file for. (It's recommended to build each one).
$ ./dist-build/android-arm.sh
$ ./dist-build/android-armv7-a.sh
# etc...
After compiling Libsodium you have to make sure that the resulting files libsodium.so/libsodium.dylib/libsodium.dll
(i.e the native libraries) are accessible by your Java or Android program. There are mainly 3 methods that you can use to make your freshly compiled native Libsodium files accessible:
- On program start-up, copy them to a temporary location, then load them. This is actually the method used in Lazysodium for Java when calling
new SodiumJava()
. - Set
java.library.path
. This is a well recognised environment variable in Java programs suitable for pointing to the location of your native files. This environment variable may not be available on Android. - Make your build tool (such as Gradle or Maven) look for them in specific folders.
Point 1. Lazysodium for Java has actually placed the native library files within the resources
folder and as soon as SodiumJava()
is created, we load the relevant native library depending on the platform we're on. This process is mentioned in point 1 in the list above.
// Loading different native libraries depending on
// the platform
private String getLibSodiumFromResources() {
String path = getPath("windows", "libsodium.dll");
if (Platform.isLinux() || Platform.isAndroid()) {
path = getPath("linux", "libsodium.so");
} else if (Platform.isMac()) {
path = getPath("mac", "libsodium.dylib");
}
return path;
}
Here's what the resources folder looks like:
src/main/resources
βββ mac/
β βββ libsodium.dylib
βββ linux/
β βββ libsodium.so
βββ windows/
β βββ libsodium.dll
Point 2 is quite simple but there are many ways of doing it such as setting environment variables in your .bashrc
or export
ing them. Seek and you shall find.
Point 3 is difficult if you are JAR'ing your application, but relatively simple otherwise. (See the Quirks section). Lazysodium dropped this method of loading the its native library files in favour of loading them via copying (point 1) as it was more reliable and did not cause exceptions. We were loading via relative paths but it failed within JARs.
We found that point 3 (see above for the points) worked well for Android. If you want to use your compiled native library files within Android instead of Lazysodium's, then create the folder:
src/main/jniLibs
Then, add the following to the android
block in your app level build.gradle file:
android {
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
Then in your jniLibs
folder make sure you have all the Android ABIs listed as folders in there. Within each ABI folder, you need the libsodium.so
files that was compiled against that ABIs (see above). Once you've done that, rename those libsodium.so
files to something like libmysodium.so
Then initialise a Lazysodium object as follows:
final LazySodium lazySodium = new LazySodium(new SodiumAndroid("mysodium"));
This will load your renamed native library files rather than Lazysodium's pre-included compiled native files. The renaming overrides the loading of Lazysodium's libsodium.so
files. After this, you can now use LazySodium
as usual.
At the end of everything you should have a directory structure as follows:
app/src/main/jniLibs/
βββ arm64-v8a/
β βββ libmysodium.so
βββ armeabi/
β βββ libmysodium.so
βββ armeabi-v7a/
β βββ libmysodium.so
βββ x86/
β βββ libmysodium.so
βββ x86_64/
βββ libmysodium.so
Congratulations, you now have compiled, included and loaded your own Libsodium native library.
When you've compiled your own Libsodium you have to watch out for certain things.
If you want to bundle native libraries inside a JAR then you have to copy the native libs to a temporary location first (this is the method outlined in point 1 in the bulleted list in the previous section). We have performed this action via a utility class:
NativeUtils.loadLibraryFromJar();
This is because finding a path to the native libraries inside a JAR is difficult. So we move the native library files to a temp location and then load them from there. We found that loading the libraries this way is the most reliable. See the Java block in the previous section.