{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
uses
{$IFDEF MSWINDOWS}
Windows,
Messages,
{$ENDIF}
{$IFDEF LINUX} // for Kylix
Libc,
Types,
{$ENDIF}
Classes,
{$IFDEF USETYPEINFO}
// this pure pascal version must handle the 64-bits ordinal values and
// the special layout of the underlying compiler (mostly FPC)
typinfo,
{$ENDIF}
{$IFNDEF LVCL}
Contnrs, // for TObjectList
{$ENDIF}
SysUtils;
{$IFNDEF FPC}
{$L 'OBJ\sqlite3se.obj'} //for Delphi
{$ELSE}
{$IFDEF MSWINDOWS}
{$linklib libsqlite3se.a}
{$linklib libmsvcrt.a}
{$linklib libkernel32.a}
{$linklib libgcc.a}
{$ELSE}
{$linklib libsqlite3selinux.a}
{$Linklib c}
{$linklib libgcc.a}
{$ENDIF}
{$ENDIF}
and add -Xt in fpc.cfg.
how does static linking work in FPC/Lazarus and where could some more information be found about it. Some of the questions would for example be, what are those other libs that get loaded here, where are those found and why are they needed...http://en.wikipedia.org/wiki/Static_library explains what static linking is. FPC is not an exception. Think about a static library as a collection of .o and .ppu files. There are different library formats but the fpc linker only accepts the gnu format. On windows this means that static libraries produced by MS tools can not be used. Mingw or cygwin ports of the gnu binutils need to be used.
program TestSqlite3;
{$L sqlite3.o}
function sqlite3_libversion(): pchar; cdecl;external;
begin
writeln(sqlite3_libversion);
end.
and compile. Make sure the path to sqlite3.o is added or simply copy it to the program directory. Linker stops at 50 undefined symbols. No panic. Let's start with what we recognise.program project1;
{$L sqlite3.o}
{$linklib libkernel32.a}
{$linklib libmsvcrt.a}
{$linklib libgcc.a}
function sqlite3_libversion(): pchar; cdecl;external;
begin
writeln(sqlite3_libversion);
end.
- Now to use the statically linked version with sqldb, there is still some work to do. In the test program we declared function sqlite3_libversion() manually and Sqlite3conn is "hard-wired" to use the dynamic library. The way how i solved this is to make a copy of sqlite3conn.pp in my project directory, change uses sqlite3dyn to sqlite3static, create a new sqlite3static from sqlite3.inc (add "unit sqlite3static;" remove uses dynlibs, add the {$linklib xxx},{$L sqlite3.o} lines, change all "external Sqlite3Lib;" to "external;" and remove the contents of the implementation section except for the function sqlite3_version. If interested I can attach this file knowing that it isn't based on the latest svn version of sqlite3.inc.One fairly off topic question (I suspect the answer but just wanted to make sure I get it): why would there be a dependency on GCC - shouldn't MinGW compile against the Microsoft C runtime? Or is that because GCC provides some functions not provided by MSVCRT that are called by sqlite?The GCC compiler uses the divdi3 functions for 64-bit multiplication and division which are not in MSVCRT. Sqlite isn't calling these functions directly but uses some 64-arithmetic.
The GCC compiler uses the divdi3 functions for 64-bit multiplication and division which are not in MSVCRT. Sqlite isn't calling these functions directly but uses some 64-arithmetic.
The reason is that these functions are relatively small and much used, and avoiding DLL call overhead (how little it is) can be worthwhile.The goal of the exercise was to get rid of the sqlite3.dll and have an "all-in" executable. Substituting a dependency on sqlite3.dll with a dependency on libgcc_s_dw_2-1.dll (or whatever the used gcc version requires) wouldn't be too smart neither.
I believe that post would made a worthy wiki article, so if it's not much trouble, you might create a page there. If you wish, I can do it for you...I'll take up your offer. If you think you can turn this into a wiki article, please go ahead. The way I wrote the reply was more a explain by example than a wiki page on static linking in general or one on the static linking of sqlite.
QuoteThe reason is that these functions are relatively small and much used, and avoiding DLL call overhead (how little it is) can be worthwhile.The goal of the exercise was to get rid of the sqlite3.dll and have an "all-in" executable. Substituting a dependency on sqlite3.dll with a dependency on libgcc_s_dw_2-1.dll (or whatever the used gcc version requires) wouldn't be too smart neither.
Just at thought, would it be possible to automate this in some way, so that the FPC installed could automate this process, and thereby giving a possibility (also for the not so experienced user) to build programs where the static linking is done upfront?The purpose of the write-up was also to demonstrate the process of finding the dependent libraries. Other than parsing all libraries on your system and make a kind of database with exported functions, I don't see how to facilitate this. To automate is even more difficult. What happens if the same function is exported by different libraries. It could be just a name collision or 2 different, incompatible, versions of the library. Both require some knowledge of the libraries to solve the ambiguity.
It also leads me to an other question, maybe off topic, why is there a requirement for having a special library/client for MySQL - I mean all the "clever" work is done one the server, and (as I understand it) all the client (simplified) has to do is to send SQL commands over port 3306, and then receive the result and pass it to the program.The db client is doing a lot more.:
I know that the communication is encrypted, but anyway?
If it was possible to write the client purely in Pascal, and having it to be a part of FPC would be an huge advantage, not only for making programs simpler, but also for having an easy way to say goodbye to Oracle, and using MariaDB instead.
- communication: databases use a proprietary network protocol.
To be honest, I don't see the advantage of rewriting a db client library in pascal. Apart from the big effort, you would be running constantly after the facts because of the proprietary protocol. We run even after the facts in creating the bindings for the existing mysql client libraries (latest in fpc trunk is 5.1)
OOP is all about re-using software. That includes the use of existing libraries.
Hi, what happens if i have a unitA that has {$linklib mylibrary} and then i have a unitB that is created at some point by unitA and that also has {$linklib mylibrary}? Is mylibrary initialized 2 times?
Because i having, at random, some strange behavior and try to exclude as much cases as possible.