This is the second 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 UWP as the target.
Couchbase Lite should work on any version of Windows 10 over build 10240 on x86, x64, and ARM (As of this writing there is a very irritating ARM bug that I am having trouble getting around, but other than that things are fine). It is .NET Native compatible, and passes WACK certification. As I laid out in a previous entry, this means that we need native builds for each of these architectures.
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 a Visual Studio 2015 project (it could also generate 2017, but I am hesitant to move it just yet). The build consists of two steps:
- Run CMake
- Run msbuild
Running CMake means running this command from any Command or Powershell prompt:
& 'C:\Program Files\CMake\bin\cmake.exe' -G "Visual Studio 14 2015 <arch>" -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.14393.0 <path/to/source>
<arch> can be either blank (for x86), Win64 (for x64) or ARM (for ARM 32-bit). -DCMAKE_SYSTEM_NAME triggers CMake to generate a UWP build instead of a Windows desktop build, and -DCMAKE_SYSTEM_VERSION indicates the version of the SDK to use. This is important because versions above 10.0.14393.0 are not supported by Visual Studio 2015 and by default CMake will pick up the highest version installed. Each architecture needs its own folder, but after that you can run the same command in each folder to build. You have one of two choices. You can either run the following from a developer command prompt
msbuild LiteCore.sln /p:Configuration=RelWithDebInfo /t:LiteCore
Or you can run the following from a normal command or powershell prompt
& 'C:\Program Files\CMake\bin\cmake.exe' --build . --target LiteCore --config RelWithDebInfo
After that you will find the two final products in the RelWithDebInfo folder: LiteCore.dll and sqlite3.dll (may become sqlcipher.dll later).
At the .NET level there are two relevant projects: Couchbase.Lite and Couchbase.Lite.Support.UWP. The former is a .NET Standard 1.4 library which contains the majority of the logic for the library and the latter is a UWP class library which houses the native builds created above as well as some support classes which are injected into the main library.
Warning: If this library is Nuget packaged it will automatically include the native libraries into your application but as a project reference Visual Studio will not copy the LiteCore native libraries from the Couchbase.Lite.Support.UWP to a UWP application despite them being marked as ‘Content’ which I think is a flaw in Visual Studio 2015. If you reference the project you will need to add the relevant LiteCore dlls to your application directly.
The support project expects the native libraries in the following directories:
- x86: vendor\couchbase-lite-core\build_cmake\x86_store\RelWithDebInfo\
- x64: vendor\couchbase-lite-core\build_cmake\x64_store\RelWithDebInfo\
- ARM: vendor\couchbase-lite-core\build_cmake\ARM\RelWithDebInfo\
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-uwp.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 ;).