How does one consistently set rpath on a dynamic library and compile time?

162 views Asked by At

I spent an inordinate amount of time this past week adding comprehensive OS, Perl Version, and cmark version tests to the Perl CommonMark module (pull request). Most of my time was spent trying to get macOS and Windows to find each version of cmark built and installed in a custom location.

On macOS, setting INC=-"I/cmark-$version/include" LIBS=-"L/cmark-$version/lib -lcmark" was sufficient to build successfully, but for some versions of Perl it was unable to find cmark at runtime. Reviewing this SO answer and a few other resources, I eventually got it to always find the library by adding this line to the build script:

[[ "${OSTYPE}" == "darwin"* ]] && install_name_tool -add_rpath "${PREFIX}/lib" blib/arch/auto/CommonMark/CommonMark.bundle || true

Adding the rpath this way works, although it fails in some instances when the rpath already exists!. Hence || true.

I'm not sure why builds with some Perl/ExtUtils::MakeMaker versions add the rpath and some don't. I tried all sorts of incantations to get it to be added every time, for example OTHERLDFLAGS=-Wl,-rpath,/cmark-$version/lib, to no avail.

What is the correct way to always include the path to the dynamic library at compile time? Ideally there would be an OS-neutral way to do so.

1

There are 1 answers

0
theory On BEST ANSWER

The answer, ultimately, is update to the latest ExtUtils::MakeMaker.

As @håkon-hægland points out in his comment on the OP, he's investigated this quite a bit, as documented in ExtUtils-MakeMaker issue #402. A pull request merged in September 2021 was his attempt to address the issue; it was released in v7.64 in December 2021.

Upgrading to the latest version fixed the issue completely, so I was able to remove the call to install_name_tool. Anyone testing on macOS 10.4 or earlier will need v7.66 to avoid the setting of rpath, however.