Bibliothek statisch linken??
Bibliothek statisch linken??
Liebe Alle,
dank eurer Antworten auf meine andere Frage habe ich mittlerweile einiges über shared libraries gelernt und und warum ich diese nicht direkt in mein Programm einbinden kann/soll/werde (meine andere Frage bezog sich auf die Linux Basis- und GTK2-Libraries).
Mein Projekt hat aber noch eine einzelne zusätzliche spezielle Library, die es benötigt: das ist die "libiowkit" von Code Mercenaries. Diese Bibliothek liegt im Quelltext (C) vor und ich möchte sie gerne in mein Freepascal-Programm einbinden, um dem Verwender meines Programmes zu ersparen, die Bibliothek selbst kompilieren und installieren zu müssen. Die Bibliothek ist seit längerem unverändert, also ist das Risiko von verpaßten Updates auch eher gering.
Ich kann bzw. muß diese Bibliothek mit make install kompilieren und dann erhalte ich in /usr/lib/ folgende Dateien:
libiowkit.a
libiowkit.la
libiowkit.so.1.0.5
libiowkit.so => libiowkit.so.1.0.5
libiowkit.so.1 => libiowkit.so.1.0.5
Im Quellverzeichnis der Bibliothek entstehen zusätzlich noch "iowkit.lo" und "iowkit.o". Mein Programm bzw. eine abgespeckte Testversion davon funktioniert mit der dynamisch gelinkten Bibliothek problemlos, doch beim statischen Linken sehe ich mich leider einfach nicht mehr raus.
Folgende Optionen bzw. Einstellungsmöglichkeiten überfordern mich:
1) {$LINKLIB ****irgendwas****}
2) {$L ****irgendwas****}
3) Funktionsdeklaration, z.B. function IowKitVersion: PChar; stdcall; external ****irgendwas**** name 'IowKitVersion';
Ich habe viel recherchiert, unzählige Kombinationen von "****irgendwas****" ausprobiert (die library, das object file, das library a file), aber entweder bekomme ich nach dem Kompilieren mit ldd immer noch einen Verweis auf die shared library oder ich kann gar nicht kompilieren, weil der Pfad zu einer Datei (eben eines der "****irgendwas****") ungültig ist bzw. die Datei nicht gefunden werden kann. Vermutlich müßte ich auch noch irgendwelche Pfade im Kompiler setzen.
Ich bitte euch um eure Hilfe und/oder Hinweise, was ich falsch mache bzw. nicht verstanden habe.
Danke und viele Grüße aus Wien,
Christian
dank eurer Antworten auf meine andere Frage habe ich mittlerweile einiges über shared libraries gelernt und und warum ich diese nicht direkt in mein Programm einbinden kann/soll/werde (meine andere Frage bezog sich auf die Linux Basis- und GTK2-Libraries).
Mein Projekt hat aber noch eine einzelne zusätzliche spezielle Library, die es benötigt: das ist die "libiowkit" von Code Mercenaries. Diese Bibliothek liegt im Quelltext (C) vor und ich möchte sie gerne in mein Freepascal-Programm einbinden, um dem Verwender meines Programmes zu ersparen, die Bibliothek selbst kompilieren und installieren zu müssen. Die Bibliothek ist seit längerem unverändert, also ist das Risiko von verpaßten Updates auch eher gering.
Ich kann bzw. muß diese Bibliothek mit make install kompilieren und dann erhalte ich in /usr/lib/ folgende Dateien:
libiowkit.a
libiowkit.la
libiowkit.so.1.0.5
libiowkit.so => libiowkit.so.1.0.5
libiowkit.so.1 => libiowkit.so.1.0.5
Im Quellverzeichnis der Bibliothek entstehen zusätzlich noch "iowkit.lo" und "iowkit.o". Mein Programm bzw. eine abgespeckte Testversion davon funktioniert mit der dynamisch gelinkten Bibliothek problemlos, doch beim statischen Linken sehe ich mich leider einfach nicht mehr raus.
Folgende Optionen bzw. Einstellungsmöglichkeiten überfordern mich:
1) {$LINKLIB ****irgendwas****}
2) {$L ****irgendwas****}
3) Funktionsdeklaration, z.B. function IowKitVersion: PChar; stdcall; external ****irgendwas**** name 'IowKitVersion';
Ich habe viel recherchiert, unzählige Kombinationen von "****irgendwas****" ausprobiert (die library, das object file, das library a file), aber entweder bekomme ich nach dem Kompilieren mit ldd immer noch einen Verweis auf die shared library oder ich kann gar nicht kompilieren, weil der Pfad zu einer Datei (eben eines der "****irgendwas****") ungültig ist bzw. die Datei nicht gefunden werden kann. Vermutlich müßte ich auch noch irgendwelche Pfade im Kompiler setzen.
Ich bitte euch um eure Hilfe und/oder Hinweise, was ich falsch mache bzw. nicht verstanden habe.
Danke und viele Grüße aus Wien,
Christian
-
- Beiträge: 825
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Bibliothek statisch linken??
Mit $LinkLib linkst du eine statische Bibliothek (in deinem Fall wäre das libiowkit.a), mit $L (oder $Link) linkst du eine Objektdatei (in deinem Fall wäre das iowkit.o). Du musst auf jeden Fall eine der beiden Varianten verwenden (okay, du kannst es auch auf der Kommandozeile des Compilers angeben, aber es in der Unit zu haben ist sinnvoller).
Deine Funktionen musst du dann wie folgt deklarieren:
Beachte dabei die folgenden Punkte:
Deine Funktionen musst du dann wie folgt deklarieren:
Code: Alles auswählen
function IowKitVersion: PChar; cdecl; external;
- du darfst keinen Bibliotheksnamen angeben, das ist sonst dynamisches Linken mit der *.so-Datei
- du musst die richtige Calling Convention wählen, für Linux ist das meist cdecl, da solltest du aber nochmal in deinen C Quellen nachschauen
- in den meisten Fällen musst du keinen name-Clause angeben, da der Compiler die Funktion richtig mangled, ansonsten musst du schauen, dass du tatsächlich den richtigen Funktionsnamen in der statischen Bibliothek/in der Objectdatei verwendest und nicht den im Quelltext (unter Linux haben C Funktionen meist einen Unterstrich als Präfix)
FPC Compiler Entwickler
Re: Bibliothek statisch linken??
Großartig, vielen Dank!! Sowohl für die schnelle Antwort als auch natürlich dafür, daß mein Programm jetzt funktioniert!
Mit dem cdcel statt stdcall hast Du selbstverständlich recht, das brauche ich für die Windows-Version meines Programmes und das habe ich beim Kopieren übersehen.
Es funktionieren - so wie Du gesagt hast - beide Varianten, entweder mit dem Verweis auf die o-Datei oder die a-Datei. Die entsprechende Datei muß in /usr/lib/ (die a-Datei) sein oder im Quellverzeichnis meines Programmes (gilt für die a-Datei oder die o-Datei).
Da die Library iowkit ihrerseits von von libc und libpthread abhängt, mußte ich nach dem $LINK bzw. $LINKLIB noch diese beiden Zeilen einfügen:
{$LINKLIB libpthread}
{$LINKLIB libc}
Obiges ist für die Profis sicherlich ohnehin klar, aber ich schreibe es zwecks Vollständigkeit hier rein, falls irgendwer mal auf diesen Thread stößt.
Danke nochmals!
Viele Grüße,
Christian
Mit dem cdcel statt stdcall hast Du selbstverständlich recht, das brauche ich für die Windows-Version meines Programmes und das habe ich beim Kopieren übersehen.
Es funktionieren - so wie Du gesagt hast - beide Varianten, entweder mit dem Verweis auf die o-Datei oder die a-Datei. Die entsprechende Datei muß in /usr/lib/ (die a-Datei) sein oder im Quellverzeichnis meines Programmes (gilt für die a-Datei oder die o-Datei).
Da die Library iowkit ihrerseits von von libc und libpthread abhängt, mußte ich nach dem $LINK bzw. $LINKLIB noch diese beiden Zeilen einfügen:
{$LINKLIB libpthread}
{$LINKLIB libc}
Obiges ist für die Profis sicherlich ohnehin klar, aber ich schreibe es zwecks Vollständigkeit hier rein, falls irgendwer mal auf diesen Thread stößt.
Danke nochmals!
Viele Grüße,
Christian
-
- Beiträge: 825
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Bibliothek statisch linken??
Freut mich zu lesen.
Du kannst auch mit -FlXXX einen Pfad für die Suche nach statischen Bibliotheken und mit -FoXXX einen Pfad für die Suche nach Objektdateien hinzufügen.cgaertner hat geschrieben: ↑Sa 17. Okt 2020, 14:13Es funktionieren - so wie Du gesagt hast - beide Varianten, entweder mit dem Verweis auf die o-Datei oder die a-Datei. Die entsprechende Datei muß in /usr/lib/ (die a-Datei) sein oder im Quellverzeichnis meines Programmes (gilt für die a-Datei oder die o-Datei).
Korrekter ist
Code: Alles auswählen
{$LinkLib pthread}
{$LinkLib c}
Alternativ könntest du in deinem Hauptprogramm die cthreads Unit hinzufügen, diese sorgt auch dafür, dass pthread und c mit reingelinkt werden und sorgt zusätzlich auch dafür, dass die Threading Funktionalität der RTL vorhanden ist.
FPC Compiler Entwickler
Re: Bibliothek statisch linken??
Das habe ich jetzt auch ausprobiert, funktioniert erwartungsgemäß ebenfalls. Wenn ich die beiden Bibliotheken wie ursprünglich mit $LINKLIB einbinde, habe ich als Abhängigkeiten libpthread und libc; wenn ich mit "uses cthreads" arbeite, habe ich als Abhängigkeiten libdl und libc. Hat die eine oder andere Variante unter diesem Gesichtspunkt Vorteile?PascalDragon hat geschrieben: ↑Sa 17. Okt 2020, 15:08Alternativ könntest du in deinem Hauptprogramm die cthreads Unit hinzufügen, diese sorgt auch dafür, dass pthread und c mit reingelinkt werden und sorgt zusätzlich auch dafür, dass die Threading Funktionalität der RTL vorhanden ist.
Noch eine Zusatzfrage: unter Windows funktioniert das doch im Prinzip genauso, nur daß ich dann halt keine *.a-Datei bzw. *.o-Datei habe, sondern eine *.lib-Datei. Brauche ich sonst noch eine Datei? Der Hersteller liefert zwar eine *.lib-Datei in seinem SDK mit, allerdings scheint mir die etwas seltsam zu sein. Als Magic Bytes hat sie nämlich "!<ARCH>", was laut Wikipedia eigentlich ein deb-Paket ist?!?! Ich habe mal im Herstellerforum angefragt - hoffentlich bekomme ich dort eine Antwort. Welches Format müßte denn die *.lib-Datei haben, damit Freepascal sie versteht? Es gibt ja COFF und noch eines (den Namen finde ich grade nicht mehr) ...
Danke und viele Grüße,
Christian
-
- Beiträge: 825
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Bibliothek statisch linken??
Nicht wirklich, da diese drei Bibliotheken alle recht eng miteinander verbandelt sind. Hauptvorteil der Variante mit der cthreads Unit ist dass die RTL von Free Pascal dann auch threadaware ist.cgaertner hat geschrieben: ↑Sa 17. Okt 2020, 20:03Das habe ich jetzt auch ausprobiert, funktioniert erwartungsgemäß ebenfalls. Wenn ich die beiden Bibliotheken wie ursprünglich mit $LINKLIB einbinde, habe ich als Abhängigkeiten libpthread und libc; wenn ich mit "uses cthreads" arbeite, habe ich als Abhängigkeiten libdl und libc. Hat die eine oder andere Variante unter diesem Gesichtspunkt Vorteile?PascalDragon hat geschrieben: ↑Sa 17. Okt 2020, 15:08Alternativ könntest du in deinem Hauptprogramm die cthreads Unit hinzufügen, diese sorgt auch dafür, dass pthread und c mit reingelinkt werden und sorgt zusätzlich auch dafür, dass die Threading Funktionalität der RTL vorhanden ist.
Ich nehme mal an, dass die statischen Bibliotheken für die Windows Variante mit MSVC erstellt wurden. Die statischen Bibliotheken sind dabei leicht unterschiedlich zu denen, die GCC/MinGW erstellt. Der interne Linker von FPC unterstützt aktuell nur die von GCC/MinGW erstellten. Du müsstest also den externen Linker mittels -Xe verwenden (GNU ld unterstützt nämlich glaube ich das MSVC auch, zumindest zum Einlesen), wobei dies zu langsamerem Linken führt und eventuell auch das SmartLinken im Zusammenhang mit Debug Informationen beeinflusst (es gibt 'nen Grund warum wir für Windows 'nen internen Linker geschrieben haben ).cgaertner hat geschrieben: ↑Sa 17. Okt 2020, 20:03Noch eine Zusatzfrage: unter Windows funktioniert das doch im Prinzip genauso, nur daß ich dann halt keine *.a-Datei bzw. *.o-Datei habe, sondern eine *.lib-Datei. Brauche ich sonst noch eine Datei? Der Hersteller liefert zwar eine *.lib-Datei in seinem SDK mit, allerdings scheint mir die etwas seltsam zu sein. Als Magic Bytes hat sie nämlich "!<ARCH>", was laut Wikipedia eigentlich ein deb-Paket ist?!?! Ich habe mal im Herstellerforum angefragt - hoffentlich bekomme ich dort eine Antwort. Welches Format müßte denn die *.lib-Datei haben, damit Freepascal sie versteht? Es gibt ja COFF und noch eines (den Namen finde ich grade nicht mehr) ...
FPC Compiler Entwickler
Re: Bibliothek statisch linken??
Hallo PascalDragon,
ja - die Bibliothek wurde mit Visual Studio 2017 erstellt. Ich habe es mir mittlerweile installiert und kann mit dem vorhandenen Sourcecode aus dem SDK, das der Hersteller zur Verfügung stellt, auch die dll neu erstellen (und da entstehen dann auch gleich die *.lib-Datei und eine *.exp-Datei mit). Trotzdem ändert das nichts an den Fehlern in Freepascal - was aber auch logisch ist, denn Du sagst ja, MSVC ist das falsche Format für statische Libraries unter Freepascal.
Ich habe dann in Freepascal den externen Linker aktiviert (in der Datei fpc.cfg die Option "-Xe" eingefügt) und damit ändert sich das Fehlerbild signifikant. Hatte ich vorher ein allgemeines "Error: Import library not found for iowkit", so wird es jetzt deutlich ausführlicher. Ich bekomme für jede der 12 eingebundenen Funktionen aus der externen Bibliothek eine Meldung in der Form ...
C:\...\RCL\lib\i386-win32\RCL.o:RCL.lpr:(.text.n__main+0x11): undefined reference to `P$RCL_$$_IOWKITVERSION$$PCHAR'
... und am Ende "Error: Error while linking". Die obige Funktion habe ich mit "function IowKitVersion: PChar; stdcall; external;" eingebunden (so heißt sie laut Hersteller-Dokumentation und so funktioniert sie mit der dynamisch gelinkten Bibliothek auch). Und die ganze Bibliothek habe ich mit "{$LINKLIB iowkit}" (das ist der Name der *.dll-Datei und der *.lib-Datei) angegeben.
Es tut mir leid, daß ich da nicht von alleine weiterkomme - darf ich Dich hier nochmal um Deine Hilfe bitten?
Danke und viele Grüße,
Christian
PS: Eine andere Idee hatte ich auch noch: da ich den Quellcode der Bibliothek ja aus dem SDK habe, wäre es ja auch möglich, die Bibliothek mit Visual Studio 2017 unter Verwendung eines externen Compilers/Linkers (nämlich GCC/MinGW) neu zu erstellen - dann müßte das Format für FreePascal ja passen. Laut Microsoft ist es ganz einfach möglich, einen anderen Compiler/Linker in Visual Studio 2017 einzubinden. Aber es zeigte sich für mich, daß die Auffassung, was "einfach möglich" ist, sehr sehr unterschiedlich sein kann.
ja - die Bibliothek wurde mit Visual Studio 2017 erstellt. Ich habe es mir mittlerweile installiert und kann mit dem vorhandenen Sourcecode aus dem SDK, das der Hersteller zur Verfügung stellt, auch die dll neu erstellen (und da entstehen dann auch gleich die *.lib-Datei und eine *.exp-Datei mit). Trotzdem ändert das nichts an den Fehlern in Freepascal - was aber auch logisch ist, denn Du sagst ja, MSVC ist das falsche Format für statische Libraries unter Freepascal.
Ich habe dann in Freepascal den externen Linker aktiviert (in der Datei fpc.cfg die Option "-Xe" eingefügt) und damit ändert sich das Fehlerbild signifikant. Hatte ich vorher ein allgemeines "Error: Import library not found for iowkit", so wird es jetzt deutlich ausführlicher. Ich bekomme für jede der 12 eingebundenen Funktionen aus der externen Bibliothek eine Meldung in der Form ...
C:\...\RCL\lib\i386-win32\RCL.o:RCL.lpr:(.text.n__main+0x11): undefined reference to `P$RCL_$$_IOWKITVERSION$$PCHAR'
... und am Ende "Error: Error while linking". Die obige Funktion habe ich mit "function IowKitVersion: PChar; stdcall; external;" eingebunden (so heißt sie laut Hersteller-Dokumentation und so funktioniert sie mit der dynamisch gelinkten Bibliothek auch). Und die ganze Bibliothek habe ich mit "{$LINKLIB iowkit}" (das ist der Name der *.dll-Datei und der *.lib-Datei) angegeben.
Es tut mir leid, daß ich da nicht von alleine weiterkomme - darf ich Dich hier nochmal um Deine Hilfe bitten?
Danke und viele Grüße,
Christian
PS: Eine andere Idee hatte ich auch noch: da ich den Quellcode der Bibliothek ja aus dem SDK habe, wäre es ja auch möglich, die Bibliothek mit Visual Studio 2017 unter Verwendung eines externen Compilers/Linkers (nämlich GCC/MinGW) neu zu erstellen - dann müßte das Format für FreePascal ja passen. Laut Microsoft ist es ganz einfach möglich, einen anderen Compiler/Linker in Visual Studio 2017 einzubinden. Aber es zeigte sich für mich, daß die Auffassung, was "einfach möglich" ist, sehr sehr unterschiedlich sein kann.
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Bibliothek statisch linken??
Das mit den Problemen beim Einbinden hat auch damit zu tun, das grosse Hersteller dazu neigen, die Software für ihre Kundschaft zu optimieren, das die nicht in Versuchung geführt werden andere Software zu benötigen.
Aber das zieht sich in den C Bereich genauso, siehe
http://www.mingw.org/wiki/msvc_and_mingw_dlls
Aber das zieht sich in den C Bereich genauso, siehe
http://www.mingw.org/wiki/msvc_and_mingw_dlls
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 825
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Bibliothek statisch linken??
Dann nutze bitte dochcgaertner hat geschrieben: ↑Mo 19. Okt 2020, 00:38Ich habe dann in Freepascal den externen Linker aktiviert (in der Datei fpc.cfg die Option "-Xe" eingefügt) und damit ändert sich das Fehlerbild signifikant. Hatte ich vorher ein allgemeines "Error: Import library not found for iowkit", so wird es jetzt deutlich ausführlicher. Ich bekomme für jede der 12 eingebundenen Funktionen aus der externen Bibliothek eine Meldung in der Form ...
C:\...\RCL\lib\i386-win32\RCL.o:RCL.lpr:(.text.n__main+0x11): undefined reference to `P$RCL_$$_IOWKITVERSION$$PCHAR'
... und am Ende "Error: Error while linking". Die obige Funktion habe ich mit "function IowKitVersion: PChar; stdcall; external;" eingebunden (so heißt sie laut Hersteller-Dokumentation und so funktioniert sie mit der dynamisch gelinkten Bibliothek auch). Und die ganze Bibliothek habe ich mit "{$LINKLIB iowkit}" (das ist der Name der *.dll-Datei und der *.lib-Datei) angegeben.
Code: Alles auswählen
function IowKitVersion: PChar; stdcall; external name 'IowKitVersion';
Ja, das wäre die andere Möglichkeit...cgaertner hat geschrieben: ↑Mo 19. Okt 2020, 00:38PS: Eine andere Idee hatte ich auch noch: da ich den Quellcode der Bibliothek ja aus dem SDK habe, wäre es ja auch möglich, die Bibliothek mit Visual Studio 2017 unter Verwendung eines externen Compilers/Linkers (nämlich GCC/MinGW) neu zu erstellen - dann müßte das Format für FreePascal ja passen. Laut Microsoft ist es ganz einfach möglich, einen anderen Compiler/Linker in Visual Studio 2017 einzubinden. Aber es zeigte sich für mich, daß die Auffassung, was "einfach möglich" ist, sehr sehr unterschiedlich sein kann.
FPC Compiler Entwickler
Re: Bibliothek statisch linken??
Liebe Alle,
kurz zu Beginn: meine ursprüngliche Frage zu statischem Linken unter Linux hat sich ja dank dieses Threads erfolgreich lösen lassen. Die weitere Diskussion hier wandelte sich hin zur selben Frage für Windows (Windows 7 64 bit, allerdings mit der 32 Bit Bibliothek und in Lazarus auch i386 als Ziel). Soll ich dafür einen neuen Thread im Windows-Unterforum aufmachen oder machen wir hier weiter, weil's zum Thema paßt?
Leider stecke ich immer noch fest. Das ist mein minimales Testprogramm:
Folgende Möglichkeiten habe ich ausprobiert:
1) Externer Linker, im Projektverzeichnis ist nur die "iowkit.lib" aus dem SDK des Herstellers:
Warning: Library iowkit.dll not found, Linking may fail !
C:\Users\...\RCL\lib\i386-win32\RCL.o:RCL.lpr:(.text.n__main+0x11): undefined reference to `IowKitVersion'
RCL.lpr(9,1) Error: Error while linking
2) Externer Linker, im Projektverzeichnis ist zusätzlich auch noch die "iowkit.dll" aus dem SDK des Herstellers (weil er die ja oben verlangt):
Freepascal linkt die iowkit.dll dynamisch dazu, die exe-Datei ist nur mit dll-Datei lauffähig. Das gleiche Ergebnis, wie wenn ich gar keine *.lib, sondern nur die *.dll im Projektverzeichnis hätte.
3) Interner Linker, im Projektverzeichnis ist nur die "iowkit.lib" aus dem SDK des Herstellers:
Warning: Library iowkit.dll not found, Linking may fail !
RCL.lpr(9,1) Error: Import library not found for iowkit
4) Interner Linker, im Projektverzeichnis ist zusätzlich auch noch die "iowkit.dll" aus dem SDK des Herstellers (weil er die ja oben verlangt):
Freepascal linkt die iowkit.dll dynamisch dazu, die exe-Datei ist nur mit dll-Datei lauffähig. Das gleiche Ergebnis, wie wenn ich gar keine *.lib, sondern nur die *.dll im Projektverzeichnis hätte. Die exe-Datei hat aber nur mehr 31 KB statt 163 KB (externer Linker).
Das SDK gibt es übrigens hier (https://www.codemercs.com/downloads/iow ... DK_win.zip), die erwähnten Dateien (*.dll, *.lib, *.exp) sind im Unterverzeichnis "sdk\iowkit api\x86 dll\".
Der Name der Funktion "IowKitVersion" lautet laut objdump in der dll-Datei identisch "IowKitVersion". In der *.lib-Datei heißt die Funktion "_IowKitVersion@0" (laut Suche mit einem Hex-Editor), wenn ich daher "function IowKitVersion: PChar; stdcall; external name '_IowKitVersion@0';" verwende, dann kompiliert mir Freepascal wieder eine exe-Datei mit dynamisch verlinkter Bibliothek, ganz kurz blinkt aber folgende Meldung auf:
Debug: C:\lazarus\fpc\3.0.4\bin\x86_64-win64\ld.exe: .\/iowkit.lib(iowkit.dll): Recognised but unhandled machine type (0x14c) in Import Library Format archive.
Viele Grüße,
Christian
kurz zu Beginn: meine ursprüngliche Frage zu statischem Linken unter Linux hat sich ja dank dieses Threads erfolgreich lösen lassen. Die weitere Diskussion hier wandelte sich hin zur selben Frage für Windows (Windows 7 64 bit, allerdings mit der 32 Bit Bibliothek und in Lazarus auch i386 als Ziel). Soll ich dafür einen neuen Thread im Windows-Unterforum aufmachen oder machen wir hier weiter, weil's zum Thema paßt?
Leider stecke ich immer noch fest. Das ist mein minimales Testprogramm:
Code: Alles auswählen
program RCL;
{$LINKLIB iowkit}
function IowKitVersion: PChar; stdcall; external name 'IowKitVersion';
begin
WriteLn(IowKitVersion);
end.
1) Externer Linker, im Projektverzeichnis ist nur die "iowkit.lib" aus dem SDK des Herstellers:
Warning: Library iowkit.dll not found, Linking may fail !
C:\Users\...\RCL\lib\i386-win32\RCL.o:RCL.lpr:(.text.n__main+0x11): undefined reference to `IowKitVersion'
RCL.lpr(9,1) Error: Error while linking
2) Externer Linker, im Projektverzeichnis ist zusätzlich auch noch die "iowkit.dll" aus dem SDK des Herstellers (weil er die ja oben verlangt):
Freepascal linkt die iowkit.dll dynamisch dazu, die exe-Datei ist nur mit dll-Datei lauffähig. Das gleiche Ergebnis, wie wenn ich gar keine *.lib, sondern nur die *.dll im Projektverzeichnis hätte.
3) Interner Linker, im Projektverzeichnis ist nur die "iowkit.lib" aus dem SDK des Herstellers:
Warning: Library iowkit.dll not found, Linking may fail !
RCL.lpr(9,1) Error: Import library not found for iowkit
4) Interner Linker, im Projektverzeichnis ist zusätzlich auch noch die "iowkit.dll" aus dem SDK des Herstellers (weil er die ja oben verlangt):
Freepascal linkt die iowkit.dll dynamisch dazu, die exe-Datei ist nur mit dll-Datei lauffähig. Das gleiche Ergebnis, wie wenn ich gar keine *.lib, sondern nur die *.dll im Projektverzeichnis hätte. Die exe-Datei hat aber nur mehr 31 KB statt 163 KB (externer Linker).
Das SDK gibt es übrigens hier (https://www.codemercs.com/downloads/iow ... DK_win.zip), die erwähnten Dateien (*.dll, *.lib, *.exp) sind im Unterverzeichnis "sdk\iowkit api\x86 dll\".
Der Name der Funktion "IowKitVersion" lautet laut objdump in der dll-Datei identisch "IowKitVersion". In der *.lib-Datei heißt die Funktion "_IowKitVersion@0" (laut Suche mit einem Hex-Editor), wenn ich daher "function IowKitVersion: PChar; stdcall; external name '_IowKitVersion@0';" verwende, dann kompiliert mir Freepascal wieder eine exe-Datei mit dynamisch verlinkter Bibliothek, ganz kurz blinkt aber folgende Meldung auf:
Debug: C:\lazarus\fpc\3.0.4\bin\x86_64-win64\ld.exe: .\/iowkit.lib(iowkit.dll): Recognised but unhandled machine type (0x14c) in Import Library Format archive.
Viele Grüße,
Christian
-
- Beiträge: 825
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Bibliothek statisch linken??
Kompilierst du auch wirklich als 32-bit Anwendung?cgaertner hat geschrieben: ↑Di 20. Okt 2020, 00:21Das SDK gibt es übrigens hier (https://www.codemercs.com/downloads/iow ... DK_win.zip), die erwähnten Dateien (*.dll, *.lib, *.exp) sind im Unterverzeichnis "sdk\iowkit api\x86 dll\".
Der Name der Funktion "IowKitVersion" lautet laut objdump in der dll-Datei identisch "IowKitVersion". In der *.lib-Datei heißt die Funktion "_IowKitVersion@0" (laut Suche mit einem Hex-Editor), wenn ich daher "function IowKitVersion: PChar; stdcall; external name '_IowKitVersion@0';" verwende, dann kompiliert mir Freepascal wieder eine exe-Datei mit dynamisch verlinkter Bibliothek, ganz kurz blinkt aber folgende Meldung auf:
Debug: C:\lazarus\fpc\3.0.4\bin\x86_64-win64\ld.exe: .\/iowkit.lib(iowkit.dll): Recognised but unhandled machine type (0x14c) in Import Library Format archive.
Der folgende Code linkt bei mir korrekt für 32-bit:
Code: Alles auswählen
program tlibtest;
{$linklib iowkit}
function IowKitVersion: PChar; stdcall; external name {$ifdef win32}'_IowKitVersion@0'{$else}'IowKitVersion'{$endif};
begin
Writeln(IowKitVersion);
end.
Code: Alles auswählen
fpc -Pi386 -FEtestoutput -Xe "-FlX:\IO-Warrior_SDK_win\sdk\iowkit api\x86 dll" .\fpctests\tlibtest.pp
FPC Compiler Entwickler
-
- Beiträge: 825
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Bibliothek statisch linken??
Okay, ich habe mir das jetzt nochmal genauer angesehen.
Erstmal, um eine Bibliothek statisch zu linken, musst du die $LinkLib-Direktive wie folgt anwenden:
Standardmäßig wird nämlich auch mit $linklib dynamisch gelinkt.
Zweitens muss die statische Bibliothek das richtige Präfix wie auch Suffix haben, sonst wird sie nicht richtig gefunden - also die Datei, nicht das was du in $linklib angibst. Im Fall von Windows ist das (GCC/MinGW kompatibel): lib und .a. Du musst also die iowkit.lib in libiowkit.a umbenennen.
Allerdings hat das dann immer noch nicht funktioniert (also es hat gelinkt, aber lief nicht). Ein Blick in das Visual Studio Projekt für die Bibliothek erklärt auch wieso: unter Windows ist es schlicht nicht dafür gedacht statisch gelinkt zu werden. Die mitgelieferten .lib-Dateien sind einfach nur die Importbibliotheken für die DLL, welche FPC ja nicht benötigt. Der Code der Bibliothek ist auch nicht dafür ausgelegt statisch gelinkt zu werden, da dieser unbedingt den DLL Einsprungspunkt benötigt.
Fazit: Unter Windows kannst du nicht auf die iowkit.dll verzichten.
Erstmal, um eine Bibliothek statisch zu linken, musst du die $LinkLib-Direktive wie folgt anwenden:
Code: Alles auswählen
{$linklib libname, static}
Zweitens muss die statische Bibliothek das richtige Präfix wie auch Suffix haben, sonst wird sie nicht richtig gefunden - also die Datei, nicht das was du in $linklib angibst. Im Fall von Windows ist das (GCC/MinGW kompatibel): lib und .a. Du musst also die iowkit.lib in libiowkit.a umbenennen.
Allerdings hat das dann immer noch nicht funktioniert (also es hat gelinkt, aber lief nicht). Ein Blick in das Visual Studio Projekt für die Bibliothek erklärt auch wieso: unter Windows ist es schlicht nicht dafür gedacht statisch gelinkt zu werden. Die mitgelieferten .lib-Dateien sind einfach nur die Importbibliotheken für die DLL, welche FPC ja nicht benötigt. Der Code der Bibliothek ist auch nicht dafür ausgelegt statisch gelinkt zu werden, da dieser unbedingt den DLL Einsprungspunkt benötigt.
Fazit: Unter Windows kannst du nicht auf die iowkit.dll verzichten.
FPC Compiler Entwickler
Re: Bibliothek statisch linken??
Hallo PascalDragon,
erneut vielen Dank dafür, daß Du Dich so in dieses Problem hineinkniest! Ich werde mich damit abfinden, daß ich unter Windows die dll-Datei mitliefern muß.
Noch eine - vielleicht interessante - Zusatzinformation: im Hersteller-Forum kam zuerst gerade der Vorschlag eines Entwicklers, die *.lib-Datei aus dem Microsoft-Format in das GCC-Format zu konvertieren. Es hieß, laut Stackoverflow soll man das so umsetzen:
gendef.exe iowkit.dll
dlltool.exe --as-flags=--64 -m i386:x86-64 -k --output-lib iowkit.a --input-def iowkit.def
Die Hilfsprogramme "gendef" und "dlltool" sind Bestandteil von MinGW-w64. Ich habe diesen Vorschlag ausprobiert und dann die entstehende Datei "iowkit.a" in "libiowkit.a" umbenannt und dann mit {$LINKLIB iowkit, static} eingebunden. Die entstehende exe-Datei benötigt aber immer noch die externe dll-Datei. Es macht hier auch keinen Unterschied, ob ich den internen oder den externen Linker verwende. Die Funktion muß dann übrigens mit "function IowKitVersion: PChar; stdcall; external name '_IowKitVersion';" definiert werden.
Viele Grüße,
Christian
erneut vielen Dank dafür, daß Du Dich so in dieses Problem hineinkniest! Ich werde mich damit abfinden, daß ich unter Windows die dll-Datei mitliefern muß.
Noch eine - vielleicht interessante - Zusatzinformation: im Hersteller-Forum kam zuerst gerade der Vorschlag eines Entwicklers, die *.lib-Datei aus dem Microsoft-Format in das GCC-Format zu konvertieren. Es hieß, laut Stackoverflow soll man das so umsetzen:
gendef.exe iowkit.dll
dlltool.exe --as-flags=--64 -m i386:x86-64 -k --output-lib iowkit.a --input-def iowkit.def
Die Hilfsprogramme "gendef" und "dlltool" sind Bestandteil von MinGW-w64. Ich habe diesen Vorschlag ausprobiert und dann die entstehende Datei "iowkit.a" in "libiowkit.a" umbenannt und dann mit {$LINKLIB iowkit, static} eingebunden. Die entstehende exe-Datei benötigt aber immer noch die externe dll-Datei. Es macht hier auch keinen Unterschied, ob ich den internen oder den externen Linker verwende. Die Funktion muß dann übrigens mit "function IowKitVersion: PChar; stdcall; external name '_IowKitVersion';" definiert werden.
Viele Grüße,
Christian
-
- Beiträge: 825
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Bibliothek statisch linken??
Die Konvertierung ist prinzipiell auch eine gute Idee, aber wie du selbst festgestellt hast bringt es nichts, da es eben nur eine Importbibliothek und keine wirkliche statische Bibliothek ist. Und in dem Fall ist es einfacher sich auf das zu verlassen was FPC selbst beherrscht.cgaertner hat geschrieben: ↑Mi 21. Okt 2020, 00:36Noch eine - vielleicht interessante - Zusatzinformation: im Hersteller-Forum kam zuerst gerade der Vorschlag eines Entwicklers, die *.lib-Datei aus dem Microsoft-Format in das GCC-Format zu konvertieren. Es hieß, laut Stackoverflow soll man das so umsetzen:
gendef.exe iowkit.dll
dlltool.exe --as-flags=--64 -m i386:x86-64 -k --output-lib iowkit.a --input-def iowkit.def
Die Hilfsprogramme "gendef" und "dlltool" sind Bestandteil von MinGW-w64. Ich habe diesen Vorschlag ausprobiert und dann die entstehende Datei "iowkit.a" in "libiowkit.a" umbenannt und dann mit {$LINKLIB iowkit, static} eingebunden. Die entstehende exe-Datei benötigt aber immer noch die externe dll-Datei. Es macht hier auch keinen Unterschied, ob ich den internen oder den externen Linker verwende. Die Funktion muß dann übrigens mit "function IowKitVersion: PChar; stdcall; external name '_IowKitVersion';" definiert werden.
FPC Compiler Entwickler
Re: Bibliothek statisch linken??
Okay, letzte Frage - dann gebe ich wirklich Ruhe!PascalDragon hat geschrieben: ↑Mi 21. Okt 2020, 09:35Die Konvertierung ist prinzipiell auch eine gute Idee, aber wie du selbst festgestellt hast bringt es nichts, da es eben nur eine Importbibliothek und keine wirkliche statische Bibliothek ist. Und in dem Fall ist es einfacher sich auf das zu verlassen was FPC selbst beherrscht.
Da der Hersteller den Sourcecode im SDK mitliefert und ich den mit Visual Studio 2017 erfolgreich kompilieren kann, kann ich ja die dll-Datei und die (für uns nutzlose) lib-Datei selbst erstellen. Dies erfolgt, indem ich in Visual Studio die Konfiguration "Dynamische Bibliothek (.dll)" auswähle. Jetzt kann ich aber dort auch alternativ die Konfiguration "Statische Bibliothek (.lib)" auswählen und dann wird nur eine lib-Datei erstellt, die aber mit 61 KB auch deutlich größer ist, als jene andere lib-Datei (11 KB).
Nützt diese lib-Datei etwas, entweder direkt für die Einbindung in Freepascal/Lazarus oder für die Konvertierung, die Du ja grundsätzlich als sinnvoll bezeichnet hast? Ich habe sie mal zur Sicherheit angehängt - sie trägt einen anderen Namen als die dll-Datei, aber das kommt vom Hersteller so.
Danke und viele Grüße,
Christian
- Dateianhänge
-
- IOW_Kit.zip
- (19.65 KiB) 115-mal heruntergeladen