* * *

Author Topic: [SOLVED] How to distribute a 64-bit and 32-bit version of SQLite with my program  (Read 1507 times)

Gizmo

  • Hero Member
  • *****
  • Posts: 634
    • http://www.quickhash-gui.org
I've read this (http://forum.lazarus.freepascal.org/index.php?topic=35362.0) and a few other threads (http://forum.lazarus.freepascal.org/index.php?topic=19238.0) but up-to-date direction still seems to be evading me.

I've re-written a program of mine to use SQLite and for the Windows side, it's working great. I have the Windows SQLIte DLL in the same folder as the compiled exe, and it works fine. I have the following compiler ifdef in my code:

Code: Pascal  [Select]
  1. {$IFDEF Windows}
  2.        // Ensure we're using the local sqlite3.dll for Windows
  3.        SQLiteDefaultLibrary := 'sqlite3.dll';
  4.      {$ENDIF}
  5.        {$IFDEF Darwin}
  6.          SQLiteDefaultLibrary := 'sqlite3-osx'; // Use an OSX version of SQLite
  7.        {$else}
  8.          {$IFDEF UNIX and !$ifdef Darwin}
  9.            SQLiteDefaultLibrary := 'sqlite3-linux'; // Use a Linux version of SQLite.
  10.          {$ENDIF}
  11.      {$ENDIF}
  12.  
  13.  if FileExists(SQLiteDefaultLibrary) then
  14.      begin
  15.        // Set the filename of the sqlite database
  16.        SQLite3Connection1.DatabaseName := 'DBName.sqlite';
  17.        // Create the database
  18.        CreateDatabase(SQLite3Connection1.DatabaseName); // THROWS ERROR HERE
  19.        if SQLIte3Connection1.Connected then lblConnectionStatus.Caption:= 'SQLite3 Database connection active';
  20.      end
  21.        else ShowMessage('Cannot create SQLite database. Ensure an SQLite.dll or equivalent file exists');
  22.  

So when I ran this on my Linux system last night, I got
Quote
Project raised exception class 'EInOutError' with message: Can not load SQLite client library "sqlite-linux". Check your installation

The line that triggers that error is in another procedure where my program creates a new SQLite database. The line "SQLite3Connection1.Open" is what throws it, and no new database file is created. Suggesting it can't connect to, or even create, the new database. Yet the same code on Windows creates a new sqlite database file.

I am running 64-bit Linux Mint 17 and Lazarus 1.6.4 and FPC 3.0.2, installed via the deb packages for 64-bit Linux systems. The SQLite compiled binary I am using is from http://sqlite.org/2017/sqlite-tools-linux-x86-3210000.zip. There only seems to be one compiled version for Linux, which I suspect may be the issue....i.e. the version is perhaps compiled for 32-bit Linux and not 64 bit Linux, but the fact they have only provided the one made me assume it was generic that would work on both. 

Anyway, what I want to know is, given that most Linux distros have SQLite installed anyway, how can I fairly reliably code my program to look for the users copy of SQLite and then use that. Or, better still, how can I package a 64-bit and 32-bit version of SQLite for inclusion with my compiled binary? Or is this error related to something else entirely!!?

Many thanks
« Last Edit: November 22, 2017, 12:30:38 am by Gizmo »
Lazarus 1.6.4 and fpc 3.0.2 - Linux Mint 17 LTS, Windows 7 and Mac Yosemite
Useful Page to remember : http://wiki.freepascal.org/Cross_compiling#From_Linux_x64_to_Linux_i386

Gizmo

  • Hero Member
  • *****
  • Posts: 634
    • http://www.quickhash-gui.org
Re: How to distribute a 64-bit and 32-bit version of SQLite with my program
« Reply #1 on: November 16, 2017, 03:41:14 pm »
OK.

SQLiteDefaultLibrary I notice is a variable (https://github.com/graemeg/freepascal/blob/master/packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp). Does it somehow lookup the path to the default sqlite program on whatever host it is running? So do I need to specify a file at all?

Alternatively, given that SQLIte is distributed with most modern Linux distributions anyway, what way are people using to lookup the SQLIte path for the distro in which their program finds itself running? How do the likes of Firefox and Chrome achieve this. Both of which use SQLIte massively.
Lazarus 1.6.4 and fpc 3.0.2 - Linux Mint 17 LTS, Windows 7 and Mac Yosemite
Useful Page to remember : http://wiki.freepascal.org/Cross_compiling#From_Linux_x64_to_Linux_i386

molly

  • Hero Member
  • *****
  • Posts: 2343
Re: How to distribute a 64-bit and 32-bit version of SQLite with my program
« Reply #2 on: November 16, 2017, 04:53:37 pm »
hi Gizmo,

Perhaps this wiki-page and this thread might be able to help you out a bit.

mig-31

  • Full Member
  • ***
  • Posts: 228
Re: How to distribute a 64-bit and 32-bit version of SQLite with my program
« Reply #3 on: November 16, 2017, 05:11:23 pm »
It's simple.
There is POSIX standard = sqlite.so must be is in /usr/lib 32-bit and /usr/lib64

Lazarus 1.6 - Linux 32/64 bit, win32

molly

  • Hero Member
  • *****
  • Posts: 2343
Re: How to distribute a 64-bit and 32-bit version of SQLite with my program
« Reply #4 on: November 16, 2017, 05:27:30 pm »
In addition to mig-31's answer have a look at this wiki article.

That's why i mentioned TSQLDBLibraryLoader, e.g. for those cases that you disagree with (or for whatever reason, can't use) the order as described.

Gizmo

  • Hero Member
  • *****
  • Posts: 634
    • http://www.quickhash-gui.org
Re: How to distribute a 64-bit and 32-bit version of SQLite with my program
« Reply #5 on: November 20, 2017, 11:11:53 pm »
Thanks guys.

So, to simply bundle and use pre-compiled binaries that I ship with the exe, would this work and be sensible or a bad idea?

Code: [Select]
  SQLDBLibraryLoader1.ConnectionType:='SQLite3';
  {$ifdef windows}
    SQLDBLibraryLoader1.LibraryName := 'sqlite-win.dll';
{$else}
  {$ifdef darwin}
     SQLDBLibraryLoader1.LibraryName := 'sqlite-osx';
  {$else}
    SQLDBLibraryLoader1.LibraryName := 'sqlite-linux';
  {$endif}
{$endif}
  SQLDBLibraryLoader1.Enabled := true;
  SQLDBLibraryLoader1.LoadLibrary;
Lazarus 1.6.4 and fpc 3.0.2 - Linux Mint 17 LTS, Windows 7 and Mac Yosemite
Useful Page to remember : http://wiki.freepascal.org/Cross_compiling#From_Linux_x64_to_Linux_i386

molly

  • Hero Member
  • *****
  • Posts: 2343
Re: How to distribute a 64-bit and 32-bit version of SQLite with my program
« Reply #6 on: November 21, 2017, 12:58:35 am »
@Gizmo:
afaik the safest way would be to use full path names, since you are shipping your own you also know where they are located exactly. You could even opt for a config file that allows to override your 'static' used defaults.

PS: if i remember correctly then the loadlibrary method is called automatically when enabled is set to true (even though the wiki calls this method explicitly in the example).
« Last Edit: November 21, 2017, 01:06:00 am by molly »

Gizmo

  • Hero Member
  • *****
  • Posts: 634
    • http://www.quickhash-gui.org
Re: How to distribute a 64-bit and 32-bit version of SQLite with my program
« Reply #7 on: November 22, 2017, 12:30:24 am »
Thank you Molly, for the tip re SQLDBLibraryLoader. Using three instances of that for each OS (to save a single one being adjusted when compiled on different platforms), I've created a working cross platform system that can utilise SQLite, without any fellow coders having to reconfigure the SQLDBLibraryLoader object .

Try as I might, I couldn't get local downloaded pre-compiled versions to work with Linux and OSX. So by querying the default paths on both platforms, and given that both pretty much all (at least most) modern Linux distros and OSX versions come with SQLite, the code below should work for most users I hope. It works on all three of my systems anyway. For Windows users, I ship the DLL.

Code: Pascal  [Select]
  1. {$ifdef windows}
  2.     SQLDBLibraryLoaderWindows.ConnectionType:='SQLite3';
  3.     if FileExists('sqlite3-win.dll') then
  4.     begin
  5.       SQLDBLibraryLoaderWindows.LibraryName := 'sqlite3-win.dll';
  6.       SQLDBLibraryLoaderWindows.Enabled := true;
  7.       SQLDBLibraryLoaderWindows.LoadLibrary;
  8.       // Set the filename of the sqlite database
  9.       SQLite3Connection1.DatabaseName := 'QuickHashDBWin.sqlite';
  10.       // Create the database
  11.       CreateDatabase(SQLite3Connection1.DatabaseName);
  12.       if SQLIte3Connection1.Connected then lblConnectionStatus.Caption:= 'SQLite3 Database connection active';
  13.     end
  14.     else
  15.     begin
  16.       ShowMessage('Cannot create SQLite database. Ensure you extracted the sqlite-win.dll file from the zip file');
  17.       exit;
  18.     end;
  19.   {$else}
  20.     {$ifdef darwin}
  21.     SQLDBLibraryLoaderOSX.ConnectionType:='SQLite3';
  22.     // OSX sqlite file is a dynamic lib libsqlite3.dylib
  23.     if FileExists('/usr/lib/libsqlite3.dylib') then
  24.     begin
  25.       SQLDBLibraryLoaderOSX.LibraryName := '/usr/lib/libsqlite3.dylib';
  26.       SQLDBLibraryLoaderOSX.Enabled := true;
  27.       SQLDBLibraryLoaderOSX.LoadLibrary;
  28.       // Set the filename of the sqlite database
  29.       SQLite3Connection1.DatabaseName := 'QuickHashDBOSX.sqlite';
  30.       // Create the database
  31.       CreateDatabase(SQLite3Connection1.DatabaseName);
  32.       if SQLIte3Connection1.Connected then lblConnectionStatus.Caption:= 'SQLite3 Database connection active';
  33.     end
  34.     else
  35.     begin
  36.       ShowMessage('Cannot create SQLite database. Is SQLite installed?');
  37.       exit;
  38.     end;
  39.     {$else}
  40.      // If it's 64-bit Linux, use the 64-bit SQLite3 install
  41.     if FileExists('/usr/lib/x86_64-linux-gnu/libsqlite3.so.0') then
  42.       begin
  43.         SQLDBLibraryLoaderLinux.LibraryName := '/usr/lib/x86_64-linux-gnu/libsqlite3.so.0';
  44.         SQLDBLibraryLoaderLinux.Enabled := true;
  45.         SQLDBLibraryLoaderLinux.LoadLibrary;
  46.         // Set the filename of the sqlite database
  47.        SQLite3Connection1.DatabaseName := 'QuickHashDBLinux.sqlite';
  48.        // Create the database
  49.        CreateDatabase(SQLite3Connection1.DatabaseName);
  50.        if SQLIte3Connection1.Connected then lblConnectionStatus.Caption:= 'SQLite3 Database connection active';
  51.       end
  52.     // If it's 32-bit Linux, use the 32-bit SQLite3 install
  53.       else if FileExists('/usr/lib/i386-linux-gnu/libsqlite3.so.0') then
  54.         begin
  55.           SQLDBLibraryLoaderLinux.LibraryName := '/usr/lib/i386-linux-gnu/libsqlite3.so.0';
  56.           SQLDBLibraryLoaderLinux.Enabled := true;
  57.           SQLDBLibraryLoaderLinux.LoadLibrary;
  58.           // Set the filename of the sqlite database
  59.          SQLite3Connection1.DatabaseName := 'QuickHashDBLinux.sqlite';
  60.          // Create the database
  61.          CreateDatabase(SQLite3Connection1.DatabaseName);
  62.          if SQLIte3Connection1.Connected then lblConnectionStatus.Caption:= 'SQLite3 Database connection active';
  63.         end
  64.     else
  65.     begin
  66.       ShowMessage('Cannot create SQLite database. Ensure SQLite3 is installed in your Linux distribution');
  67.       exit;
  68.     end;
  69.     {$endif}
  70. {$endif}
  71.  
« Last Edit: November 22, 2017, 12:34:40 am by Gizmo »
Lazarus 1.6.4 and fpc 3.0.2 - Linux Mint 17 LTS, Windows 7 and Mac Yosemite
Useful Page to remember : http://wiki.freepascal.org/Cross_compiling#From_Linux_x64_to_Linux_i386

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus