Forum > macOS / Mac OS X

How to tell LoadLibrary the path to libssl?

(1/2) > >>

anse:
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:
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.

Thaddy:
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.

anse:
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:
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

Navigation

[0] Message Index

[#] Next page

Go to full version