http://qs321.pair.com?node_id=11112858

IB2017 has asked for the wisdom of the Perl Monks concerning the following question:

Hello

I am messing around with libraries on macOS, and I am having the following problems: when you install a new module, their dependences, for example dylib, get installed in standard locations. The module then call the dynlib from there. I want to use at RUNTIME other locations where I want to put such dylib.

Let's say I want to use Image::PNG::QRCode; which requires "libpng". Let's say I put the "libpng16.16.dylib" library in a custom directory on my Desktop and I delete any other copy of this library from its standard location. I tried to add the path like following

use lib '/Users/xx/Desktop/lib/libpng16.16.dylib'; #or use lib '/Users/xx/Desktop/lib';

I also tried to add the path to the env with in a begin block $ENV{'LD_LIBRARY_PATH'} = '/Users/xx/Desktop/lib'; with no success.

When I run my script, I get an error saying "Library not loaded: /usr/local/opt/libpng/lib/libpng16.16.dylib" which is the standard location (and I removed the dynlib!)

How can I force my script to look in another location for my libraries? I hope it makes sense.

Replies are listed 'Best First'.
Re: Include custon location for dylib
by bliako (Monsignor) on Feb 12, 2020 at 14:43 UTC

    the crude and possibly bad+dirty way to do this is to prepend to your LD_LIBRARY_PATH **AND** DYLD_LIBRARY_PATH the directories you want ld to look for libraries.

    Those are environment variables. So don't control them within the perl script (like you seem to do). You either set them temporarily at the command line prior to executing your perl script, or insert them to your shell startup script (like ~/.bashrc if using bash) for permanent use (I don't recommend).

    This latter method is not proper as I already mentioned because it applies for all your applications run from your shell (so those at the launcher will not be affected unless they are launched via a shell which reads your startup files - (sanity chek: I believe?)).

    Therefore, if you had perlbrew installed, setting those two env vars would theoretically invalidate brew's ability to control perl's loading procedure. In practice, possibly perlbrew knows better and overwrites those. I am not sure though. But any other application - outside perl - which relies on finding a png library it will find first your other libraries and the chaos starts. That's also the classic way to hack root from within because who controls your libraries and lib search path controls you.

    Here is the most harmless bash idiom to do the above:

    LD_LIBRARY_PATH="/path1:/path2:${LD_LIBRARY_PATH}" DYLD_LIBRARY_PATH="/path1:/path2:${DYLD_LIBRARY_PATH}" myperlscript.pl

    Edit: warning, if you use OSX's archaic /bin/bash these may not work. Hint: change your login shell to modern bash (e.g. the one installed by macports). Do not, I repeat, do not link macports bash to /bin/bash!

    It launches your script with those env vars set only once for just that run. If you must go this way, then perhaps you could create a wrapper shell script to run your perl script the way I said above. Similarly, alter your perl script's shebang to point to a perl wrapper which sets those env vars first and then calls the proper perl to interpret your script. By know you are re-inventing perlbrew ...

    Or investigate how to set ENV within you Perl script so that subsequent use will use it. Others are more experts in this. Search the monastery too, I recall this came up recently.

    Another alternative is to configure Perl's DynaLoader. I do not know if it is possible to tell it where to look for libs other than what I said above, with those two env vars. I.e. whether DynaLoader relies on ld or it has a mind of its own (unlikely i presume).

    bw, bliako

Re: Include custon location for dylib
by Anonymous Monk on Feb 12, 2020 at 11:45 UTC