Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2024-08

Understanding error messages in static linking

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Thomas Kurz

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
@@
@@

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

Thomas Kurz
to Thomas Kurz

I'm trying to post this message again. I got no responses in August, maybe I have better luck now :))

Earlier message 131 lines
----- Original Message ----- From: Thomas Kurz via fpc-pascal To: FPC-Pascal users discussions Sent: Tuesday, August 20, 2024, 18:16:05 Subject: [fpc-pascal] Understanding error messages in static linking 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 @@ @@ 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
Sven Barth
to Thomas Kurz: I am trying to statically link OpenSSL. I'm using the Win64 full installer from…

Thomas Kurz via fpc-pascal schrieb am
Di., 20. Aug. 2024, 18:16:

Show quoted text 8 lines
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.

The internal linker does not support static libraries created by MSVC. Try the external linker using -Xe or use GCC compiled libraries.

Regards,
Sven