SQLLite statisch linken

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

SQLLite statisch linken

Beitrag von monta »

Ich versuche gerade, die sqllite-Engine anstatt DLL statisch mit in die Echse zu linken. Hat das zufällig schonmal jemand hinbekommen?

Es gibt dazu zwar ein Thema:
http://www.lazarus.freepascal.org/index ... 954.0.html" onclick="window.open(this.href);return false;

Allerdings bringt mich das nicht wirklich weiter. Da dlls ja nicht gelinkt werden können, hab ich das ganze mit gcc als sqlite3.o übersetzt und wollte es eigentlich per {$l sqlite3.o} einbinden. Geht aber nicht, da irgendwelche Symbole nicht gefunden werden:

Code: Alles auswählen

DeTeSA.lpr(23,1) Error: Undefined symbol: THREADVARLIST_SQLITE3
DeTeSA.lpr(23,1) Error: Undefined symbol: ___divdi3
DeTeSA.lpr(23,1) Error: Undefined symbol: ___moddi3
DeTeSA.lpr(23,1) Error: Undefined symbol: ___umoddi3
DeTeSA.lpr(23,1) Error: Undefined symbol: ___udivdi3
DeTeSA.lpr(23,1) Error: Undefined symbol: ___fixunsdfdi
DeTeSA.lpr(23,1) Error: Undefined symbol: _atoi
DeTeSA.lpr(23,1) Error: Undefined symbol: _GetSystemTimeAsFileTime@4
DeTeSA.lpr(23,1) Error: Undefined symbol: _QueryPerformanceCounter@4
Johannes

Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Re: SQLLite statisch linken

Beitrag von Hitman »

.o klingt schonmal wie ein schlechter ersatz für eine ganze .dll ... was du eher versuchen solltest zu erstellen, wäre die .a Datei (also die static link library). Die sollte sich dann - sofern richtig gelinkt - auch problemlos anfügen lassen. ($linklib sqlite).

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: SQLLite statisch linken

Beitrag von monta »

Es geht mehr oder weniger, als .a geht es. Als .o auch, allerdings mit ein paar zusätzlichen Dateien:

Code: Alles auswählen

{$LINKLIB sqlite3}
{$Linklib msvcrt}
{$Linklib kernel32}
{$Linklib gcc}
Allerdings werde ich das ganze wohl lassen. Das nächste Problem wäre nämlich, SQLdb dazu zu überreden, nicht automatisch eine dll zu suchen, sondern auf die einkompilierte Version zuzugreifen.

Aber ich glaube, ich werde eine andere Lösung probieren, das ganze als Ressource zu integrieren und beim ersten Start bzw. bei Bedarf, wenn keine SQLite.dll gefunden wird, extrahier ich das einfach in den Programmordner. (Und ehe es jemand sagt, ich weiß, das Vista/Win7 da protestiert auf Grund der Schreibrechte, aber es ist ein einmal-wegwerf-Programm, was nicht installiert sondern nur schnell gestartet werden soll ;) )
Johannes

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: SQLLite statisch linken

Beitrag von mse »

monta hat geschrieben:Das nächste Problem wäre nämlich, SQLdb dazu zu überreden, nicht automatisch eine dll zu suchen, sondern auf die einkompilierte Version zuzugreifen.

Code: Alles auswählen

unit sqlite3;
 
{$i sqlite3.inc}
 
end.

Code: Alles auswählen

unit sqlite3dyn;
 
{$DEFINE LOAD_DYNAMICALLY}
 
{$i sqlite3.inc}
 
end.

Code: Alles auswählen

unit sqlite3conn;
{$mode objfpc}
{$h+}
 
interface
 
uses
  classes, db, bufdataset, sqldb, sqlite3dyn, types;
sqlite3dyn müsste wohl durch sqlite3 ersetzt werden (nicht getestet).

Socke
Lazarusforum e. V.
Beiträge: 3177
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: SQLLite statisch linken

Beitrag von Socke »

mse hat geschrieben:sqlite3dyn müsste wohl durch sqlite3 ersetzt werden (nicht getestet).
Ohne mir den Quelltext angesehen zu haben, könntest du auch falsch liegen. Dynamisches Linken heißt soviel wie Funktionszeiger zur Laufzeit bestimmen. Statisch gelinkt heißt in diesem Kontext, dass die Funktionszeiger beim Kompilieren bestimmt werden. Beides geht mindestens mit externen Bibliotheken, wie das aussieht, wenn die Bibliothek mit hinein gelinkt wird, kann ich nicht sagen (wie wäre denn dann der Name/Pfad der Bibliothek?).

Vielleicht hilft aber eine modifizierte sqlite3-Unit in der der Bibliotheksname nicht explilzit angegeben ist; dann dürfte der Compiler eine größere Freiheit beim Suchen haben :D
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: SQLLite statisch linken

Beitrag von mse »

Socke hat geschrieben: Ohne mir den Quelltext angesehen zu haben, könntest du auch falsch liegen.
Ausschnitt aus sqlite3.inc:

Code: Alles auswählen

uses
  ctypes,
{$ifdef LOAD_DYNAMICALLY}
  SysUtils, DynLibs;
{$else}
  DynLibs;
 
{$ifdef darwin}
{$linklib sqlite3}
{$endif}
{$endif}
 
const
{$IFDEF WINDOWS}
  Sqlite3Lib = 'sqlite3.dll';
{$else}
  Sqlite3Lib = 'libsqlite3.'+sharedsuffix;
{$endif}
 
{$IFDEF LOAD_DYNAMICALLY}
  {$DEFINE D}
{$ELSE}
  {$DEFINE S}
{$ENDIF}
[...]
{$IFDEF S}function{$ELSE}var{$ENDIF}sqlite3_libversion{$IFDEF D}: function{$ENDIF}(): pchar; cdecl;{$IFDEF S}external Sqlite3Lib;{$ENDIF}
{$IFDEF S}function{$ELSE}var{$ENDIF}sqlite3_libversion_number{$IFDEF D}: function{$ENDIF}(): cint; cdecl;{$IFDEF S}external Sqlite3Lib;{$ENDIF}
[...]
{$IFDEF LOAD_DYNAMICALLY}
[...]
procedure LoadAddresses(LibHandle: TLibHandle);
begin
  pointer(sqlite3_libversion) := GetProcedureAddress(LibHandle,'sqlite3_libversion');
  pointer(sqlite3_libversion_number) := GetProcedureAddress(LibHandle,'sqlite3_libversion_number');
[...]
function TryInitialiseSqlite(const LibraryName: string): Boolean;
begin
  Result := false;
  if (RefCount=0) then
  begin
    SQLiteLibraryHandle := LoadLibrary(LibraryName);
Dynamisches Linken heißt soviel wie Funktionszeiger zur Laufzeit bestimmen. Statisch gelinkt heißt in diesem Kontext, dass die Funktionszeiger beim Kompilieren bestimmt werden.
Ich wurde mal belehrt, dass unter Linux zwischen "static shared" und "dynamic shared" unterschieden wird. Bei static shared werden die Bibliotheken durch ld beim Programmstart geladen. Sind die Bibliotheken auf dem Zielsystem nicht vorhanden, kann das Programm nicht starten. Dies birgt den Nachteil in sich, dass für IDE's, die Komponenten enthalten welche Bibliotheken verwenden, auch alle Bibliotheken installiert sein müssen, sonst kann die IDE nicht starten. Daher wird für Komponenten meist dynamic shared verwendet. Dabei werden die Bibliotheken durch das Programm bei Bedarf explizit durch loadlibrary() geladen und die Funktionsadressen durch getprocedureaddress() aufgelöst.
Monta sucht den dritten Weg, wo der Bibliothekscode zur Kompilierzeit hinzugebunden wird. AFAIK wird dazu {$LINK} anstatt {$LINKLIB} verwended, es müssten für diesen Fall wohl noch weitere Änderungen an sqlite3.inc vorgenommen werden.

Martin

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: SQLLite statisch linken

Beitrag von monta »

mse hat geschrieben:Monta sucht den dritten Weg, wo der Bibliothekscode zur Kompilierzeit hinzugebunden wird. AFAIK wird dazu {$LINK} anstatt {$LINKLIB} verwended, es müssten für diesen Fall wohl noch weitere Änderungen an sqlite3.inc vorgenommen werden.
Genau, und das hab ich mir bisher noch nicht tiefer angeschaut.
Ein einfaches Ändern des defines LOAD_DYNAMICALLY beinhaltet genau die beiden Methoden die ihr ja schon genannt hab, die ja aber nicht das gewünschte beeinflussen. Da die SQLITE-Verbindung eh die gesamte Programmleufzeit besteht, ist auch relativ egal, wie die Library geladen wird, sie muss ohnehin vorhanden sein, sonst geht gar nichts.

Das tiefe Wühlen in der sqlite.inc hab ich erstmal verschoben. Da das doch etwas zu weit gehen dürfte, wird es wohl bei einer externen lib bleiben.
Johannes

Antworten