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

I'm working out how to set up a clutch of CentOS 7 servers to run a Perl application, and I realise that I am not understanding (or liking!) what cpan is doing.

System perl comes with @INC set to be

/usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .

So, matched pairs of a "lib64" and a "share". Fine.

I want everybody on the machine to be able to run our perl application with a consistent set of perl modules. And I don't want to skirmish with the vagaries of vendor_perl. So I tried, as root, installing them "locally", with

cpanm -l /usr/local --installdeps MYAPPLICATION

The first thing I noticed was that this installed things in /usr/local/lib/perl5 I couldn't imagine why I ever would want two different sets of perl libraries in /usr/local so I put in a symlink from /usr/local/lib/perl5 -> /usr/local/share/perl5 (But was that a mistake?) And now lots of dependencies get installed in /usr/local/share/perl5, where MYAPPLICATION can find them.

But...

cpanm puts lots of other dependencies not in /usr/local/lib64/perl5, which is on @INC, but in /usr/local/share/perl5/x86_64-linux-thread-multi, which isn't!

What is the right way to fix this?

Should I be trying to steer cpanm to put "local" things in the "expected" places? If so, how?

Should I just symlink /usr/local/lib64/perl5 to /usr/local/share/perl5/x86_64-linux-thread-multi? Or are they meant to be subtly different things?

Or what?

Replies are listed 'Best First'.
Re: Misplaced local cpan modules
by jcb (Parson) on Dec 06, 2019 at 23:43 UTC

    They are subtly different. The base "perl5" directory is for architecture-independent code, while the "perl5/x86_64-linux-thre­ad-multi" dir is for that specific interpreter ABI. In effect, pure Perl extensions go in the former, while XS extensions go in the latter.

    The reasons for having this type of directory structure go back to "ancient times" where multiple systems could share a common network-mounted /usr or the same disk could be used with different machines having different processors. Perl adopted this convention and extended it to allow for other variations that produce incompatible ABIs, such as the availability or omission of threading support. For me this is a bit of history, and I would welcome corrections or further explanations from more senior monks.

Re: Misplaced local cpan modules
by NERDVANA (Priest) on Dec 08, 2019 at 03:50 UTC

    The "local" being referenced by the documentation of cpanm is according to the package local::lib (see man local::lib). This is a distribution-neutral directory hierarchy mainly intended for use when you don't have permission to write to root-owned paths. Meanwhile, the "/usr/local/..." paths in CentOS are just paths that RedHat thought should be added in accordance with the Unix Filesystem Hierarchy. For comparison, Debian has a completely different idea of what they should be:

    /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base

    When I run cpanm normally (no -l option), it installs to /usr/local/share/perl/5.26.1, so my cpanm (supplied by debian) seems to know about the debian paths and understands that it should be using the "local" and not "vendor_perl" paths.

    Are you sure that your cpanm was going to do this wrong without the -l option? And was it the cpanm installed from CentOS packages? If so, maybe ask on the CentOS forums? I think your symlinks are not a bad workaround; just add one more for the x64 subdirectory and you should have a working solution.

Re: Misplaced local cpan modules
by Anonymous Monk on Dec 06, 2019 at 20:26 UTC
    Why symlink when you can configure?

      Currently, cpanm is defaulting to installing things in a place where, by default, Perl won't find them. In my environment, the default settings for the two systems are incompatible.

      I don't understand how/why that has come about, and so I'm not sure how best I should fix it.

      One option is to configure one tool to match the expectations of the other -- to (everywhere) tell Perl to look where cpanm is putting things, or to tell cpanm to put things where Perl expects.

      The alternative is to make the environment these tools are operating in one in which their default behaviours are compatible.

      It's not obvious to me which is better -- which will maximise the number of things that "just work".