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