Recent

Author Topic: How to tell LoadLibrary the path to libssl?  (Read 1096 times)

anse

  • New Member
  • *
  • Posts: 49
  • Bugmonkey
    • HeidiSQL
How to tell LoadLibrary the path to libssl?
« on: November 02, 2025, 01:41:46 pm »
I want to ship libmysqclient.24.dylib with my application and want to load it from the application directory then:

LoadLibrary(ExtractFilePath(0) + 'libmysqclient.24.dylib')

The file exists and begins to load, but it has a dependency to libssl.3.dylib, so I placed this one as well in my application directory. But it is being looked up in ~/lib and some other system paths. The one in my application directory is ignored / not loaded. I'm ending up with such an error message from GetLoadErrorStr:

dlopen(/Users/ricky/Documents/myapp/libmysqlclient.24.dylib): Library not loaded: @loader_path/../lib/libssl.3.dylib

As a macOS beginner, I read that I should add my application path to the envirenment variable DYLD_LIBRARY_PATH. Is there a way to do that within the app itself? Most related articles I read tell me I should add a script or modify the env var in a terminal before running my app. But I want to provide a works-out-of-the-box app for my users.

If that's not possible, can a dmg installer install libssl and its friends in the system path if they don't exist?

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: How to tell LoadLibrary the path to libssl?
« Reply #1 on: November 02, 2025, 03:23:12 pm »
It is possible from code too. It is a bit cumbersome, though.
See e.g.: https://unix.stackexchange.com/questions/29128/how-to-read-environment-variables-of-a-process#:~:text=If%20a%20process%20changes%20its%20environment%2C%20then%20in,the%20environment%20from%20the%20global%20char%20%2A%2A__environ%20variable.

The problem is that the environment is copied at startup. After the program has changed the user environment the environment needs to be reloaded and that can only be done as described in the link.

A better, cleaner,  option is to write an installer or installer script to do that, as is indeed the usual advice.
The good news is that FPC supports what is necessary to do it the hard way.

It would be a bit easier if FPC had a setenv from clib exposed, but - as opposed to many other supported platforms - it is missing for posix/unix/linux/apple!
I will see if I can do that, because it is a missing POSIX call and FPC should support it.
« Last Edit: November 02, 2025, 03:52:42 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: How to tell LoadLibrary the path to libssl?
« Reply #2 on: November 02, 2025, 04:13:30 pm »
I just discovered that the environment visible to a process itself is fixed length, so if you add or change you need to do that on a copy and realloc the environment. That is a bit too much for something that otherwise just requires an install script. The low-level way is, well, very,very low level in this case. Can be done, though. But I advise against it.

(On Windows it is very easy, alas not on UNIXes)

A third option is to link statically libmysqlclient.a but I don't know if this will succeed and probably needs to change some interface files.
« Last Edit: November 02, 2025, 04:21:12 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

anse

  • New Member
  • *
  • Posts: 49
  • Bugmonkey
    • HeidiSQL
Re: How to tell LoadLibrary the path to libssl?
« Reply #3 on: November 02, 2025, 07:14:09 pm »
Thanks a lot Thaddy for sheding some light on both ways. I heavily agree with you saying modifying the environment in a running app is too cumbersome. Using static .a libraries has indeed other downsides, one aspect is they can't be updated seperately from the app.

I was mainly stumbling about the system usage of (DY)LD_LIBRARY_PATH because it is said on macOS one should ship his app with the used third party libraries bundled. The paths used by the loader contradicts this somehow.

Looks like a script generated through the installer is the cleanest way to go.
I also just realize in Lazarus, I can override environment variables in the Run > "Run parameters" dialog: https://wiki.freepascal.org/IDE_Window:_Run_parameters#Environment

Josh

  • Hero Member
  • *****
  • Posts: 1454
Re: How to tell LoadLibrary the path to libssl?
« Reply #4 on: November 02, 2025, 09:04:21 pm »
Hi
Your DyLib should be in the Framworks Folder.

Note you will need to Codesign All executables,DyLib etc

Below sample App Structure

Your.App
   Contents
      Frameworks
         lib-crypto.dylib
         libsqlite.dylib
      MacOS
         MyExecutable  *//not symlink to it
      Modules
         mod-ffmpeg.so
      plug-ins
         nyquist-plug-in-installer.ny
      Resources
         YourApp.icns
      -CodeSignature
         CodeResources
      info.plist
      PgInfo
« Last Edit: November 02, 2025, 09:21:19 pm by Josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Fred vS

  • Hero Member
  • *****
  • Posts: 3780
    • StrumPract is the musicians best friend
Re: How to tell LoadLibrary the path to libssl?
« Reply #5 on: November 02, 2025, 09:19:59 pm »
@Josh, you are faster than me, anyway this is the same bell:

Hello.

Usually a MacOs application is encapsulated into a .app directory with some sub-directories:

The binary of the app:
Code: Pascal  [Select][+][-]
  1. YourMacApp.app/Contents/MacOS/YourMacApp_binary

And if you have custom dependencies:
Code: Pascal  [Select][+][-]
  1. YourMacApp.app/Resources/lib/yourdependencies.dynlib

And to load the libraries you may do something like this:

Code: Pascal  [Select][+][-]
  1. var
  2. binpath, libpath: string;
  3. ...
  4.  
  5. binPath := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0)));
  6. libPath := copy(binPath, 1, length(binPath) -6) + 'Resources/lib/yourdependencies.dynlib';
  7. LoadLibrary(libPath);
« Last Edit: November 02, 2025, 09:29:34 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

anse

  • New Member
  • *
  • Posts: 49
  • Bugmonkey
    • HeidiSQL
Re: How to tell LoadLibrary the path to libssl?
« Reply #6 on: November 03, 2025, 07:22:41 am »
I think that folder structure is quite clear, even Lazarus takes care of that when building.

The question was how to manipulate the path which a shipped third party dylib (libmysqlclient) uses when loading another third party dylib (libssl).

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: How to tell LoadLibrary the path to libssl?
« Reply #7 on: November 03, 2025, 10:43:10 am »
forcedirectories?
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

anse

  • New Member
  • *
  • Posts: 49
  • Bugmonkey
    • HeidiSQL
Re: How to tell LoadLibrary the path to libssl?
« Reply #8 on: December 18, 2025, 11:41:01 am »
Your DyLib should be in the Framworks Folder.

Note you will need to Codesign All executables,DyLib etc

In the app bundle I am now having all dylib's in the Frameworks folder. I also fixed the expected loader path by using the install_name_tool from macOS, modifying the app and all .dylib's to load dependencies from the Frameworks folder in my app bundle.

Now only TFPHttpClient still throws me an error "Could not initialize OpenSSL library" when requesting a https URL. Apparently because libssl.1.1.dylib is in the Frameworks folder, not in the app folder. Is there a way to hint the openssl units to the Frameworks folder?

Espectr0

  • Full Member
  • ***
  • Posts: 235
Re: How to tell LoadLibrary the path to libssl?
« Reply #9 on: December 18, 2025, 12:44:53 pm »
If I remember correctly, you need to add it to the project's linker options: “-rpath @executable_path\..\Frameworks”.
Then you use loadlibrary normally without specifying the path, just the filename.

anse

  • New Member
  • *
  • Posts: 49
  • Bugmonkey
    • HeidiSQL
Re: How to tell LoadLibrary the path to libssl?
« Reply #10 on: December 18, 2025, 02:00:31 pm »
Thank you @Espectr0, that works like a charm now. TFPHttpClient can now request https pages normally.  8-)

That rpath option (run-time search path) is even well documented - I just missed it: https://wiki.freepascal.org/macOS_Frameworks#Distributing_an_application_with_a_Framework

Note it should be "-rpath @loader_path/../Frameworks". Not sure if @executable_path does the same.


 

TinyPortal © 2005-2018