sqlitestatic-linkinglazarus

Static link sqlite in Lazarus


I am building an application with Lazarus where I use a sqlite database to store thousands of records. Right now I am linking to the sqlite library dynamically via the sqlite3.dll.

Is it possible to link to it statically? Where can I find the Lazarus compatible lib file to do that?

Note: I only started using Lazarus and Free Pascal a month ago so something that might look very obvious to one, might not be for me. So bear with me a bit.

Cheers


Solution

  • Actual static linking is difficult since the TSQLite3Connection component is inherently designed to actively load the SQLite3 DLL. In other words, it's not linking against the library when you compile the program, the component is coded to dynamically load the DLL at run time.

    If you are looking to have a totally self contained program, then you can accomplish this two different ways.

    1. Create a new TSQLite3Connection component that links statically against sqlite3 instead of loading the DLL dynamically.
    2. Include the sqlite3.dll as a resource in your program and have your program automatically deploy it before it runs.

    Solution #1 is not trivial and not for the faint of heart. I've done it, and I intended to include a link to the component, but the result isn't stable. The problem is that you have to compile a static version of sqlite3, which isn't a real problem, but you have to do it with something like gcc under MinGW and that introduces issues. Compiling with gcc under MinGW means you have to then link in libgcc.a, and because FreePascal's internal linker doesn't know how to interpret stdcall symbols properly, you also have to link against MinGW's libkernel32.a, and libmsvcrt.a. The result just isn't stable. Crashes galore.

    Solution #2 should be fairly easy, but the Lazarus maintainers make it a little hard. The part where you store the dll inside the executable as a resource is easy enough to do. And so is writing it out as a temp file. The problem is that you can't tell the TSQLite3Connection component where to find it after. So it looks in the executable's folder, or in system folders. Neither of which can necessarily be written to by the executable. The only place you can guarantee that your program will be able to write to is a temp folder. So what I did is created a new version of TSQLite3Connection component call TSQLite3DynConnection, meaning you can dynamically specify where the DLL is. I made a published property called ClientLibrary where you can specify the location of the dll (it doesn't have to end in .dll, so you can use system temp filename generation routines). You can get this component at: https://icculus.org/~kfitzner/misc/sqlite3dyndll.zip. It will compile against Lazarus 1.6.2 FP 3.0.0, or FP 1.0.6 / FP 2.6.0, which are the two versions I use.

    I'll update this answer if I can get the statically linked version stable.

    2 Dec 2016 update: I managed to get a static version stable.