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

Reply via email to