Skip to content

Should MakeMaker be setting LD_RUN_PATH on MacOS? #442

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jkahrman opened this issue Mar 24, 2023 · 4 comments
Open

Should MakeMaker be setting LD_RUN_PATH on MacOS? #442

jkahrman opened this issue Mar 24, 2023 · 4 comments
Labels

Comments

@jkahrman
Copy link

Unless I'm mistaken, LD_RUN_PATH is only used by the GNU Linker (or maybe all ELF linkers, I'm not sure where to look for an authoritative answer). MacOS uses dyld, which I believe ignores this variable (again, I'm extrapolating based on naming conventions and the lack of internet references suggesting otherwise).

If that's the case, shouldn't MakeMaker avoid setting this variable? I realize it isn't hurting anything, but the noise is confusing when debugging.

Others have already gone in this direction:
mattn/p5-Devel-CheckLib@61c8295

@twogee
Copy link

twogee commented Jul 25, 2023

Actually, LD_RUN_PATH causes grief with homebrew on Apple silicon, where the x86(_64) version installs in /usr/local, and arm64 version installs in /opt/homebrew...

@sevan
Copy link
Contributor

sevan commented May 31, 2025

So at the moment there's a problem which spans 3 Perl related components.
Let's step back for a second and put these aside for a second and how a problem free setup would work.
In your Perl source you have a hints file which layout out the default paths to store & look for things and any flags which should be used when building/linking. If you look at hints/darwin.sh you'll see that nothing to do with "run paths". Everything that's bundled with Perl builds, installs, and passes the test suite just fine on current macOS.
Outside of what distributed in the Perl source code as standard, and linking to things outside then things get a little less clear.

dyld in macOS supports linker variables and in the past you could either set an environment variable or use install_name_tool to adjust the paths to libraries. (see dyld(1) on macOS)
With the introduction of SIP in macOS, the use of variable is blocked since it can be in the attackers control, leaving the use of install_name_tool.
As a sidenote, at some point Apple made it so you couldn't like against the SSL/crypto libraries included with the OS meaning you had to use your own copy by building or installing libressl/openssl or something similar to use.

Enter MySQL, the binary package builds for macos provided by Oracle has a libmysqlclient.dylib which uses a linker variable for itself (@rpath) and to reference (@loader_path) the libssl and libcryto it is bundled with.
This is all fine, until a Perl user comes along installs MySQL on macOS from Oracle, then tries to install DBD:mysql. It should build, but when you try to make use of the resulting bundle file e.g when trying to run the test suite, things fail, because the system is unable to resolve the libssl/libtls links.
What was done as a solution was to change Devel::Checklib & MakeMaker to use -rpath for anything built on macOS.
Where what should've happened was for install_name_tool to be used to adjust @loader_path references and setting the -rpath in DBD:mysql.
This is where the problem which spans the 3 Perl related components comes in.
DBD:mysql's Makefile.PL needs to be adjust so that on macOS it runs install_name_tool -change on blib/arch/auto/DBD/mysql/mysql.bundle to fill the locations of libssl.1.1.dylib, and libcrypto.1.1.dylib and to set the -rpath for libmysqlclient.dylib
With that in place, the change on Devel::Checklib to nail -rpath for everything can be dropped, along with the same change here in MakeMaker (see attached patch).

tl;dr you should only nail -rpath on case by case basis, not blindly for everything and anything built for Perl.
This can be confirmed for Perl & MakeMaker by dropping setting -rpath from MakeMaker source and running the test suite on a new Perl distro built from the patched source.

Attached patch also adjusts cpan/ExtUtils-MakeMaker/t/04-xs-rpath-darwin.t to use LDDLFLAGS and set -rpath there.
At this point cpan/ExtUtils-MakeMaker/t/04-xs-rpath-darwin.t is just for example purposes (it's not exercising anything in the Perl infrastructure)

patch-drop-rpath-in-makemaker.txt

@jkahrman
Copy link
Author

jkahrman commented Jun 1, 2025

Okay, but you seem to be describing problems with -rpath linker arguments. I was referring to ExtUtils-MakeMaker generating Makefiles that explicitly set the LD_RUN_PATH environment variable and produce shell commands that explicitly set the same. I believe that this is noise on MacOS and is confusing when debugging.

It’s been a while since I read the code that prompted me to create this issue, but I don’t see how the proposed changes to the -rpath arguments address the noise of the environment variable.

@sevan
Copy link
Contributor

sevan commented Jun 1, 2025

As you correctly pointed out, LD_RUN_PATH is a thing on ELF based system, you either pass -rpath or set it in LD_RUN_PATH and it gets used for setting -rpath automagically.

The reason I posted in this issue is because you cited one of the commits which are related to the -rpath problems on Darwin, and the follow up comment here to yours I assumed was also referring to fallout from -rpath.

Just for context -rpath is currently being set blindly for everything by default in Perl, whether on Darwin or on ELF based systems.
Since I posted my comment on Friday, I've been looking at LD_RUN_PATH on Linux, and have ripped it out of Perl's Configure, MakeMaker, Devel::Checklib and built a new instance of Perl with it, like on Darwin, everything works in the default case & the Perl test suite passes. DBD::mysql also builds and passes its test suite when libmysql is installed in the default location for the system e.g /usr/lib, so again it is unnecessary and needs to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants