Hello,

I am trying to statically link OpenSSL. I'm using the Win64 full installer from 
https://slproweb.com/products/Win32OpenSSL.html which includes precopmiled 
static libraries which were compiled with VC using the /MT, /MD, /MTd and /MDd 
switches. This obviously stands for:

/MD    Creates a multithreaded DLL using MSVCRT.lib.
/MDd   Creates a debug multithreaded DLL using MSVCRTD.lib.
/MT    Creates a multithreaded executable file using LIBCMT.lib.
/MTd   Creates a debug multithreaded executable file using LIBCMTD.lib.

So using the MD version seems to be most logical to me. FPC is 3.3/trunk, but 
not the most recent one (about 2 months old).

Trial 1: 

program project1;
{$linklib z:/libcrypto_static.lib}
begin
end.

Result: `Error: Invalid DLL z:\libcrypto_static.lib, Dos Header invalid`

The message reads like a DLL has to be specified.


Trial 2:

program project1;
{$linklib z:/libcrypto-3-x64.dll}
begin
end.

Result: `project1.lpr(6,1) Error: Import library not found for 
z:\libcrypto-3-x64`

Strange. Because the file is there...


Trial 3:

I'm now using `objconv` from 
https://github.com/gitGNU/objconv/blob/master/objconv-x64.exe

Conversion: `objconv-x64.exe -fcoff libcrypto_static.lib libcrypto_static.a` 
(interestingly, using `-fCOFF` as printed on the help page doesn't work)
Result: `Input library: libcrypto_static.lib, Format: COFF64, Output: 
libcrypto_static.a, Format: COFF64`

So it's converting from COFF to COFF. Okay.

Now we have a new minimal example:

program project1;
{$linklib z:/libcrypto_static.a}
begin
end.

At least it gives no errors.

But I haven't used anything from libcrypto yet, so let's go to...


Trial 4:

program project1;
uses CTypes;
{$linklib z:/libcrypto_static.a}
function OPENSSL_init_crypto(opt: cuint64; const settings: pointer): CInt; 
cdecl; external;
begin
  OPENSSL_init_crypto (0, nil);  // parameters aren't important right now
end.

Result: `project1.lpr(7,1) Error: Invalid ar member lfn name index in 
z:\libcrypto_static.a`

Googling this error gives 1 result: It is the source code line of this error 
message, so it doesn't seem to be a very common problem :)


Trial 5:

Let's try changing the `external` declaration. From the FPC manual:

> external ’lname’;
> Then this tells the compiler that the function resides in library “lname”. 
> The compiler will then automatically link this library to the program. 

New approach:

program project1;
uses CTypes;
function OPENSSL_init_crypto(opt: cuint64; const settings: pointer): CInt; 
cdecl; external 'libcrypto_static';
begin
  OPENSSL_init_crypto (0, nil);
end.

This compiles, but gives an error when executing: "...because 
libcrypto_static.dll was not found". One can now use `libcrypto-3-x64` instead 
of `libcrypto_static`, but then I have to redistribute the libcrypto DLL, which 
is just what I'm trying to avoid.

Next idea:


Trial 6:

Use `objconv-x64.exe -fcoff -lx libcrypto_static.lib` to split the library into 
separate object files.

Then I get:

Member crypto\libcrypto-lib-init.obj - COFF-64
   OPENSSL_cleanup
   OPENSSL_init_crypto
   OPENSSL_atexit
   ??_C@_0O@BNMMJHOI@crypto?2init?4c@
   ??_C@_0BE@PHOHEBBN@OPENSSL_init_crypto@

Let's use this one:

program project1;
uses CTypes;
{$L libcrypto-lib-init.obj}
function OPENSSL_init_crypto(opt: cuint64; const settings: pointer): CInt; 
cdecl; external;
begin
  OPENSSL_init_crypto (0, nil);
end.

Result: `project1.lpr(7,1) Error: Associative or exact match COMDAT sections 
are not yet supported (symbol: .debug$S)`


And this is the point where I'm completely stuck. Is there anything I can try 
or is it just impossible to create an .exe which doesn't depend need the 
libcrypto DLL?

Please, I don't want to discuss the pros and cons about static linking. There 
are no high-security demands I have to satisfy. I'd just like to understand 
what I'm doing wrong.

Kind regards,
Thomas

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to