This is the third entry in an ongoing series about building Couchbase Lite .NET from source. As I mentioned in a previous post, I am too close and familiar with the library and I often forget that it is complicated and annoying to build without the amount of full time work that I have spent with it. This entry will feature Xamarin Android as the target.
As of the time of this writing the exact supported versions for Android are not entirely finalized but it is looking like Android 4.1+. Any version of Xamarin Android should work to build this but I tend to keep on a fairly modern version of it. However, as I mentioned in a previous post we need to build native components. We have chosen to support three Android architectures based on the popularity of devices: x86, armeabi-v7a, and arm64-v8a. That means that a native build is required for each.
The native build makes use of CMake, which is a tool to generate various types of projects. CMake is not a tool for directly building, but rather for setting things up to build. In this case, it will generate Unix Makefiles (this build is untested on Windows, as CMake for Android on Windows is rather complicated).
The build consists of two steps:
- Run CMake
- Run Make
Running CMake means running this command
cmake -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_NDK=<path/to/ndk> \ -DCMAKE_ANDROID_ARCH_ABI=<arch> -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \ -DCMAKE_SYSTEM_VERSION=<version> -DCMAKE_ANDROID_STL_TYPE=c++_static -DCMAKE_BUILD_TYPE=MinSizeRel \ <path/to/source>
Let’s go through what this means. -DCMAKE_SYSTEM_NAME informs CMake that we want to generate a project that uses the Android NDK toolchain. -DCMAKE_ANDROID_NDK specifies the path to the NDK toolchain. -DCMAKE_ANDROID_ARCH_ABI is the architecture being built for (one of the three I mentioned above). -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION specifies which C++ compiler to use (GCC vs clang basically). We have chosen clang to align with our other builds and because Google has deprecated GCC. -DCMAKE_SYSTEM_VERSION is either 16 for x86 / armeabi-v7a or 21 for arm64-v8a (The first version this architecture was available in). The reason it is 16 is because originally the plan was to support API 16+, but if it changes we may switch to 19 (Having a lower version than what you support won’t hurt usually unless you want to use newer features). -DCMAKE_ANDROID_STL_TYPE=c++_static specifies which C++ standard library to use (there are several to choose from, but we chose libc++ because we found that the old version of libstdc++ included with the NDK was not good enough at C++11). -DCMAKE_BUILD_TYPE=MinSizeRel specifies to make as small a release as possible (and there are issues with the other ones which cause crashing at runtime so we can’t avoid using this mode for now).
That certainly is a lot of options, but the next step is much easier. To run Make all you have to do is:
make -j8 LiteCore # Or whatever degree of parallelism you want
Note that each architecture requires its own folder. After that you will be able to find the two final products: libLiteCore.so and libsqlite3.so (may becomes libsqlcipher.so later).
At the .NET level there are two relevant projects: Couchbase.Lite and Couchbase.Lite.Support.Android. The former is a .NET Standard 1.4 library which contains the majority of the logic for the library and the latter is a Xamarin Android class library which houses the native builds created above as well as some support classes which are injected into the main library. The support library expects the native libraries in the following directories:
- x86: vendor\couchbase-lite-core\build_cmake\android\lib\x86
- armeabi-v7a: vendor\couchbase-lite-core\build_cmake\android\lib\armeabi-v7a
- arm64-v8a: vendor\couchbase-lite-core\build_cmake\android\lib\arm64-v8a
If you are looking to package, the nuspec files are all in the packaging/nuget directory. The nuspec files are not set up to build from source so you need to build everything first. After that you can take some cues from the do_package.bat script and run the following:
nuget pack couchbase-lite.nuspec /BasePath ..\.. /Properties version=2.0.0 nuget pack couchbase-lite-support-android.nuspec /BasePath ..\.. /Properties version=2.0.0
This will output two Nuget packages and they will be the same as what you find in whatever Nuget feed you acquire Couchbase Lite from.
Warning: Due to a Nuget bug, the nuspec files must change the paths from using backslash ( \ ) to using forward slash ( / ) if Nuget is run on a non-Windows machine. It sucks, but there is nothing I can do about that.
Hopefully this article will be useful for anyone attempting to build from source, as I encourage everyone to do since this is an open source product and the fastest way to get an issue fixed is to point out as specifically as possible where it is ;).