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.
To comment on the snippet, I'll do this for windows because I went through the exercise of linking statically sqlite. I'll actually go through the complete steps, for posterity
- Get the sqlite source from
http://www.sqlite.org/download.html (amalgamation: all sources in one file).
The source is written in C and needs to be compiled to a static library using a gnu tool chain. Personally I use wxDev-C++ (
http://wxdsgn.sourceforge.net/). This a complete IDE for developing with wxWidgets and probably an overkill for this purpose. The advantage is that the installation is straightforward and that everything needed is installed and, when compiling from the IDE, there is no messing with include/library paths. It is based on the mingw port of the binutils which doesn't require additional run time dlls as opposed to Cygwin.
- in Dev-C++, create a new project, select static library, remove all the files added automatically from the project and add sqlite3.c, save project as sqlite3.dev in dir "whatever", compile project. In whatever\objects\MingW you'll find sqlite3.o. Easy enough.
- sqlite3 being written in C, and C having its own run-time (equivalent to fpc RTL) we'll probably need to pull in a few other libraries. If the program uses windows api's then we'll need to add these libraries also. You could go through the 128.000 lines of code in sqlite3.c to figure out the external dependencies but it is easier to be lazy and have the fpc linker do this for us. Create a new pascal program that uses the newly created library:
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.
- InterlockedCompareExchange looks windows api. According msdn defined in kernel32. In the Dev-Cpp\lib directory you find a libkernel32.a. Add the path to it or copy it to the program directory. Add {$linklib libkernel32.a} to your program. Compile. Undefined reduced to 14 !!
- memcpy sounds like the c run time. That is msvcrt on windows. libmsvcrt.a is in Dev-Cpp\lib. Add {$linklib libmsvcrt.a}. Compile. Only 4 undefined symbols remain.
- a quick google on "Undefined symbol: ___udivdi3" shows that this belongs to the gcc run time library. In Dev-Cpp/lib/gcc/mingw32/3.4.2/ there is libgcc.a. Add {$linklib libgcc.a} to the program. Compile. Bingo! Run program and it'll print the sqlite3 version
If you have lost track, the complete program is now
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.
Hope this answers you questions.