Open skaji opened 2 years ago
Thank you for the report!
I knew this could be a problem with loading from blib, but didn't realize this could also be an issue after the rollout
.
How do you solve this in cpm? Do you skip using an artifact and rebuild from scratch every time?
For Alien::** problem described here, in order to support "Build artifacts", we may use$ORIGIN/ @loader_path for RPATH.
What does this exactly mean?
I need to pull in @plicease here as an Alien expert :)
How do you solve this in cpm? Do you skip using an artifact and rebuild from scratch every time?
cpm has the same problem, and I did not provide any solutions.
For the time being, people can execute cpm with --no-prebuilt
option to disable "artifacts".
For Alien::** problem described here, in order to support "Build artifacts", we may use$ORIGIN/ @loader_path for RPATH.
What does this exactly mean?
We may set relative RPATH by using $ORIGIN
(linux) and @loader_path
(macOS).
The relative path of libtidy.so from HTML/T5/T5.so is always the same when rolling out, thus:
❯ chmod +w local/lib/perl5/x86_64-linux/auto/HTML/T5/T5.so
❯ chrpath -r \$ORIGIN/../../share/dist/Alien-TidyHTML5/lib local/lib/perl5/x86_64-linux/auto/HTML/T5/T5.so
local/lib/perl5/x86_64-linux/auto/HTML/T5/T5.so: RUNPATH=/home/skaji/.carmel/5.34.1-x86_64-linux/perl5/lib/perl5/x86_64-linux/auto/share/dist/Alien-TidyHTML5/lib
local/lib/perl5/x86_64-linux/auto/HTML/T5/T5.so: new RUNPATH: $ORIGIN/../../share/dist/Alien-TidyHTML5/lib
❯ perl -Ilocal/lib/perl5 -MHTML::T5 -E 'say "OK"'
OK
Please note that, I changed RPATH by chrpath
just for proof of concept,
but, actually we should set RPATH $ORIGIN/../../share/dist/Alien-TidyHTML5/lib
in the compile time of HTML::T5.
Another solution is to use LD_LIBRARY_PATH environment variable:
❯ LD_LIBRARY_PATH=$PWD/local/lib/perl5/x86_64-linux/auto/share/dist/Alien-TidyHTML5/lib perl -Ilocal/lib/perl5 -MHTML::T5 -E 'say "OK"'
OK
This solution would be better because this can be used with loading modules from "blib".
For Alien::Build
based Aliens the recommendation is to use static libraries when possible. When not possible Alien::Role::Dino
has some smarts for handling dynamic libs. For Windows this is fine because it updates PATH at runtime, but for Linux and most other Unix it sets the rpath at build time, which won't (currently) be relocatable (this is not a problem unique to Carmel tbh; modern Perls properly built ought to be relocatable as well). Alien::patchelf
might be helpful in the future @shawnlaffan I think might actually be using this in practice for some of his aliens, and maybe we can pull some of that tech into AB core?
Alien::gdal is one example. The code is a bit clunky but works: https://github.com/shawnlaffan/perl-alien-gdal/blob/4d411d3a341cde271e1277a575e73c3eb5ab9687/alienfile#L330 and https://github.com/shawnlaffan/perl-alien-gdal/blob/4d411d3a341cde271e1277a575e73c3eb5ab9687/alienfile#L421
I think I talked with you a little bit about this :) Anyway I write about this in detail here.
Description
There are modules which depend on their initial installation paths, and they may not work if we change their installation paths. Especially
Alien::**
family save their initial installation paths inalien.json
.Real problem
Let's say we have the following cpanfile:
Please note that HTML::T5 depends on Alien::TidyHTML5, more precisely, a shared library
libtidy.so
provided by Alien::TidyHTML5.Then, it turns out that HTML::T5 does not work with carmel:
HTML::T5 is built with
LD_RUN_PATH="/home/skaji/.carmel/5.34.1-x86_64-linux/perl5/lib/perl5/x86_64-linux/auto/share/dist/Alien-TidyHTML5/lib"
saved in Alien::TidyHTML5's alien.json, so HTML::T5 only works if we have libtidy.so in/home/skaji/.carmel/5.34.1-x86_64-linux/perl5/lib/perl5/x86_64-linux/auto/share/dist/Alien-TidyHTML5/lib
. You can also check this byreadelf
:What to do
I believe that "Build artifacts" is a right approach for Perl ecosystem. So I think we should encourage CPAN authors to support "Build artifacts" in their modules.
For
Alien::**
problem described here, in order to support "Build artifacts", we may use$ORIGIN
/@loader_path
for RPATH.