Once upon a time (late-1990s) I had some reasonable success (shareware)
marketing a JPEG library for Delphi. This was a wrapper around the
Independent JPEG Group's JPEG software which was written in 'C'. My JPEG
library had thus to link to a 'C' library and both dynamic and static
linking was offered. I too had the problem of too many C DLLs to link in.
The way it was solved for static libraries was to first link in the JPEG
object files e.g.
{IDG JPEG objects modules to both compression and decompression}
{$L jdapimin.obj}
{$L jmemmgr.obj}
{$L jmemnobs.obj}
{$L jerror.obj}
{IDG JPEG modules for decompression}
{$L jdinput.obj}
{$L jdtrans.obj}
...
and then to identify the missing 'C' library functions (via linker
errors). I then wrote Pascal equivalents (placed just before the $L
statements. e.g.
{ Stubs for external C RTL functions referenced by JPEG OBJ files.}
function _malloc(size: Integer): Pointer; cdecl;
begin
GetMem(Result, size);
end;
procedure _free(P: Pointer); cdecl;
begin
FreeMem(P);
end;
procedure _memset(P: Pointer; B: Byte; count: Integer);cdecl;
begin
FillChar(P^, count, B);
end;
procedure _memcpy(dest, source: Pointer; count: Integer);cdecl;
begin
Move(source^, dest^, count);
end;
function __ftol: Integer;
var
f: double;
begin
asm
lea eax, f // BC++ passes floats on the FPU stack
fstp qword ptr [eax] // Delphi passes floats on the CPU stack
end;
Result := Trunc(f);
end;
As long as you can reduce the missing dependencies to a relatively small
number, it should all work.
Regards
Tony Whyman
MWA
On 21/08/2022 18:34, Anthony Walter via fpc-pascal wrote:
I will pay $100 to the first person that can solve my problem of
linking a compiled C static library to a Free Pascal program on Windows.
Recently I have been building many C libraries with GCC on Linux and
linking them to Free Pascal. These include building C libraries such
as "libxmp" for decoding mod/tracker music into PCM audio samples,
"libchuimpmunk2d" for simulating 2D solid body physics, or "libsdl2"
for cross platform controller input and haptic feedback among other
things.
So far on Linux I am happily able to use a cmake/make/gcc toolchain to
build these C libraries from source and easily statically link them to
my Free Pascal programs.
Here is an example and abbreviated Pascal unit that links to a static
build of Chimpmunk 2D:
unit Chimpmunk2D;
interface
type
cpSpace = Pointer;
function cpSpaceNew: cpSpace; cdecl; external;
procedure cpSpaceDestroy(space: cpSpace); cdecl; external;
implementation
{$ifdef linux}
{$linklib c}
{$linklib m}
{$linklib chipmunk-linux}
{$endif}
end.
Where libchipmunk-linux.a is my static library build on Linux from the
Chipmunk2D C source code and is in the same folder as the source code
as "Chimpmunk2D.pas". This works fine on Linux.
I am also able to use mingw32 gcc to compile this same C source into a
static library for Windows using these two commands while inside the
folder containing the Chipmunk2D sources:
x86_64-w64-mingw32-gcc-win32 -static -static-libgcc -std=gnu99
-ffast-math src/*.c -Iinclude -c
x86_64-w64-mingw32-ar rcs libchipmunk-win.a *.o
rm *.o
The problem then arises when I try to use {$linklib chipmunk-win}. No
matter how I try to arrange the static dependencies I cannot resolve
missing functions.
Many attempts were made compiling against other mingw32 static
libraries for Windows.
{$ifdef windows}
{$linklib mingw32}
{$linklib mingwex}
{$linklib kernel32}
{$linklib msvcrt}
{$linklib chipmunk-win}
{$endif}
I get many errors similar to these below:
Verbose: Compiling resource
C:\Development\Projects\physics\lib\x86_64-win64\Physics.obj
Verbose: Linking C:\Development\Pascal\Projects\physics\Physics.exe
Physics.lpr(30,1) Error: Undefined symbol: ___chkstk_ms
Physics.lpr(30,1) Error: Undefined symbol: __mingw_raise_matherr
Physics.lpr(30,1) Error: Undefined symbol: __imp_WideCharToMultiByte
Physics.lpr(30,1) Error: Undefined symbol: __imp_IsDBCSLeadByteEx
Physics.lpr(30,1) Error: Undefined symbol: __imp_MultiByteToWideChar
Physics.lpr(30,1) Verbose: There were 5 errors compiling module, stopping
Verbose: Compilation aborted
BUT
If I use mingw32-w64 on Linux to create a DLL instead, then m
problems on Windows go away.
x86_64-w64-mingw32-gcc-win32 -static -shared -static-libgcc -std=gnu99
-ffast-math src/*.c -Iinclude -o libchipmunk-win.dll
However, I am not satisfied with an ever growing list of DLLs (I am at
6 currently) that must be deployed on Windows to build / run any
project using my Pascal toolkit. I thought I could resolve this static
linking problem on Windows at a later date, thus eliminating all the
DLLs required to run projects using my toolkit on Windows, but every
time I return to try another attempt I cannot resolve the external
dependencies of something like "libchipmunk-win.a".
Therefore, if anyone has expertise in the area of linking static C
libraries and can provide an example of how to link just one
("libchipmunk-win.a") on Windows either providing a different Windows
C compiling method (MSVC as opposed to x86_64-w64-mingw32-gcc-win32)
and the proper directives to correctly link a static library, I would
gladly pay that person $100.
Additionally, I would write up a guide for other people if they have
trouble while attempting to do the same thing.
If you have any tips or suggestions you can respond to this thread. If
you have a solution and want to collect the reward, reply to my email
address associated with this thread.
For reference, here are links to Windows static and dynamic libraries
I;ve already built. Feel free to build new static libraries yourself,
but just be sure to provide the list of tools and arguments you used
if sending a solution.
https://files.codebot.org/sysrpl/applications/libchipmunk-win.a
https://files.codebot.org/sysrpl/applications/libchipmunk-win.dll
_______________________________________________
fpc-pascal maillist -fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal