Saturday, August 11, 2012

Compiling SQLCipher for Windows

SQLCipher is a great extension to the SQLite library. It can be used to encrypt the database when using the SQLite API. It can be compiled for the major platforms like Linux, Mac OS X, iOS, Android and Microsoft Windows.

It is very simple to compile SQLCipher, except for the Windows case, where it can take some more time to get a working library. I spent some hours to have a static library, and I suppose it might be useful to write it down to accelerate the process for anybody who needs it.

In this thread you can find some information on how to compile SQLCipher for Windows. Instead, I preferred to take a different way: I didn't bother compiling OpenSSL (which is needed to compile SQLCipher), and used cygwin to buil the SQLCipher library linking to OpenSSL.

Download SQLCipher sources

First of all download the SQLCipher sources, with a zip archive or from the git. Uncompress the sources somewhere (I'll refer to this path using <sqlcipher_sources>).

Download the OpenSSL library

You can either compile OpenSSL using the Microsoft compiler or mingw or you can download the library from this website. I'll refer to the path containing the libraries with <openssl_binaries>.

Download and setup cygwin

I used cygwin to compile SQLCipher. Download it from the website. When requested, install at least these packages:

make

nano (in case you need to edit)

tcl: Tool Command Language

gcc-mingw-core

mingw-gcc-core

This should be sufficient.

Compile SQLCipher from the cygwin command line

I used MinGW to compile the sources. First of all set the correct C compiler that make will use to compile the sources:

I'm sure there is a more elegant way of solving this, but simply correcting the command which failed was sufficient for me (the linking order is the cause; any static library or object that depends on other library should be placed before it in the command line, so libeay32.lib should be placed after libsqlite3.a):

You should find the static library in sqlcipher_sources.lib directory, together with the sqlite3 executable.

Building a project linking to libsqlcipher.a

When building a project using the libsqlcipher, I had to link all the necessary libraries in the correct order:

libeay32.lib

libsqlite3.a

libgcc.a

For example, in a Qt project I added this to link to the library:

win32 {

message("Compiling for Windows!")

LIBS += \

$$_PRO_FILE_PWD_/os_specific_windows/3rdparty/lib/libeay32.lib \

$$_PRO_FILE_PWD_/os_specific_windows/3rdparty/lib/libsqlite3.a \

$$_PRO_FILE_PWD_/os_specific_windows/3rdparty/lib/libgcc.a

INCLUDEPATH += 3rdparty/include

}

Windows 7 64bit

After being asked, out of curiosity, I also tried to compile for Windows 7 64bit, and I followed the exact same procedure (I just downloaded and installed the 64bit version of all the libs and cygwin packages). The error during make is:

So it seems that also the library now is failing to compile: maybe something has changed in some tool or in the Makefile, I don't know.
Luckily, sqlite3 uses amalgamation; it is therefore possible to compile manually quite simply. I built the library this way:

I them ran another command i got following error:./.libs/libsqlite3.a(sqlite3.o):sqlite3.c:(.text+0x1ab7): undefined reference to `_EVP_CipherFinal'./.libs/libsqlite3.a(sqlite3.o):sqlite3.c:(.text+0x1acb): undefined reference to `_EVP_CIPHER_CTX_cleanup'./.libs/libsqlite3.a(sqlite3.o):sqlite3.c:(.text+0x1c23): undefined reference to `_PKCS5_PBKDF2_HMAC_SHA1'./.libs/libsqlite3.a(sqlite3.o):sqlite3.c:(.text+0x1cf1): undefined reference to `_PKCS5_PBKDF2_HMAC_SHA1'collect2: ld returned 1 exit status

I don't think I have it anymore, and also you might be using a different SQLCipher version. The line of least resistance might be to simply correct the compile line that is failing. For instance, this is what I just got:

I tried to download the latest version from github (might also be the same I already compiled), followed the steps in the procedure and I got both the static library and the executable. Check again your procedure, I don't know what might be stopping you, sorry.

I tried compiling SQLCipher in Windows 7, I also got similar error as you mentioned in the unresolved symbol. But I am not sure where to change the libeay32.lib at the end. Because in my makefile I do not see such a line. Can you please help.

i686-pc-mingw32-gcc: error: /usr/lib/gcc/i686-pc-mingw32/4.5.2/libgcc.a: No such file or directoryi686-pc-mingw32-gcc: error: ./.libs/libsqlite3.a: No such file or directoryi686-pc-mingw32-gcc: error: /cygdrive/c/OpenSSL-Win32/lib/libeay32.lib: No such file or directory

And inside d.\sqlcipher_sources I do not find the lib directory nor any library, nor any sqlite3 executable, as you mencioned.

thanks to your great preliminary work I've successfully built the static library. I'm trying to use these files in Qt Creator 3, adding LIBS and INCLUDEPATH for the appropriate platform in my .pro-file. I'm trying to load the QSQLCIPHER driver and open/create a unencrypted database, but the driver couldn't be loaded and the database creation fails.I'm going completely out of my mind...